gsd-agent 1.0.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 +221 -0
- package/bin/cli.js +313 -0
- package/dist/auth-flow.d.ts +50 -0
- package/dist/auth-flow.d.ts.map +1 -0
- package/dist/auth-flow.js +233 -0
- package/dist/auth-flow.js.map +1 -0
- package/dist/auth.d.ts +42 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +117 -0
- package/dist/auth.js.map +1 -0
- package/dist/command-executor.d.ts +44 -0
- package/dist/command-executor.d.ts.map +1 -0
- package/dist/command-executor.js +193 -0
- package/dist/command-executor.js.map +1 -0
- package/dist/command-executor.test.d.ts +8 -0
- package/dist/command-executor.test.d.ts.map +1 -0
- package/dist/command-executor.test.js +87 -0
- package/dist/command-executor.test.js.map +1 -0
- package/dist/command-queue.d.ts +44 -0
- package/dist/command-queue.d.ts.map +1 -0
- package/dist/command-queue.js +184 -0
- package/dist/command-queue.js.map +1 -0
- package/dist/command-queue.test.d.ts +7 -0
- package/dist/command-queue.test.d.ts.map +1 -0
- package/dist/command-queue.test.js +220 -0
- package/dist/command-queue.test.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +103 -0
- package/dist/config.js.map +1 -0
- package/dist/conflict-resolver.d.ts +43 -0
- package/dist/conflict-resolver.d.ts.map +1 -0
- package/dist/conflict-resolver.js +91 -0
- package/dist/conflict-resolver.js.map +1 -0
- package/dist/conflict-resolver.test.d.ts +7 -0
- package/dist/conflict-resolver.test.d.ts.map +1 -0
- package/dist/conflict-resolver.test.js +123 -0
- package/dist/conflict-resolver.test.js.map +1 -0
- package/dist/discovery.d.ts +59 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +180 -0
- package/dist/discovery.js.map +1 -0
- package/dist/discovery.test.d.ts +8 -0
- package/dist/discovery.test.d.ts.map +1 -0
- package/dist/discovery.test.js +132 -0
- package/dist/discovery.test.js.map +1 -0
- package/dist/hash.d.ts +20 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +35 -0
- package/dist/hash.js.map +1 -0
- package/dist/hash.test.d.ts +7 -0
- package/dist/hash.test.d.ts.map +1 -0
- package/dist/hash.test.js +58 -0
- package/dist/hash.test.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +202 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.test.d.ts +8 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +37 -0
- package/dist/integration.test.js.map +1 -0
- package/dist/logger.d.ts +68 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +159 -0
- package/dist/logger.js.map +1 -0
- package/dist/output-streamer.d.ts +27 -0
- package/dist/output-streamer.d.ts.map +1 -0
- package/dist/output-streamer.js +71 -0
- package/dist/output-streamer.js.map +1 -0
- package/dist/output-streamer.test.d.ts +7 -0
- package/dist/output-streamer.test.d.ts.map +1 -0
- package/dist/output-streamer.test.js +90 -0
- package/dist/output-streamer.test.js.map +1 -0
- package/dist/realtime-subscriber.d.ts +63 -0
- package/dist/realtime-subscriber.d.ts.map +1 -0
- package/dist/realtime-subscriber.js +201 -0
- package/dist/realtime-subscriber.js.map +1 -0
- package/dist/realtime-subscriber.test.d.ts +7 -0
- package/dist/realtime-subscriber.test.d.ts.map +1 -0
- package/dist/realtime-subscriber.test.js +183 -0
- package/dist/realtime-subscriber.test.js.map +1 -0
- package/dist/reconnection-manager.d.ts +88 -0
- package/dist/reconnection-manager.d.ts.map +1 -0
- package/dist/reconnection-manager.js +229 -0
- package/dist/reconnection-manager.js.map +1 -0
- package/dist/reconnection-manager.test.d.ts +8 -0
- package/dist/reconnection-manager.test.d.ts.map +1 -0
- package/dist/reconnection-manager.test.js +151 -0
- package/dist/reconnection-manager.test.js.map +1 -0
- package/dist/remote-sync-handler.d.ts +61 -0
- package/dist/remote-sync-handler.d.ts.map +1 -0
- package/dist/remote-sync-handler.js +197 -0
- package/dist/remote-sync-handler.js.map +1 -0
- package/dist/remote-sync-handler.test.d.ts +7 -0
- package/dist/remote-sync-handler.test.d.ts.map +1 -0
- package/dist/remote-sync-handler.test.js +212 -0
- package/dist/remote-sync-handler.test.js.map +1 -0
- package/dist/retry.d.ts +35 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +63 -0
- package/dist/retry.js.map +1 -0
- package/dist/retry.test.d.ts +5 -0
- package/dist/retry.test.d.ts.map +1 -0
- package/dist/retry.test.js +84 -0
- package/dist/retry.test.js.map +1 -0
- package/dist/storage-client.d.ts +69 -0
- package/dist/storage-client.d.ts.map +1 -0
- package/dist/storage-client.js +168 -0
- package/dist/storage-client.js.map +1 -0
- package/dist/storage-client.test.d.ts +7 -0
- package/dist/storage-client.test.d.ts.map +1 -0
- package/dist/storage-client.test.js +126 -0
- package/dist/storage-client.test.js.map +1 -0
- package/dist/supabase.d.ts +82 -0
- package/dist/supabase.d.ts.map +1 -0
- package/dist/supabase.js +341 -0
- package/dist/supabase.js.map +1 -0
- package/dist/supabase.test.d.ts +7 -0
- package/dist/supabase.test.d.ts.map +1 -0
- package/dist/supabase.test.js +273 -0
- package/dist/supabase.test.js.map +1 -0
- package/dist/sync-engine.d.ts +84 -0
- package/dist/sync-engine.d.ts.map +1 -0
- package/dist/sync-engine.js +251 -0
- package/dist/sync-engine.js.map +1 -0
- package/dist/sync-engine.test.d.ts +7 -0
- package/dist/sync-engine.test.d.ts.map +1 -0
- package/dist/sync-engine.test.js +241 -0
- package/dist/sync-engine.test.js.map +1 -0
- package/dist/sync-state.d.ts +82 -0
- package/dist/sync-state.d.ts.map +1 -0
- package/dist/sync-state.js +145 -0
- package/dist/sync-state.js.map +1 -0
- package/dist/sync-state.test.d.ts +7 -0
- package/dist/sync-state.test.d.ts.map +1 -0
- package/dist/sync-state.test.js +129 -0
- package/dist/sync-state.test.js.map +1 -0
- package/dist/types.d.ts +148 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/types.test.d.ts +7 -0
- package/dist/types.test.d.ts.map +1 -0
- package/dist/types.test.js +73 -0
- package/dist/types.test.js.map +1 -0
- package/dist/watcher.d.ts +55 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +214 -0
- package/dist/watcher.js.map +1 -0
- package/dist/watcher.test.d.ts +8 -0
- package/dist/watcher.test.d.ts.map +1 -0
- package/dist/watcher.test.js +164 -0
- package/dist/watcher.test.js.map +1 -0
- package/package.json +58 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for GSD Agent
|
|
3
|
+
*
|
|
4
|
+
* These types define the data structures used throughout the agent for
|
|
5
|
+
* workspace management, file change tracking, and synchronization.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Workspace represents a discovered GSD project
|
|
9
|
+
*
|
|
10
|
+
* Each workspace corresponds to a directory containing a .planning/ folder.
|
|
11
|
+
* The agent tracks multiple workspaces and syncs their files independently.
|
|
12
|
+
*/
|
|
13
|
+
export interface Workspace {
|
|
14
|
+
/** Unique identifier for the workspace */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Absolute path to the workspace root directory */
|
|
17
|
+
root_path: string;
|
|
18
|
+
/** Human-readable name (derived from directory name) */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Current workspace status */
|
|
21
|
+
status: 'active' | 'paused' | 'archived';
|
|
22
|
+
/** ISO timestamp of last successful sync */
|
|
23
|
+
last_sync: string;
|
|
24
|
+
/** ISO timestamp when workspace was first discovered */
|
|
25
|
+
discovered_at: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* FileChangeEvent represents a single file system change
|
|
29
|
+
*
|
|
30
|
+
* Events are generated by the filesystem watcher and queued for sync to Supabase.
|
|
31
|
+
* Each event captures the file state at the time of change.
|
|
32
|
+
*/
|
|
33
|
+
export interface FileChangeEvent {
|
|
34
|
+
/** Unique identifier for this event */
|
|
35
|
+
id: string;
|
|
36
|
+
/** Reference to the workspace this file belongs to */
|
|
37
|
+
workspace_id: string;
|
|
38
|
+
/** File path relative to workspace root (e.g., ".planning/STATE.md") */
|
|
39
|
+
file_path: string;
|
|
40
|
+
/** Type of filesystem event */
|
|
41
|
+
event_type: 'add' | 'change' | 'unlink';
|
|
42
|
+
/** SHA-256 hash of file content (for deduplication) */
|
|
43
|
+
content_hash: string;
|
|
44
|
+
/** File content (null for unlink events) */
|
|
45
|
+
content?: string;
|
|
46
|
+
/** Source of the change */
|
|
47
|
+
source: 'cli' | 'web' | 'sync';
|
|
48
|
+
/** ISO timestamp when event occurred */
|
|
49
|
+
timestamp: string;
|
|
50
|
+
/** Additional metadata about the file */
|
|
51
|
+
metadata: {
|
|
52
|
+
/** File size in bytes */
|
|
53
|
+
size: number;
|
|
54
|
+
/** ISO timestamp of file modification time */
|
|
55
|
+
mtime: string;
|
|
56
|
+
/** Agent version that generated this event */
|
|
57
|
+
agent_version: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* SyncConfig defines agent configuration
|
|
62
|
+
*
|
|
63
|
+
* Configuration is loaded from ~/.gsd-agent/config.json with fallback to defaults.
|
|
64
|
+
* All paths are expanded (~ becomes home directory).
|
|
65
|
+
*/
|
|
66
|
+
export interface SyncConfig {
|
|
67
|
+
/** Supabase project URL */
|
|
68
|
+
supabase_url: string;
|
|
69
|
+
/** Supabase service role key (stored securely) */
|
|
70
|
+
supabase_key: string;
|
|
71
|
+
/** Parent directories to watch for .planning/ folders */
|
|
72
|
+
watch_dirs: string[];
|
|
73
|
+
/** Glob patterns to ignore during watching */
|
|
74
|
+
ignored_patterns: string[];
|
|
75
|
+
/** Debounce delay in milliseconds (default: 300) */
|
|
76
|
+
debounce_ms: number;
|
|
77
|
+
/** Maximum files per batch sync (default: 50) */
|
|
78
|
+
batch_size: number;
|
|
79
|
+
/** Logging level */
|
|
80
|
+
log_level: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
|
|
81
|
+
/** Path to log file */
|
|
82
|
+
log_file: string;
|
|
83
|
+
/** Number of days to keep log files (default: 7) */
|
|
84
|
+
log_rotation_days: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* AgentState represents the runtime state of the agent
|
|
88
|
+
*
|
|
89
|
+
* This is the in-memory state maintained during agent execution.
|
|
90
|
+
* Not persisted to disk (workspaces are persisted separately).
|
|
91
|
+
*/
|
|
92
|
+
export interface AgentState {
|
|
93
|
+
/** Map of workspace ID to workspace metadata */
|
|
94
|
+
workspaces: Map<string, Workspace>;
|
|
95
|
+
/** Queue of pending file change events awaiting sync */
|
|
96
|
+
sync_queue: FileChangeEvent[];
|
|
97
|
+
/** Whether a sync operation is currently in progress */
|
|
98
|
+
is_syncing: boolean;
|
|
99
|
+
/** ISO timestamp of last heartbeat sent to Supabase */
|
|
100
|
+
last_heartbeat: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* RemoteChangeEvent represents a file change from Supabase Realtime
|
|
104
|
+
*
|
|
105
|
+
* These events come from the web UI or other agents modifying files.
|
|
106
|
+
* The agent must apply these changes to the local filesystem.
|
|
107
|
+
*/
|
|
108
|
+
export interface RemoteChangeEvent {
|
|
109
|
+
/** Database record ID */
|
|
110
|
+
id: string;
|
|
111
|
+
/** Reference to the workspace this file belongs to */
|
|
112
|
+
workspace_id: string;
|
|
113
|
+
/** File path relative to workspace root */
|
|
114
|
+
file_path: string;
|
|
115
|
+
/** File content (null for large files in Storage) */
|
|
116
|
+
content: string | null;
|
|
117
|
+
/** SHA-256 hash of file content */
|
|
118
|
+
content_hash: string;
|
|
119
|
+
/** File size in bytes */
|
|
120
|
+
size: number;
|
|
121
|
+
/** ISO timestamp when remote change occurred */
|
|
122
|
+
updated_at: string;
|
|
123
|
+
/** Storage URL for large files (>200KB) */
|
|
124
|
+
storage_url?: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* ConflictEvent represents a detected conflict between local and remote versions
|
|
128
|
+
*
|
|
129
|
+
* Conflict occurs when both local and remote versions changed since last sync.
|
|
130
|
+
* Agent creates git-style conflict markers and commits the conflicted file.
|
|
131
|
+
*/
|
|
132
|
+
export interface ConflictEvent {
|
|
133
|
+
/** Reference to the workspace */
|
|
134
|
+
workspace_id: string;
|
|
135
|
+
/** File path relative to workspace root */
|
|
136
|
+
file_path: string;
|
|
137
|
+
/** SHA-256 hash of local version */
|
|
138
|
+
local_hash: string;
|
|
139
|
+
/** SHA-256 hash of remote version */
|
|
140
|
+
remote_hash: string;
|
|
141
|
+
/** Local file content */
|
|
142
|
+
local_content: string;
|
|
143
|
+
/** Remote file content */
|
|
144
|
+
remote_content: string;
|
|
145
|
+
/** ISO timestamp when conflict detected */
|
|
146
|
+
detected_at: string;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../src/types.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for type definitions
|
|
3
|
+
*
|
|
4
|
+
* Validates that new types compile correctly and have expected structure.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
describe('RemoteChangeEvent type', () => {
|
|
8
|
+
it('should compile with all required fields', () => {
|
|
9
|
+
const event = {
|
|
10
|
+
id: 'evt_123',
|
|
11
|
+
workspace_id: 'ws_456',
|
|
12
|
+
file_path: '.planning/STATE.md',
|
|
13
|
+
content: '# State content',
|
|
14
|
+
content_hash: 'abc123',
|
|
15
|
+
size: 1024,
|
|
16
|
+
updated_at: '2026-03-27T01:00:00Z'
|
|
17
|
+
};
|
|
18
|
+
expect(event.id).toBe('evt_123');
|
|
19
|
+
expect(event.workspace_id).toBe('ws_456');
|
|
20
|
+
expect(event.file_path).toBe('.planning/STATE.md');
|
|
21
|
+
expect(event.content).toBe('# State content');
|
|
22
|
+
expect(event.content_hash).toBe('abc123');
|
|
23
|
+
expect(event.size).toBe(1024);
|
|
24
|
+
expect(event.updated_at).toBe('2026-03-27T01:00:00Z');
|
|
25
|
+
});
|
|
26
|
+
it('should allow null content for large files', () => {
|
|
27
|
+
const event = {
|
|
28
|
+
id: 'evt_789',
|
|
29
|
+
workspace_id: 'ws_456',
|
|
30
|
+
file_path: '.planning/large-file.md',
|
|
31
|
+
content: null,
|
|
32
|
+
content_hash: 'def456',
|
|
33
|
+
size: 300000,
|
|
34
|
+
updated_at: '2026-03-27T01:00:00Z',
|
|
35
|
+
storage_url: 'https://storage.supabase.co/bucket/file.md'
|
|
36
|
+
};
|
|
37
|
+
expect(event.content).toBeNull();
|
|
38
|
+
expect(event.storage_url).toBe('https://storage.supabase.co/bucket/file.md');
|
|
39
|
+
});
|
|
40
|
+
it('should allow optional storage_url', () => {
|
|
41
|
+
const event = {
|
|
42
|
+
id: 'evt_999',
|
|
43
|
+
workspace_id: 'ws_456',
|
|
44
|
+
file_path: '.planning/small.md',
|
|
45
|
+
content: 'small content',
|
|
46
|
+
content_hash: 'ghi789',
|
|
47
|
+
size: 100,
|
|
48
|
+
updated_at: '2026-03-27T01:00:00Z'
|
|
49
|
+
};
|
|
50
|
+
expect(event.storage_url).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('ConflictEvent type', () => {
|
|
54
|
+
it('should compile with all required fields', () => {
|
|
55
|
+
const conflict = {
|
|
56
|
+
workspace_id: 'ws_456',
|
|
57
|
+
file_path: '.planning/PROJECT.md',
|
|
58
|
+
local_hash: 'local_abc',
|
|
59
|
+
remote_hash: 'remote_def',
|
|
60
|
+
local_content: 'Local version',
|
|
61
|
+
remote_content: 'Remote version',
|
|
62
|
+
detected_at: '2026-03-27T01:30:00Z'
|
|
63
|
+
};
|
|
64
|
+
expect(conflict.workspace_id).toBe('ws_456');
|
|
65
|
+
expect(conflict.file_path).toBe('.planning/PROJECT.md');
|
|
66
|
+
expect(conflict.local_hash).toBe('local_abc');
|
|
67
|
+
expect(conflict.remote_hash).toBe('remote_def');
|
|
68
|
+
expect(conflict.local_content).toBe('Local version');
|
|
69
|
+
expect(conflict.remote_content).toBe('Remote version');
|
|
70
|
+
expect(conflict.detected_at).toBe('2026-03-27T01:30:00Z');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.js","sourceRoot":"","sources":["../src/types.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem watcher for GSD Agent
|
|
3
|
+
*
|
|
4
|
+
* Watches .planning/ directories for file changes using chokidar.
|
|
5
|
+
* Handles atomic writes, debouncing, and ignored patterns per research findings.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import { Workspace, SyncConfig } from './types.js';
|
|
9
|
+
import { Logger } from './logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* FileWatcher class monitors .planning/ directories for changes
|
|
12
|
+
*/
|
|
13
|
+
export declare class FileWatcher extends EventEmitter {
|
|
14
|
+
private workspaces;
|
|
15
|
+
private config;
|
|
16
|
+
private logger;
|
|
17
|
+
private watcher;
|
|
18
|
+
private debounceTimers;
|
|
19
|
+
constructor(workspaces: Workspace[], config: SyncConfig, logger: Logger);
|
|
20
|
+
/**
|
|
21
|
+
* Start watching all workspace .planning/ directories
|
|
22
|
+
*/
|
|
23
|
+
start(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stop watching and clean up
|
|
26
|
+
*/
|
|
27
|
+
stop(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Handle file system events with debouncing
|
|
30
|
+
* @param filePath Absolute path to changed file
|
|
31
|
+
* @param eventType Type of change event
|
|
32
|
+
*/
|
|
33
|
+
private handleFileEvent;
|
|
34
|
+
/**
|
|
35
|
+
* Process a file event and emit FileChangeEvent
|
|
36
|
+
* @param filePath Absolute path to changed file
|
|
37
|
+
* @param eventType Type of change event
|
|
38
|
+
*/
|
|
39
|
+
private processFileEvent;
|
|
40
|
+
/**
|
|
41
|
+
* Find workspace that contains the given file path
|
|
42
|
+
* @param filePath Absolute path to file
|
|
43
|
+
* @returns Workspace object or null if not found
|
|
44
|
+
*/
|
|
45
|
+
private findWorkspaceForFile;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create and start a filesystem watcher
|
|
49
|
+
* @param workspaces Array of workspaces to watch
|
|
50
|
+
* @param config SyncConfig with watch settings
|
|
51
|
+
* @param logger Logger instance
|
|
52
|
+
* @returns FileWatcher instance
|
|
53
|
+
*/
|
|
54
|
+
export declare function createWatcher(workspaces: Workspace[], config: SyncConfig, logger: Logger): FileWatcher;
|
|
55
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC;;GAEG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,cAAc,CAAyC;gBAEnD,UAAU,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM;IAOvE;;OAEG;IACH,KAAK,IAAI,IAAI;IA2Db;;OAEG;IACH,IAAI,IAAI,IAAI;IAeZ;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAqBvB;;;;OAIG;YACW,gBAAgB;IAmE9B;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;CAQ7B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,GACb,WAAW,CAIb"}
|
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem watcher for GSD Agent
|
|
3
|
+
*
|
|
4
|
+
* Watches .planning/ directories for file changes using chokidar.
|
|
5
|
+
* Handles atomic writes, debouncing, and ignored patterns per research findings.
|
|
6
|
+
*/
|
|
7
|
+
import chokidar from 'chokidar';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
import { hashFile } from './hash.js';
|
|
13
|
+
/**
|
|
14
|
+
* FileWatcher class monitors .planning/ directories for changes
|
|
15
|
+
*/
|
|
16
|
+
export class FileWatcher extends EventEmitter {
|
|
17
|
+
workspaces;
|
|
18
|
+
config;
|
|
19
|
+
logger;
|
|
20
|
+
watcher = null;
|
|
21
|
+
debounceTimers = new Map();
|
|
22
|
+
constructor(workspaces, config, logger) {
|
|
23
|
+
super();
|
|
24
|
+
this.workspaces = workspaces;
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.logger = logger;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Start watching all workspace .planning/ directories
|
|
30
|
+
*/
|
|
31
|
+
start() {
|
|
32
|
+
if (this.watcher) {
|
|
33
|
+
this.logger.warn('Watcher already started');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Build list of paths to watch
|
|
37
|
+
const watchPaths = this.workspaces.map(ws => path.join(ws.root_path, '.planning'));
|
|
38
|
+
// Filter out non-existent paths
|
|
39
|
+
const existingPaths = watchPaths.filter(p => {
|
|
40
|
+
if (!fs.existsSync(p)) {
|
|
41
|
+
this.logger.warn(`Watch path does not exist: ${p}`);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
if (existingPaths.length === 0) {
|
|
47
|
+
this.logger.warn('No valid watch paths found');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Configure chokidar with atomic write handling and ignored patterns
|
|
51
|
+
this.watcher = chokidar.watch(existingPaths, {
|
|
52
|
+
ignored: [
|
|
53
|
+
/node_modules/,
|
|
54
|
+
/\.git/,
|
|
55
|
+
/dist/,
|
|
56
|
+
/build/,
|
|
57
|
+
/\.log$/,
|
|
58
|
+
/\.DS_Store$/
|
|
59
|
+
],
|
|
60
|
+
persistent: true,
|
|
61
|
+
ignoreInitial: false, // emit events for existing files on startup
|
|
62
|
+
awaitWriteFinish: {
|
|
63
|
+
stabilityThreshold: 300, // wait 300ms for file size to stabilize
|
|
64
|
+
pollInterval: 100
|
|
65
|
+
},
|
|
66
|
+
atomic: true, // filter atomic write temp files
|
|
67
|
+
depth: 5 // limit recursion depth
|
|
68
|
+
});
|
|
69
|
+
// Set up event handlers
|
|
70
|
+
this.watcher
|
|
71
|
+
.on('add', (filePath) => this.handleFileEvent(filePath, 'add'))
|
|
72
|
+
.on('change', (filePath) => this.handleFileEvent(filePath, 'change'))
|
|
73
|
+
.on('unlink', (filePath) => this.handleFileEvent(filePath, 'unlink'))
|
|
74
|
+
.on('error', (error) => {
|
|
75
|
+
this.logger.error('Watcher error', { error });
|
|
76
|
+
})
|
|
77
|
+
.on('ready', () => {
|
|
78
|
+
this.logger.info('Filesystem watcher ready', {
|
|
79
|
+
paths: existingPaths,
|
|
80
|
+
workspaces: this.workspaces.length
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Stop watching and clean up
|
|
86
|
+
*/
|
|
87
|
+
stop() {
|
|
88
|
+
if (this.watcher) {
|
|
89
|
+
this.watcher.close();
|
|
90
|
+
this.watcher = null;
|
|
91
|
+
}
|
|
92
|
+
// Clear all pending debounce timers
|
|
93
|
+
for (const timer of this.debounceTimers.values()) {
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
}
|
|
96
|
+
this.debounceTimers.clear();
|
|
97
|
+
this.logger.info('Filesystem watcher stopped');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Handle file system events with debouncing
|
|
101
|
+
* @param filePath Absolute path to changed file
|
|
102
|
+
* @param eventType Type of change event
|
|
103
|
+
*/
|
|
104
|
+
handleFileEvent(filePath, eventType) {
|
|
105
|
+
// For unlink events, emit immediately (no debounce)
|
|
106
|
+
if (eventType === 'unlink') {
|
|
107
|
+
void this.processFileEvent(filePath, eventType);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// For add/change events, debounce to handle rapid changes
|
|
111
|
+
const existingTimer = this.debounceTimers.get(filePath);
|
|
112
|
+
if (existingTimer) {
|
|
113
|
+
clearTimeout(existingTimer);
|
|
114
|
+
}
|
|
115
|
+
const timer = setTimeout(() => {
|
|
116
|
+
this.debounceTimers.delete(filePath);
|
|
117
|
+
void this.processFileEvent(filePath, eventType);
|
|
118
|
+
}, this.config.debounce_ms);
|
|
119
|
+
this.debounceTimers.set(filePath, timer);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Process a file event and emit FileChangeEvent
|
|
123
|
+
* @param filePath Absolute path to changed file
|
|
124
|
+
* @param eventType Type of change event
|
|
125
|
+
*/
|
|
126
|
+
async processFileEvent(filePath, eventType) {
|
|
127
|
+
try {
|
|
128
|
+
// Find workspace for this file
|
|
129
|
+
const workspace = this.findWorkspaceForFile(filePath);
|
|
130
|
+
if (!workspace) {
|
|
131
|
+
this.logger.warn(`No workspace found for file: ${filePath}`);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Compute relative path from workspace root
|
|
135
|
+
const relativePath = path.relative(workspace.root_path, filePath);
|
|
136
|
+
// Build FileChangeEvent
|
|
137
|
+
let contentHash = '';
|
|
138
|
+
let content;
|
|
139
|
+
let metadata;
|
|
140
|
+
if (eventType !== 'unlink') {
|
|
141
|
+
try {
|
|
142
|
+
// Read file content and compute hash
|
|
143
|
+
content = fs.readFileSync(filePath, 'utf-8');
|
|
144
|
+
contentHash = await hashFile(filePath);
|
|
145
|
+
// Get file stats
|
|
146
|
+
const stats = fs.statSync(filePath);
|
|
147
|
+
metadata = {
|
|
148
|
+
size: stats.size,
|
|
149
|
+
mtime: stats.mtime.toISOString(),
|
|
150
|
+
agent_version: '0.1.0'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
this.logger.error(`Failed to read file: ${filePath}`, { error });
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// For unlink events, no content or metadata
|
|
160
|
+
metadata = {
|
|
161
|
+
size: 0,
|
|
162
|
+
mtime: new Date().toISOString(),
|
|
163
|
+
agent_version: '0.1.0'
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const event = {
|
|
167
|
+
id: randomUUID(),
|
|
168
|
+
workspace_id: workspace.id,
|
|
169
|
+
file_path: relativePath,
|
|
170
|
+
event_type: eventType,
|
|
171
|
+
content_hash: contentHash,
|
|
172
|
+
content,
|
|
173
|
+
source: 'cli',
|
|
174
|
+
timestamp: new Date().toISOString(),
|
|
175
|
+
metadata
|
|
176
|
+
};
|
|
177
|
+
// Emit the event
|
|
178
|
+
this.emit('change', event);
|
|
179
|
+
this.logger.debug(`File event processed: ${eventType} ${relativePath}`, {
|
|
180
|
+
workspace_id: workspace.id,
|
|
181
|
+
content_hash: contentHash
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
this.logger.error(`Error processing file event: ${filePath}`, { error });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Find workspace that contains the given file path
|
|
190
|
+
* @param filePath Absolute path to file
|
|
191
|
+
* @returns Workspace object or null if not found
|
|
192
|
+
*/
|
|
193
|
+
findWorkspaceForFile(filePath) {
|
|
194
|
+
for (const workspace of this.workspaces) {
|
|
195
|
+
if (filePath.startsWith(workspace.root_path)) {
|
|
196
|
+
return workspace;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Create and start a filesystem watcher
|
|
204
|
+
* @param workspaces Array of workspaces to watch
|
|
205
|
+
* @param config SyncConfig with watch settings
|
|
206
|
+
* @param logger Logger instance
|
|
207
|
+
* @returns FileWatcher instance
|
|
208
|
+
*/
|
|
209
|
+
export function createWatcher(workspaces, config, logger) {
|
|
210
|
+
const watcher = new FileWatcher(workspaces, config, logger);
|
|
211
|
+
watcher.start();
|
|
212
|
+
return watcher;
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.test.d.ts","sourceRoot":"","sources":["../src/watcher.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|