@gitgov/core 1.13.0 → 2.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 +151 -270
- package/dist/src/agent_runner-COAjsdtr.d.ts +2585 -0
- package/dist/src/fs.d.ts +1375 -0
- package/dist/src/fs.js +8483 -0
- package/dist/src/fs.js.map +1 -0
- package/dist/src/index-DMkBFK4C.d.ts +807 -0
- package/dist/src/index.d.ts +1709 -5212
- package/dist/src/index.js +4779 -8956
- package/dist/src/index.js.map +1 -1
- package/dist/src/memory.d.ts +267 -0
- package/dist/src/memory.js +790 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/memory_file_lister-D0llxocS.d.ts +221 -0
- package/package.json +19 -8
- package/prompts/gitgov_agent_prompt.md +0 -480
package/dist/src/fs.d.ts
ADDED
|
@@ -0,0 +1,1375 @@
|
|
|
1
|
+
import { R as RecordStore, C as ConfigStore, G as GitGovConfig, S as SessionStore, a as GitGovSession, I as IGitModule, b as GitModuleDependencies, E as ExecOptions, c as ExecResult, d as ChangedFile, e as GetCommitHistoryOptions, f as CommitInfo, g as CommitAuthor } from './index-DMkBFK4C.js';
|
|
2
|
+
export { F as FsFileListerOptions } from './index-DMkBFK4C.js';
|
|
3
|
+
import { C as ConfigManager, S as SessionManager, I as ILintModule, L as LintOptions, a as LintReport, F as FixRecordOptions, b as FixReport, R as RecordStores, c as IIndexerAdapter, G as GitGovRecord, d as LintRecordContext, e as LintResult, f as IProjectInitializer, E as EnvironmentValidation, g as ISyncStateModule, h as SyncStateModuleDependencies, i as StateDeltaFile, j as ConflictDiff, k as IntegrityViolation, A as AuditStateOptions, l as AuditStateReport, m as SyncStatePushOptions, n as SyncStatePushResult, o as SyncStatePullOptions, p as SyncStatePullResult, q as SyncStateResolveOptions, r as SyncStateResolveResult, s as IEventStream, t as IAgentRunner, P as ProtocolHandlerRegistry, u as AgentRunnerDependencies, v as RunOptions, w as AgentResponse } from './agent_runner-COAjsdtr.js';
|
|
4
|
+
export { z as FsFileLister, x as FsKeyProvider, y as FsKeyProviderOptions } from './agent_runner-COAjsdtr.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Serializer for FsRecordStore - allows custom serialization
|
|
8
|
+
*/
|
|
9
|
+
interface Serializer {
|
|
10
|
+
stringify: (value: unknown) => string;
|
|
11
|
+
parse: <T>(text: string) => T;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* IdEncoder for transforming IDs to filesystem-safe filenames
|
|
15
|
+
* Useful for characters not allowed in filesystem (e.g., `:` on Windows)
|
|
16
|
+
*/
|
|
17
|
+
interface IdEncoder {
|
|
18
|
+
/** Transform ID to filename-safe string */
|
|
19
|
+
encode: (id: string) => string;
|
|
20
|
+
/** Recover original ID from filename */
|
|
21
|
+
decode: (encoded: string) => string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Default encoder: `:` → `_` (for IDs like "human:camilo")
|
|
25
|
+
* Reversible because IDs cannot contain `_` (see id_generator.ts)
|
|
26
|
+
*/
|
|
27
|
+
declare const DEFAULT_ID_ENCODER: IdEncoder;
|
|
28
|
+
/**
|
|
29
|
+
* Options for FsRecordStore
|
|
30
|
+
*/
|
|
31
|
+
interface FsRecordStoreOptions {
|
|
32
|
+
/** Base directory for files */
|
|
33
|
+
basePath: string;
|
|
34
|
+
/** File extension (default: ".json") */
|
|
35
|
+
extension?: string;
|
|
36
|
+
/** Custom serializer (default: JSON with indent 2) */
|
|
37
|
+
serializer?: Serializer;
|
|
38
|
+
/** Create directory if it doesn't exist (default: true) */
|
|
39
|
+
createIfMissing?: boolean;
|
|
40
|
+
/** ID encoder for filesystem-safe filenames (default: undefined = no encoding) */
|
|
41
|
+
idEncoder?: IdEncoder;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* FsRecordStore<T> - Filesystem implementation of Store<T>
|
|
45
|
+
*
|
|
46
|
+
* Persists records as JSON files on disk.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* const store = new FsRecordStore<TaskRecord>({
|
|
50
|
+
* basePath: '.gitgov/tasks',
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* await store.put('123-task-foo', task);
|
|
54
|
+
* const task = await store.get('123-task-foo');
|
|
55
|
+
*/
|
|
56
|
+
declare class FsRecordStore<T> implements RecordStore<T> {
|
|
57
|
+
private readonly basePath;
|
|
58
|
+
private readonly extension;
|
|
59
|
+
private readonly serializer;
|
|
60
|
+
private readonly createIfMissing;
|
|
61
|
+
private readonly idEncoder;
|
|
62
|
+
constructor(options: FsRecordStoreOptions);
|
|
63
|
+
private getFilePath;
|
|
64
|
+
get(id: string): Promise<T | null>;
|
|
65
|
+
put(id: string, value: T): Promise<void>;
|
|
66
|
+
delete(id: string): Promise<void>;
|
|
67
|
+
list(): Promise<string[]>;
|
|
68
|
+
exists(id: string): Promise<boolean>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* FsConfigStore - Filesystem implementation of ConfigStore
|
|
73
|
+
*
|
|
74
|
+
* Handles persistence of config.json to the local filesystem.
|
|
75
|
+
*
|
|
76
|
+
* NOTE: Session state (.session.json) is handled by FsSessionStore.
|
|
77
|
+
* NOTE: Project discovery utilities are in src/utils/project_discovery.ts
|
|
78
|
+
*
|
|
79
|
+
* @see packages/blueprints/03_products/core/specs/modules/config_store_module/fs_config_store_module.md
|
|
80
|
+
* @see packages/blueprints/03_products/protocol/10_appendices/config_file.md
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Filesystem-based ConfigStore implementation.
|
|
85
|
+
*
|
|
86
|
+
* Stores configuration in .gitgov/config.json.
|
|
87
|
+
* Implements fail-safe pattern: returns null instead of throwing for missing files.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const store = new FsConfigStore('/path/to/project');
|
|
92
|
+
* const config = await store.loadConfig();
|
|
93
|
+
* if (config) {
|
|
94
|
+
* console.log(config.projectName);
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
declare class FsConfigStore implements ConfigStore {
|
|
99
|
+
private readonly configPath;
|
|
100
|
+
constructor(projectRootPath: string);
|
|
101
|
+
/**
|
|
102
|
+
* Load project configuration from .gitgov/config.json
|
|
103
|
+
*
|
|
104
|
+
* [EARS-A1] Returns complete GitGovConfig for valid files
|
|
105
|
+
* [EARS-A2] Returns null for non-existent files (fail-safe)
|
|
106
|
+
* [EARS-A3] Returns null for invalid JSON (graceful degradation)
|
|
107
|
+
*/
|
|
108
|
+
loadConfig(): Promise<GitGovConfig | null>;
|
|
109
|
+
/**
|
|
110
|
+
* Save project configuration to .gitgov/config.json
|
|
111
|
+
*
|
|
112
|
+
* [EARS-A4] Writes config with JSON indentation
|
|
113
|
+
*/
|
|
114
|
+
saveConfig(config: GitGovConfig): Promise<void>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Create a ConfigManager instance for a project.
|
|
118
|
+
*
|
|
119
|
+
* [EARS-B1] Factory function that creates a ConfigManager with FsConfigStore backend.
|
|
120
|
+
* Use this when you already have the projectRoot (e.g., from DI container).
|
|
121
|
+
*
|
|
122
|
+
* @param projectRoot - Absolute path to project root (REQUIRED)
|
|
123
|
+
* @returns ConfigManager instance with FsConfigStore backend
|
|
124
|
+
*/
|
|
125
|
+
declare function createConfigManager(projectRoot: string): ConfigManager;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* FsSessionStore - Filesystem implementation of SessionStore
|
|
129
|
+
*
|
|
130
|
+
* Handles persistence of .session.json to the local filesystem.
|
|
131
|
+
* Session files are machine-local and NOT versioned in Git.
|
|
132
|
+
*
|
|
133
|
+
* @see packages/blueprints/03_products/core/specs/modules/session_store_module/fs_session_store_module.md
|
|
134
|
+
* @see packages/blueprints/03_products/protocol/10_appendices/session_state.md
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Filesystem-based SessionStore implementation.
|
|
139
|
+
*
|
|
140
|
+
* Stores session state in .gitgov/.session.json.
|
|
141
|
+
* Implements fail-safe pattern: returns null instead of throwing for missing files.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* const store = new FsSessionStore('/path/to/project');
|
|
146
|
+
* const session = await store.loadSession();
|
|
147
|
+
* if (session) {
|
|
148
|
+
* console.log(session.lastSession?.actorId);
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
declare class FsSessionStore implements SessionStore {
|
|
153
|
+
private readonly sessionPath;
|
|
154
|
+
private readonly actorsPath;
|
|
155
|
+
constructor(projectRootPath: string);
|
|
156
|
+
/**
|
|
157
|
+
* Load local session from .gitgov/.session.json
|
|
158
|
+
*
|
|
159
|
+
* [EARS-A1] Returns complete GitGovSession for valid files
|
|
160
|
+
* [EARS-A2] Returns null for non-existent files (fail-safe)
|
|
161
|
+
* [EARS-A3] Returns null for invalid JSON (graceful degradation)
|
|
162
|
+
* [EARS-A4] Returns cloud token if present
|
|
163
|
+
* [EARS-A5] Returns syncPreferences if present
|
|
164
|
+
*/
|
|
165
|
+
loadSession(): Promise<GitGovSession | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Save local session to .gitgov/.session.json
|
|
168
|
+
*
|
|
169
|
+
* [EARS-B1] Writes session to .gitgov/.session.json with JSON indentation
|
|
170
|
+
* [EARS-B2] Preserves all fields (cloud, actorState, syncPreferences)
|
|
171
|
+
*/
|
|
172
|
+
saveSession(session: GitGovSession): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Detect actor from .key files in .gitgov/actors/
|
|
175
|
+
*
|
|
176
|
+
* [EARS-C1] Returns actor ID from first .key file
|
|
177
|
+
* [EARS-C2] Returns first .key file alphabetically if multiple exist
|
|
178
|
+
* [EARS-C3] Returns null if no .key files exist
|
|
179
|
+
* [EARS-C4] Returns null if actors directory doesn't exist
|
|
180
|
+
* [EARS-C5] Ignores non-.key files
|
|
181
|
+
* [EARS-C6] Returns null for empty directory
|
|
182
|
+
*
|
|
183
|
+
* @returns Actor ID (e.g., "human:camilo-v2") or null
|
|
184
|
+
*/
|
|
185
|
+
detectActorFromKeyFiles(): Promise<string | null>;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Create a SessionManager instance for a project.
|
|
189
|
+
*
|
|
190
|
+
* [EARS-D1] Factory function that creates a SessionManager with FsSessionStore backend.
|
|
191
|
+
* Use this when you already have the projectRoot (e.g., from DI container).
|
|
192
|
+
*
|
|
193
|
+
* @param projectRoot - Absolute path to project root (REQUIRED)
|
|
194
|
+
* @returns SessionManager instance with FsSessionStore backend
|
|
195
|
+
*/
|
|
196
|
+
declare function createSessionManager(projectRoot: string): SessionManager;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Filesystem-specific types for FsLintModule.
|
|
200
|
+
*
|
|
201
|
+
* These types are exported via @gitgov/core/fs subpath.
|
|
202
|
+
* For pure validation types, use @gitgov/core.
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Public interface for FsLintModule operations (with I/O).
|
|
207
|
+
*
|
|
208
|
+
* This interface wraps LintModule and adds filesystem operations:
|
|
209
|
+
* - Directory scanning for record discovery
|
|
210
|
+
* - File reading and parsing
|
|
211
|
+
* - Backup creation and restoration
|
|
212
|
+
* - File writing for fixes
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const fsLintModule: IFsLintModule = new FsLintModule({
|
|
217
|
+
* lintModule,
|
|
218
|
+
* stores
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* // Scan directory and validate all records
|
|
222
|
+
* const report = await fsLintModule.lint({ path: '.gitgov/' });
|
|
223
|
+
*
|
|
224
|
+
* // Validate specific file
|
|
225
|
+
* const fileReport = await fsLintModule.lintFile(filePath);
|
|
226
|
+
*
|
|
227
|
+
* // Fix with backups
|
|
228
|
+
* const fixReport = await fsLintModule.fix(report, { createBackups: true });
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
interface IFsLintModule extends ILintModule {
|
|
232
|
+
/**
|
|
233
|
+
* Scans directories and validates all records.
|
|
234
|
+
* Overrides ILintModule.lint() to accept filesystem-specific options.
|
|
235
|
+
*/
|
|
236
|
+
lint(options?: Partial<FsLintOptions>): Promise<LintReport>;
|
|
237
|
+
/**
|
|
238
|
+
* Validates a specific file.
|
|
239
|
+
*/
|
|
240
|
+
lintFile(filePath: string, options?: Partial<FsLintOptions>): Promise<LintReport>;
|
|
241
|
+
/**
|
|
242
|
+
* Applies automatic repairs to files, creating backups.
|
|
243
|
+
*/
|
|
244
|
+
fix(lintReport: LintReport, fixOptions?: Partial<FsFixOptions>): Promise<FixReport>;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Dependencies for FsLintModule.
|
|
248
|
+
*/
|
|
249
|
+
interface FsLintModuleDependencies {
|
|
250
|
+
/** Absolute path to project root (REQUIRED, injected from DI/CLI bootstrap) */
|
|
251
|
+
projectRoot: string;
|
|
252
|
+
/** Core LintModule for pure validation (REQUIRED) */
|
|
253
|
+
lintModule: ILintModule;
|
|
254
|
+
/** Record stores for reference lookups (OPTIONAL) */
|
|
255
|
+
stores?: RecordStores;
|
|
256
|
+
/** Indexer adapter for reference resolution (OPTIONAL) */
|
|
257
|
+
indexerAdapter?: IIndexerAdapter;
|
|
258
|
+
/** FileSystem abstraction for I/O (OPTIONAL, default: Node.js fs) */
|
|
259
|
+
fileSystem?: FileSystem;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Options for FsLintModule operations.
|
|
263
|
+
* Extends LintOptions with filesystem-specific settings.
|
|
264
|
+
*/
|
|
265
|
+
interface FsLintOptions extends LintOptions {
|
|
266
|
+
/** Directory or file to validate (default: '.gitgov/') */
|
|
267
|
+
path?: string;
|
|
268
|
+
/** Validate file naming conventions (default: true) */
|
|
269
|
+
validateFileNaming?: boolean;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Options for FsLintModule fix operation.
|
|
273
|
+
* Extends FixRecordOptions with filesystem-specific settings.
|
|
274
|
+
*/
|
|
275
|
+
interface FsFixOptions extends FixRecordOptions {
|
|
276
|
+
/** Create backups before modifying files (default: true) */
|
|
277
|
+
createBackups?: boolean;
|
|
278
|
+
/** Dry-run mode that reports without applying changes (default: false) */
|
|
279
|
+
dryRun?: boolean;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* FileSystem interface for I/O operations.
|
|
283
|
+
* Can be mocked for testing.
|
|
284
|
+
*/
|
|
285
|
+
interface FileSystem {
|
|
286
|
+
readFile(path: string, encoding: string): Promise<string>;
|
|
287
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
288
|
+
exists(path: string): Promise<boolean>;
|
|
289
|
+
unlink(path: string): Promise<void>;
|
|
290
|
+
readdir?(path: string): Promise<string[]>;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* FsLintModule - Filesystem-aware Validation
|
|
295
|
+
*
|
|
296
|
+
* This module wraps the pure LintModule and adds filesystem operations:
|
|
297
|
+
* - Directory scanning for record discovery (EARS-A1)
|
|
298
|
+
* - File naming validation (EARS-B1, EARS-B2)
|
|
299
|
+
* - Backup creation and restoration (EARS-C1, EARS-C2)
|
|
300
|
+
* - Delegation to LintModule core (EARS-D1)
|
|
301
|
+
* - Schema version detection (EARS-E1)
|
|
302
|
+
* - Error filtering (EARS-F1)
|
|
303
|
+
*
|
|
304
|
+
* @see fs_lint_module.md for EARS specifications
|
|
305
|
+
* @module lint/fs
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Filesystem-aware lint module.
|
|
310
|
+
* Wraps LintModule (pure) and adds I/O operations.
|
|
311
|
+
*
|
|
312
|
+
* @implements {IFsLintModule}
|
|
313
|
+
*/
|
|
314
|
+
declare class FsLintModule implements IFsLintModule {
|
|
315
|
+
private readonly projectRoot;
|
|
316
|
+
private readonly lintModule;
|
|
317
|
+
private readonly fileSystem;
|
|
318
|
+
private lastBackupPath;
|
|
319
|
+
/**
|
|
320
|
+
* Constructor for FsLintModule.
|
|
321
|
+
*
|
|
322
|
+
* @param dependencies - Module dependencies
|
|
323
|
+
*/
|
|
324
|
+
constructor(dependencies: FsLintModuleDependencies);
|
|
325
|
+
/**
|
|
326
|
+
* Delegates to LintModule.lintRecord() for pure validation.
|
|
327
|
+
*/
|
|
328
|
+
lintRecord(record: GitGovRecord, context: LintRecordContext): LintResult[];
|
|
329
|
+
/**
|
|
330
|
+
* Delegates to LintModule.fixRecord() for pure fix.
|
|
331
|
+
*/
|
|
332
|
+
fixRecord(record: GitGovRecord, results: LintResult[], options: FixRecordOptions): GitGovRecord;
|
|
333
|
+
/**
|
|
334
|
+
* [EARS-A1] Scans directories and validates all records.
|
|
335
|
+
*
|
|
336
|
+
* @param options - Configuration options
|
|
337
|
+
* @returns Consolidated lint report
|
|
338
|
+
*/
|
|
339
|
+
lint(options?: Partial<FsLintOptions>): Promise<LintReport>;
|
|
340
|
+
/**
|
|
341
|
+
* Validates a specific file.
|
|
342
|
+
*
|
|
343
|
+
* @param filePath - Path to the file to validate
|
|
344
|
+
* @param options - Configuration options
|
|
345
|
+
* @returns Lint report for this single file
|
|
346
|
+
*/
|
|
347
|
+
lintFile(filePath: string, options?: Partial<FsLintOptions>): Promise<LintReport>;
|
|
348
|
+
/**
|
|
349
|
+
* Applies automatic repairs to files, creating backups.
|
|
350
|
+
*
|
|
351
|
+
* @param lintReport - Lint report with detected problems
|
|
352
|
+
* @param fixOptions - Options for the fix operation
|
|
353
|
+
* @returns Report of applied repairs
|
|
354
|
+
*/
|
|
355
|
+
fix(lintReport: LintReport, fixOptions?: Partial<FsFixOptions>): Promise<FixReport>;
|
|
356
|
+
/**
|
|
357
|
+
* Validates a single record by reading from filesystem.
|
|
358
|
+
* @private
|
|
359
|
+
*/
|
|
360
|
+
private lintSingleRecord;
|
|
361
|
+
/**
|
|
362
|
+
* [EARS-B1, EARS-B2] Validates file naming conventions.
|
|
363
|
+
* @private
|
|
364
|
+
*/
|
|
365
|
+
private validateFileNaming;
|
|
366
|
+
/**
|
|
367
|
+
* [EARS-A1] Discovers all records with their types by scanning filesystem.
|
|
368
|
+
* @private
|
|
369
|
+
*/
|
|
370
|
+
private discoverAllRecordsWithTypes;
|
|
371
|
+
/**
|
|
372
|
+
* Gets file path for a record.
|
|
373
|
+
* @private
|
|
374
|
+
*/
|
|
375
|
+
private getFilePath;
|
|
376
|
+
/**
|
|
377
|
+
* [EARS-C1] Creates a backup of a file before modification.
|
|
378
|
+
* @private
|
|
379
|
+
*/
|
|
380
|
+
private createBackup;
|
|
381
|
+
/**
|
|
382
|
+
* [EARS-C2] Restores file from backup if fix fails.
|
|
383
|
+
* @private
|
|
384
|
+
*/
|
|
385
|
+
private restoreBackup;
|
|
386
|
+
/**
|
|
387
|
+
* Applies a fix to a file.
|
|
388
|
+
* @private
|
|
389
|
+
*/
|
|
390
|
+
private applyFix;
|
|
391
|
+
/**
|
|
392
|
+
* Fixes legacy record with embedded metadata issues.
|
|
393
|
+
* @private
|
|
394
|
+
*/
|
|
395
|
+
private fixLegacyRecord;
|
|
396
|
+
/**
|
|
397
|
+
* Fixes bidirectional reference inconsistencies.
|
|
398
|
+
* @private
|
|
399
|
+
*/
|
|
400
|
+
private fixBidirectionalReference;
|
|
401
|
+
/**
|
|
402
|
+
* Recalculates checksum for a record.
|
|
403
|
+
* @private
|
|
404
|
+
*/
|
|
405
|
+
private recalculateChecksum;
|
|
406
|
+
/**
|
|
407
|
+
* Fixes signature structure issues.
|
|
408
|
+
* @private
|
|
409
|
+
*/
|
|
410
|
+
private fixSignatureStructure;
|
|
411
|
+
/**
|
|
412
|
+
* [EARS-E1] Detects validator type from error message.
|
|
413
|
+
* Includes detection of SCHEMA_VERSION_MISMATCH for outdated schemas.
|
|
414
|
+
* @private
|
|
415
|
+
*/
|
|
416
|
+
private detectValidatorType;
|
|
417
|
+
/**
|
|
418
|
+
* Determines if an error is fixable.
|
|
419
|
+
* @private
|
|
420
|
+
*/
|
|
421
|
+
private isFixable;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* FsProjectInitializer - Filesystem implementation of IProjectInitializer.
|
|
426
|
+
*
|
|
427
|
+
* Initializes GitGovernance projects on the local filesystem,
|
|
428
|
+
* creating the .gitgov/ directory structure and configuration files.
|
|
429
|
+
*
|
|
430
|
+
* The projectRoot is injected at construction time (DI from CLI/bootstrap).
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```typescript
|
|
434
|
+
* const initializer = new FsProjectInitializer('/path/to/project');
|
|
435
|
+
*
|
|
436
|
+
* const validation = await initializer.validateEnvironment();
|
|
437
|
+
* if (!validation.isValid) {
|
|
438
|
+
* console.log(validation.warnings);
|
|
439
|
+
* return;
|
|
440
|
+
* }
|
|
441
|
+
*
|
|
442
|
+
* await initializer.createProjectStructure();
|
|
443
|
+
* await initializer.writeConfig(config);
|
|
444
|
+
* await initializer.initializeSession(actorId);
|
|
445
|
+
* await initializer.copyAgentPrompt();
|
|
446
|
+
* await initializer.setupGitIntegration();
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
declare class FsProjectInitializer implements IProjectInitializer {
|
|
450
|
+
private readonly projectRoot;
|
|
451
|
+
constructor(projectRoot: string);
|
|
452
|
+
/**
|
|
453
|
+
* Creates the .gitgov/ directory structure.
|
|
454
|
+
*/
|
|
455
|
+
createProjectStructure(): Promise<void>;
|
|
456
|
+
/**
|
|
457
|
+
* Checks if .gitgov/config.json exists.
|
|
458
|
+
*/
|
|
459
|
+
isInitialized(): Promise<boolean>;
|
|
460
|
+
/**
|
|
461
|
+
* Writes config.json to .gitgov/
|
|
462
|
+
*/
|
|
463
|
+
writeConfig(config: GitGovConfig): Promise<void>;
|
|
464
|
+
/**
|
|
465
|
+
* Creates .session.json with initial actor state.
|
|
466
|
+
*/
|
|
467
|
+
initializeSession(actorId: string): Promise<void>;
|
|
468
|
+
/**
|
|
469
|
+
* Reads a file from the filesystem.
|
|
470
|
+
*/
|
|
471
|
+
readFile(filePath: string): Promise<string>;
|
|
472
|
+
/**
|
|
473
|
+
* Gets the path for an actor record.
|
|
474
|
+
*/
|
|
475
|
+
getActorPath(actorId: string): string;
|
|
476
|
+
/**
|
|
477
|
+
* Validates environment for GitGovernance initialization.
|
|
478
|
+
* Checks: Git repo exists, write permissions, not already initialized.
|
|
479
|
+
*/
|
|
480
|
+
validateEnvironment(): Promise<EnvironmentValidation>;
|
|
481
|
+
/**
|
|
482
|
+
* Copies the @gitgov agent prompt to project root for IDE access.
|
|
483
|
+
*/
|
|
484
|
+
copyAgentPrompt(): Promise<void>;
|
|
485
|
+
/**
|
|
486
|
+
* Sets up .gitignore for GitGovernance files.
|
|
487
|
+
*/
|
|
488
|
+
setupGitIntegration(): Promise<void>;
|
|
489
|
+
/**
|
|
490
|
+
* Removes .gitgov/ directory (for rollback on failed init).
|
|
491
|
+
*/
|
|
492
|
+
rollback(): Promise<void>;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* LocalGitModule - Local Git Operations via CLI
|
|
497
|
+
*
|
|
498
|
+
* This module provides a business-agnostic abstraction layer for interacting
|
|
499
|
+
* with the local Git repository. It exposes semantic methods instead of raw
|
|
500
|
+
* Git commands, with comprehensive error handling and type safety.
|
|
501
|
+
*
|
|
502
|
+
* Uses execCommand (injected) to run git CLI commands.
|
|
503
|
+
*
|
|
504
|
+
* @module git/local
|
|
505
|
+
*/
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* LocalGitModule - CLI-based implementation of IGitModule
|
|
509
|
+
*
|
|
510
|
+
* All operations are async and use dependency injection for testability.
|
|
511
|
+
* Errors are transformed into typed exceptions for better handling.
|
|
512
|
+
*
|
|
513
|
+
* For unit tests without git, use MemoryGitModule instead.
|
|
514
|
+
*/
|
|
515
|
+
declare class LocalGitModule implements IGitModule {
|
|
516
|
+
private repoRoot;
|
|
517
|
+
private execCommand;
|
|
518
|
+
/**
|
|
519
|
+
* Creates a new LocalGitModule instance
|
|
520
|
+
*
|
|
521
|
+
* @param dependencies - Required dependencies (execCommand) and optional config (repoRoot)
|
|
522
|
+
* @throws Error if execCommand is not provided
|
|
523
|
+
*/
|
|
524
|
+
constructor(dependencies: GitModuleDependencies);
|
|
525
|
+
/**
|
|
526
|
+
* Ensures that repoRoot is set, auto-detecting it if necessary
|
|
527
|
+
*
|
|
528
|
+
* @returns Path to repository root
|
|
529
|
+
* @throws GitCommandError if not in a Git repository
|
|
530
|
+
*/
|
|
531
|
+
private ensureRepoRoot;
|
|
532
|
+
/**
|
|
533
|
+
* Executes a Git command with standardized error handling
|
|
534
|
+
*
|
|
535
|
+
* @param args - Git command arguments
|
|
536
|
+
* @param options - Execution options
|
|
537
|
+
* @returns Command result
|
|
538
|
+
* @throws GitCommandError if command fails
|
|
539
|
+
*/
|
|
540
|
+
private execGit;
|
|
541
|
+
/**
|
|
542
|
+
* Executes an arbitrary shell command with the repository as working directory.
|
|
543
|
+
*
|
|
544
|
+
* This method is intended for advanced use cases where the existing
|
|
545
|
+
* semantic methods don't cover the needed functionality. Use with caution.
|
|
546
|
+
*
|
|
547
|
+
* @param command - The command to execute (e.g., 'git')
|
|
548
|
+
* @param args - Command arguments
|
|
549
|
+
* @param options - Optional execution options
|
|
550
|
+
* @returns Command execution result with exitCode, stdout, stderr
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* const result = await gitModule.exec('git', ['diff', '--name-only', 'HEAD~1..HEAD']);
|
|
554
|
+
* if (result.exitCode === 0) {
|
|
555
|
+
* const files = result.stdout.split('\n');
|
|
556
|
+
* }
|
|
557
|
+
*/
|
|
558
|
+
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
559
|
+
/**
|
|
560
|
+
* Initializes a new Git repository in the current directory
|
|
561
|
+
*
|
|
562
|
+
* Creates the `.git/` directory structure and sets up initial configuration.
|
|
563
|
+
* Useful for testing and for commands that require a fresh repository.
|
|
564
|
+
*
|
|
565
|
+
* @throws GitCommandError if directory is already a Git repository
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* await gitModule.init();
|
|
569
|
+
* // Repository initialized with default branch (main or master)
|
|
570
|
+
*/
|
|
571
|
+
init(): Promise<void>;
|
|
572
|
+
/**
|
|
573
|
+
* Returns the absolute path to the current Git repository root
|
|
574
|
+
*
|
|
575
|
+
* @returns Repository root path
|
|
576
|
+
* @throws GitCommandError if not in a Git repository
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* const repoRoot = await gitModule.getRepoRoot();
|
|
580
|
+
* // => "/home/user/my-project"
|
|
581
|
+
*/
|
|
582
|
+
getRepoRoot(): Promise<string>;
|
|
583
|
+
/**
|
|
584
|
+
* Returns the name of the current branch (HEAD)
|
|
585
|
+
*
|
|
586
|
+
* @returns Current branch name
|
|
587
|
+
* @throws GitCommandError if in detached HEAD state or other error
|
|
588
|
+
*
|
|
589
|
+
* @example
|
|
590
|
+
* const branch = await gitModule.getCurrentBranch();
|
|
591
|
+
* // => "main"
|
|
592
|
+
*/
|
|
593
|
+
getCurrentBranch(): Promise<string>;
|
|
594
|
+
/**
|
|
595
|
+
* Get commit hash for a given reference (branch, tag, HEAD, etc.)
|
|
596
|
+
*
|
|
597
|
+
* Used by test helpers and sync operations to get commit SHAs.
|
|
598
|
+
* Returns the full 40-character SHA-1 hash of the commit.
|
|
599
|
+
*
|
|
600
|
+
* @param ref Git reference (default: "HEAD"). Can be:
|
|
601
|
+
* - "HEAD" for current commit
|
|
602
|
+
* - Branch name (e.g., "main", "gitgov-state")
|
|
603
|
+
* - Tag name (e.g., "v1.0.0")
|
|
604
|
+
* - Commit hash (returns the same hash)
|
|
605
|
+
* - Relative refs (e.g., "HEAD~1", "main^")
|
|
606
|
+
* @returns Commit SHA hash (full 40-character hash)
|
|
607
|
+
* @throws GitCommandError if ref does not exist
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* const headHash = await git.getCommitHash("HEAD");
|
|
611
|
+
* // => "a1b2c3d4e5f6..."
|
|
612
|
+
*
|
|
613
|
+
* const mainHash = await git.getCommitHash("main");
|
|
614
|
+
* // => "f6e5d4c3b2a1..."
|
|
615
|
+
*
|
|
616
|
+
* const parentHash = await git.getCommitHash("HEAD~1");
|
|
617
|
+
* // => "9876543210ab..."
|
|
618
|
+
*/
|
|
619
|
+
getCommitHash(ref?: string): Promise<string>;
|
|
620
|
+
/**
|
|
621
|
+
* Set a Git configuration value.
|
|
622
|
+
* Used for configuring repository settings like user.name, core.editor, etc.
|
|
623
|
+
*
|
|
624
|
+
* [EARS-F1, EARS-F2]
|
|
625
|
+
*
|
|
626
|
+
* @param key - Configuration key (e.g., "user.name", "core.editor")
|
|
627
|
+
* @param value - Configuration value
|
|
628
|
+
* @param scope - Configuration scope: "local" (default), "global", or "system"
|
|
629
|
+
* @throws GitCommandError if configuration fails
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```typescript
|
|
633
|
+
* // Set local config (repository-specific)
|
|
634
|
+
* await git.setConfig('core.editor', 'vim');
|
|
635
|
+
*
|
|
636
|
+
* // Set global config (user-wide)
|
|
637
|
+
* await git.setConfig('user.name', 'John Doe', 'global');
|
|
638
|
+
*
|
|
639
|
+
* // Set system config (machine-wide, requires permissions)
|
|
640
|
+
* await git.setConfig('credential.helper', 'cache', 'system');
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
setConfig(key: string, value: string, scope?: 'local' | 'global' | 'system'): Promise<void>;
|
|
644
|
+
/**
|
|
645
|
+
* Finds the most recent common ancestor between two branches
|
|
646
|
+
*
|
|
647
|
+
* @param branchA - First branch name
|
|
648
|
+
* @param branchB - Second branch name
|
|
649
|
+
* @returns Commit hash of the merge base
|
|
650
|
+
* @throws BranchNotFoundError if either branch does not exist
|
|
651
|
+
* @throws GitCommandError if operation fails
|
|
652
|
+
*
|
|
653
|
+
* @example
|
|
654
|
+
* const mergeBase = await gitModule.getMergeBase("main", "feature");
|
|
655
|
+
* // => "a1b2c3d4e5f6..."
|
|
656
|
+
*/
|
|
657
|
+
getMergeBase(branchA: string, branchB: string): Promise<string>;
|
|
658
|
+
/**
|
|
659
|
+
* Returns a list of files changed between two commits
|
|
660
|
+
*
|
|
661
|
+
* @param fromCommit - Source commit or reference
|
|
662
|
+
* @param toCommit - Target commit or reference
|
|
663
|
+
* @param pathFilter - Optional path filter (e.g., ".gitgov/")
|
|
664
|
+
* @returns Array of changed files with their status
|
|
665
|
+
* @throws GitCommandError if operation fails
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* const changes = await gitModule.getChangedFiles("HEAD~1", "HEAD", ".gitgov/");
|
|
669
|
+
* // => [{ status: "M", file: ".gitgov/tasks/123.json" }]
|
|
670
|
+
*/
|
|
671
|
+
getChangedFiles(fromCommit: string, toCommit: string, pathFilter: string): Promise<ChangedFile[]>;
|
|
672
|
+
/**
|
|
673
|
+
* Get list of staged files (in staging area / index)
|
|
674
|
+
*
|
|
675
|
+
* Used during conflict resolution to identify which files the user resolved and staged.
|
|
676
|
+
*
|
|
677
|
+
* @returns Array of file paths that are currently staged
|
|
678
|
+
* @throws GitCommandError if operation fails
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* // After user resolves conflict and does: git add .gitgov/tasks/123.json
|
|
682
|
+
* const staged = await gitModule.getStagedFiles();
|
|
683
|
+
* // => [".gitgov/tasks/123.json"]
|
|
684
|
+
*/
|
|
685
|
+
getStagedFiles(): Promise<string[]>;
|
|
686
|
+
/**
|
|
687
|
+
* Retrieves the content of a file at a specific point in history
|
|
688
|
+
*
|
|
689
|
+
* @param commitHash - Commit hash
|
|
690
|
+
* @param filePath - File path relative to repository root
|
|
691
|
+
* @returns File content as string
|
|
692
|
+
* @throws FileNotFoundError if file doesn't exist in that commit
|
|
693
|
+
* @throws GitCommandError if operation fails
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* const content = await gitModule.getFileContent("abc123", ".gitgov/config.json");
|
|
697
|
+
* // => '{"version": "1.0.0"}'
|
|
698
|
+
*/
|
|
699
|
+
getFileContent(commitHash: string, filePath: string): Promise<string>;
|
|
700
|
+
/**
|
|
701
|
+
* Retrieves the commit history for a branch
|
|
702
|
+
*
|
|
703
|
+
* @param branch - Branch name
|
|
704
|
+
* @param options - Filtering and formatting options
|
|
705
|
+
* @returns Array of commits ordered from newest to oldest
|
|
706
|
+
* @throws GitCommandError if operation fails
|
|
707
|
+
*
|
|
708
|
+
* @example
|
|
709
|
+
* const history = await gitModule.getCommitHistory("main", { maxCount: 10 });
|
|
710
|
+
* // => [{ hash: "abc123", message: "Initial commit", author: "User <email>", date: "2025-01-01T00:00:00Z" }]
|
|
711
|
+
*/
|
|
712
|
+
getCommitHistory(branch: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
|
|
713
|
+
/**
|
|
714
|
+
* Retrieves commit history in a specific range
|
|
715
|
+
*
|
|
716
|
+
* @param fromHash - Starting commit hash (exclusive)
|
|
717
|
+
* @param toHash - Ending commit hash (inclusive)
|
|
718
|
+
* @param options - Filtering and formatting options
|
|
719
|
+
* @returns Array of commits in the specified range
|
|
720
|
+
* @throws GitCommandError if either commit doesn't exist
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* const commits = await gitModule.getCommitHistoryRange("abc123", "def456");
|
|
724
|
+
* // => [{ hash: "def456", ... }, { hash: "cba321", ... }]
|
|
725
|
+
*/
|
|
726
|
+
getCommitHistoryRange(fromHash: string, toHash: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
|
|
727
|
+
/**
|
|
728
|
+
* Retrieves the full commit message for a specific commit
|
|
729
|
+
*
|
|
730
|
+
* @param commitHash - Commit hash
|
|
731
|
+
* @returns Full commit message as string
|
|
732
|
+
* @throws GitCommandError if commit doesn't exist
|
|
733
|
+
*
|
|
734
|
+
* @example
|
|
735
|
+
* const message = await gitModule.getCommitMessage("abc123");
|
|
736
|
+
* // => "feat: add new feature\n\nDetailed description..."
|
|
737
|
+
*/
|
|
738
|
+
getCommitMessage(commitHash: string): Promise<string>;
|
|
739
|
+
/**
|
|
740
|
+
* Checks if there are uncommitted changes in the working directory
|
|
741
|
+
*
|
|
742
|
+
* @param pathFilter - Optional path filter (e.g., ".gitgov/")
|
|
743
|
+
* @returns true if there are uncommitted changes, false otherwise
|
|
744
|
+
* @throws GitCommandError if operation fails
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* const hasChanges = await gitModule.hasUncommittedChanges(".gitgov/");
|
|
748
|
+
* // => true
|
|
749
|
+
*/
|
|
750
|
+
hasUncommittedChanges(pathFilter?: string): Promise<boolean>;
|
|
751
|
+
/**
|
|
752
|
+
* Checks if a rebase operation is currently in progress
|
|
753
|
+
*
|
|
754
|
+
* @returns true if rebase is in progress, false otherwise
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* const inRebase = await gitModule.isRebaseInProgress();
|
|
758
|
+
* // => false
|
|
759
|
+
*/
|
|
760
|
+
isRebaseInProgress(): Promise<boolean>;
|
|
761
|
+
/**
|
|
762
|
+
* Checks if a branch exists locally
|
|
763
|
+
*
|
|
764
|
+
* @param branchName - Branch name to check
|
|
765
|
+
* @returns true if branch exists, false otherwise
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* const exists = await gitModule.branchExists("feature-branch");
|
|
769
|
+
* // => true
|
|
770
|
+
*/
|
|
771
|
+
branchExists(branchName: string): Promise<boolean>;
|
|
772
|
+
/**
|
|
773
|
+
* Lists all remote branches for a given remote
|
|
774
|
+
*
|
|
775
|
+
* @param remoteName - Name of the remote (e.g., "origin")
|
|
776
|
+
* @returns Array of remote branch names without the remote prefix
|
|
777
|
+
* @throws GitCommandError if operation fails
|
|
778
|
+
*
|
|
779
|
+
* @example
|
|
780
|
+
* const branches = await gitModule.listRemoteBranches("origin");
|
|
781
|
+
* // => ["main", "develop", "gitgov-state"]
|
|
782
|
+
*
|
|
783
|
+
* @note This method only returns the branch names, not the full "origin/branch" format
|
|
784
|
+
*/
|
|
785
|
+
listRemoteBranches(remoteName: string): Promise<string[]>;
|
|
786
|
+
/**
|
|
787
|
+
* Checks if a remote is configured in the git repository.
|
|
788
|
+
*
|
|
789
|
+
* @param remoteName - Name of the remote to check (e.g., "origin")
|
|
790
|
+
* @returns true if the remote is configured, false otherwise
|
|
791
|
+
*
|
|
792
|
+
* @example
|
|
793
|
+
* const hasOrigin = await gitModule.isRemoteConfigured("origin");
|
|
794
|
+
* // => true
|
|
795
|
+
*/
|
|
796
|
+
isRemoteConfigured(remoteName: string): Promise<boolean>;
|
|
797
|
+
/**
|
|
798
|
+
* Retrieves the tracking remote for a branch
|
|
799
|
+
*
|
|
800
|
+
* @param branchName - Branch name
|
|
801
|
+
* @returns Remote name or null if not configured
|
|
802
|
+
* @throws BranchNotFoundError if branch doesn't exist
|
|
803
|
+
*
|
|
804
|
+
* @example
|
|
805
|
+
* const remote = await gitModule.getBranchRemote("main");
|
|
806
|
+
* // => "origin"
|
|
807
|
+
*/
|
|
808
|
+
getBranchRemote(branchName: string): Promise<string | null>;
|
|
809
|
+
/**
|
|
810
|
+
* Retrieves the list of conflicted files during a rebase or merge
|
|
811
|
+
*
|
|
812
|
+
* @returns Array of file paths in conflict
|
|
813
|
+
* @throws GitCommandError if no rebase/merge in progress
|
|
814
|
+
*
|
|
815
|
+
* @example
|
|
816
|
+
* const conflicts = await gitModule.getConflictedFiles();
|
|
817
|
+
* // => [".gitgov/tasks/123.json", ".gitgov/tasks/456.json"]
|
|
818
|
+
*/
|
|
819
|
+
getConflictedFiles(): Promise<string[]>;
|
|
820
|
+
/**
|
|
821
|
+
* Switches to the specified branch
|
|
822
|
+
*
|
|
823
|
+
* @param branchName - Branch name to checkout
|
|
824
|
+
* @throws BranchNotFoundError if branch doesn't exist
|
|
825
|
+
* @throws GitCommandError if operation fails
|
|
826
|
+
*
|
|
827
|
+
* @example
|
|
828
|
+
* await gitModule.checkoutBranch("feature-branch");
|
|
829
|
+
*/
|
|
830
|
+
checkoutBranch(branchName: string): Promise<void>;
|
|
831
|
+
/**
|
|
832
|
+
* Stash uncommitted changes
|
|
833
|
+
*
|
|
834
|
+
* @param message - Optional message for the stash
|
|
835
|
+
* @returns Stash hash if changes were stashed, null if nothing to stash
|
|
836
|
+
*/
|
|
837
|
+
stash(message?: string): Promise<string | null>;
|
|
838
|
+
/**
|
|
839
|
+
* Pop the most recent stash
|
|
840
|
+
*
|
|
841
|
+
* @returns true if stash was popped successfully, false if no stash exists
|
|
842
|
+
*/
|
|
843
|
+
stashPop(): Promise<boolean>;
|
|
844
|
+
/**
|
|
845
|
+
* Drop a specific stash or the most recent one
|
|
846
|
+
*
|
|
847
|
+
* @param stashHash - Optional stash hash to drop, defaults to most recent
|
|
848
|
+
*/
|
|
849
|
+
stashDrop(stashHash?: string): Promise<void>;
|
|
850
|
+
/**
|
|
851
|
+
* Creates an orphan branch (no history) and switches to it
|
|
852
|
+
*
|
|
853
|
+
* @param branchName - Orphan branch name to create
|
|
854
|
+
* @throws GitCommandError if branch already exists or operation fails
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* await gitModule.checkoutOrphanBranch("gitgov-state");
|
|
858
|
+
*/
|
|
859
|
+
checkoutOrphanBranch(branchName: string): Promise<void>;
|
|
860
|
+
/**
|
|
861
|
+
* Fetches the latest changes from a remote repository
|
|
862
|
+
*
|
|
863
|
+
* @param remote - Remote name (e.g., "origin")
|
|
864
|
+
* @throws GitCommandError if operation fails
|
|
865
|
+
*
|
|
866
|
+
* @example
|
|
867
|
+
* await gitModule.fetch("origin");
|
|
868
|
+
*/
|
|
869
|
+
fetch(remote: string): Promise<void>;
|
|
870
|
+
/**
|
|
871
|
+
* Pulls and merges a remote branch
|
|
872
|
+
*
|
|
873
|
+
* @param remote - Remote name
|
|
874
|
+
* @param branchName - Branch name
|
|
875
|
+
* @throws MergeConflictError if merge conflicts occur
|
|
876
|
+
* @throws GitCommandError if operation fails
|
|
877
|
+
*
|
|
878
|
+
* @example
|
|
879
|
+
* await gitModule.pull("origin", "main");
|
|
880
|
+
*/
|
|
881
|
+
pull(remote: string, branchName: string): Promise<void>;
|
|
882
|
+
/**
|
|
883
|
+
* Pulls and rebases a remote branch
|
|
884
|
+
*
|
|
885
|
+
* @param remote - Remote name
|
|
886
|
+
* @param branchName - Branch name
|
|
887
|
+
* @throws RebaseConflictError if rebase conflicts occur
|
|
888
|
+
* @throws GitCommandError if operation fails
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* await gitModule.pullRebase("origin", "main");
|
|
892
|
+
*/
|
|
893
|
+
pullRebase(remote: string, branchName: string): Promise<void>;
|
|
894
|
+
/**
|
|
895
|
+
* Resets the current branch to a specific commit, discarding all local changes
|
|
896
|
+
*
|
|
897
|
+
* @param target - Commit hash or branch name
|
|
898
|
+
* @throws GitCommandError if operation fails
|
|
899
|
+
*
|
|
900
|
+
* @example
|
|
901
|
+
* await gitModule.resetHard("HEAD~1");
|
|
902
|
+
*/
|
|
903
|
+
resetHard(target: string): Promise<void>;
|
|
904
|
+
/**
|
|
905
|
+
* Checks out specific files from another branch into the current staging area
|
|
906
|
+
*
|
|
907
|
+
* @param sourceBranch - Source branch name
|
|
908
|
+
* @param filePaths - Array of file paths to checkout
|
|
909
|
+
* @throws BranchNotFoundError if source branch doesn't exist
|
|
910
|
+
* @throws GitCommandError if operation fails
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* await gitModule.checkoutFilesFromBranch("main", [".gitgov/tasks/123.json"]);
|
|
914
|
+
*/
|
|
915
|
+
checkoutFilesFromBranch(sourceBranch: string, filePaths: string[]): Promise<void>;
|
|
916
|
+
/**
|
|
917
|
+
* Adds files to the staging area
|
|
918
|
+
*
|
|
919
|
+
* @param filePaths - Array of file paths to add
|
|
920
|
+
* @param options - Optional settings (force: add ignored files)
|
|
921
|
+
* @throws GitCommandError if operation fails
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* await gitModule.add([".gitgov/tasks/123.json"]);
|
|
925
|
+
* await gitModule.add([".gitgov"], { force: true }); // Add ignored files
|
|
926
|
+
*/
|
|
927
|
+
add(filePaths: string[], options?: {
|
|
928
|
+
force?: boolean;
|
|
929
|
+
}): Promise<void>;
|
|
930
|
+
/**
|
|
931
|
+
* Removes files from both working directory and staging area
|
|
932
|
+
*
|
|
933
|
+
* @param filePaths - Array of file paths to remove
|
|
934
|
+
* @throws GitCommandError if operation fails
|
|
935
|
+
*
|
|
936
|
+
* @example
|
|
937
|
+
* await gitModule.rm([".gitgov/tasks/123.json"]);
|
|
938
|
+
*/
|
|
939
|
+
rm(filePaths: string[]): Promise<void>;
|
|
940
|
+
/**
|
|
941
|
+
* Creates a new commit with staged files
|
|
942
|
+
*
|
|
943
|
+
* @param message - Commit message
|
|
944
|
+
* @param author - Optional commit author
|
|
945
|
+
* @returns Commit hash of the created commit
|
|
946
|
+
* @throws GitCommandError if operation fails
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* const hash = await gitModule.commit("feat: add new task");
|
|
950
|
+
* // => "abc123def456..."
|
|
951
|
+
*/
|
|
952
|
+
commit(message: string, author?: CommitAuthor): Promise<string>;
|
|
953
|
+
/**
|
|
954
|
+
* Creates an empty commit (no changes required)
|
|
955
|
+
*
|
|
956
|
+
* @param message - Commit message
|
|
957
|
+
* @param author - Optional commit author
|
|
958
|
+
* @returns Commit hash of the created commit
|
|
959
|
+
* @throws GitCommandError if operation fails
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* const hash = await gitModule.commitAllowEmpty("chore: initialize state branch");
|
|
963
|
+
* // => "abc123def456..."
|
|
964
|
+
*/
|
|
965
|
+
commitAllowEmpty(message: string, author?: CommitAuthor): Promise<string>;
|
|
966
|
+
/**
|
|
967
|
+
* Pushes a local branch to a remote repository
|
|
968
|
+
*
|
|
969
|
+
* @param remote - Remote name
|
|
970
|
+
* @param branchName - Branch name
|
|
971
|
+
* @throws GitCommandError if operation fails
|
|
972
|
+
*
|
|
973
|
+
* @example
|
|
974
|
+
* await gitModule.push("origin", "main");
|
|
975
|
+
*/
|
|
976
|
+
push(remote: string, branchName: string): Promise<void>;
|
|
977
|
+
/**
|
|
978
|
+
* Pushes a local branch to a remote repository and sets up tracking
|
|
979
|
+
*
|
|
980
|
+
* @param remote - Remote name
|
|
981
|
+
* @param branchName - Branch name
|
|
982
|
+
* @throws GitCommandError if operation fails
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* await gitModule.pushWithUpstream("origin", "feature-branch");
|
|
986
|
+
*/
|
|
987
|
+
pushWithUpstream(remote: string, branchName: string): Promise<void>;
|
|
988
|
+
/**
|
|
989
|
+
* Configures tracking for a local branch with a remote branch
|
|
990
|
+
*
|
|
991
|
+
* @param branchName - Local branch name
|
|
992
|
+
* @param remote - Remote name
|
|
993
|
+
* @param remoteBranch - Remote branch name
|
|
994
|
+
* @throws BranchNotFoundError if local branch doesn't exist
|
|
995
|
+
* @throws GitCommandError if operation fails
|
|
996
|
+
*
|
|
997
|
+
* @example
|
|
998
|
+
* await gitModule.setUpstream("feature-branch", "origin", "feature-branch");
|
|
999
|
+
*/
|
|
1000
|
+
setUpstream(branchName: string, remote: string, remoteBranch: string): Promise<void>;
|
|
1001
|
+
/**
|
|
1002
|
+
* Continues a rebase after resolving conflicts
|
|
1003
|
+
*
|
|
1004
|
+
* @returns Commit hash of the rebased commit
|
|
1005
|
+
* @throws RebaseNotInProgressError if no rebase is in progress
|
|
1006
|
+
* @throws GitCommandError if operation fails
|
|
1007
|
+
*
|
|
1008
|
+
* @example
|
|
1009
|
+
* const hash = await gitModule.rebaseContinue();
|
|
1010
|
+
* // => "abc123def456..."
|
|
1011
|
+
*/
|
|
1012
|
+
rebaseContinue(): Promise<string>;
|
|
1013
|
+
/**
|
|
1014
|
+
* Aborts an ongoing rebase
|
|
1015
|
+
*
|
|
1016
|
+
* @throws RebaseNotInProgressError if no rebase is in progress
|
|
1017
|
+
* @throws GitCommandError if operation fails
|
|
1018
|
+
*
|
|
1019
|
+
* @example
|
|
1020
|
+
* await gitModule.rebaseAbort();
|
|
1021
|
+
*/
|
|
1022
|
+
rebaseAbort(): Promise<void>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Creates a new branch and switches to it (git checkout -b)
|
|
1025
|
+
*
|
|
1026
|
+
* @param branchName - Name of the branch to create
|
|
1027
|
+
* @param startPoint - Optional starting point (commit hash or branch name)
|
|
1028
|
+
* @throws GitCommandError if branch already exists or operation fails
|
|
1029
|
+
* @throws BranchAlreadyExistsError if the branch already exists locally
|
|
1030
|
+
*/
|
|
1031
|
+
createBranch(branchName: string, startPoint?: string): Promise<void>;
|
|
1032
|
+
/**
|
|
1033
|
+
* Rebases current branch onto target branch (git rebase)
|
|
1034
|
+
*
|
|
1035
|
+
* @param targetBranch - Branch to rebase onto
|
|
1036
|
+
* @throws GitCommandError if rebase fails
|
|
1037
|
+
* @throws RebaseConflictError if conflicts are detected during rebase
|
|
1038
|
+
*/
|
|
1039
|
+
rebase(targetBranch: string): Promise<void>;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Project Discovery Utilities
|
|
1044
|
+
*
|
|
1045
|
+
* Filesystem-based utilities for discovering GitGovernance project roots.
|
|
1046
|
+
* Used at CLI bootstrap to resolve projectRoot before injecting it via DI.
|
|
1047
|
+
*
|
|
1048
|
+
* NOTE: These functions should only be called at the CLI/bootstrap level.
|
|
1049
|
+
* Core modules receive projectRoot via constructor injection.
|
|
1050
|
+
*/
|
|
1051
|
+
/**
|
|
1052
|
+
* Finds the project root by searching upwards for a .git directory.
|
|
1053
|
+
* Caches the result for subsequent calls.
|
|
1054
|
+
*
|
|
1055
|
+
* @param startPath - Starting path (default: process.cwd())
|
|
1056
|
+
* @returns Path to project root, or null if not found
|
|
1057
|
+
*/
|
|
1058
|
+
declare function findProjectRoot(startPath?: string): string | null;
|
|
1059
|
+
/**
|
|
1060
|
+
* Finds the project root by searching upwards.
|
|
1061
|
+
* First looks for .gitgov (initialized project), then .git (for init).
|
|
1062
|
+
*
|
|
1063
|
+
* @param startPath - Starting path (default: process.cwd())
|
|
1064
|
+
* @returns Path to project root, or null if not found
|
|
1065
|
+
*/
|
|
1066
|
+
declare function findGitgovRoot(startPath?: string): string | null;
|
|
1067
|
+
/**
|
|
1068
|
+
* Gets the .gitgov directory path from project root.
|
|
1069
|
+
*
|
|
1070
|
+
* @throws Error if not inside a GitGovernance project
|
|
1071
|
+
*/
|
|
1072
|
+
declare function getGitgovPath(): string;
|
|
1073
|
+
/**
|
|
1074
|
+
* Checks if current directory is inside a GitGovernance project.
|
|
1075
|
+
*/
|
|
1076
|
+
declare function isGitgovProject(): boolean;
|
|
1077
|
+
/**
|
|
1078
|
+
* Reset the project root cache.
|
|
1079
|
+
* Useful for testing when switching between project contexts.
|
|
1080
|
+
*/
|
|
1081
|
+
declare function resetDiscoveryCache(): void;
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* FsSyncStateModule - Manages state synchronization between local environment and gitgov-state branch
|
|
1085
|
+
*
|
|
1086
|
+
* Responsibilities:
|
|
1087
|
+
* - Create and maintain the gitgov-state branch (local and remote)
|
|
1088
|
+
* - Publish local changes (pushState)
|
|
1089
|
+
* - Pull remote changes (pullState)
|
|
1090
|
+
* - Resolve conflicts in a governed manner (resolveConflict)
|
|
1091
|
+
* - Audit state integrity (auditState)
|
|
1092
|
+
*
|
|
1093
|
+
* Philosophy:
|
|
1094
|
+
* - Pipeline Pattern: Sequential operations with validation at each phase
|
|
1095
|
+
* - Fail-Fast: Early verifications to avoid costly operations
|
|
1096
|
+
* - Strict Dependencies: All dependencies (git, config, identity, lint, indexer) are required for robust operations
|
|
1097
|
+
*/
|
|
1098
|
+
declare class FsSyncStateModule implements ISyncStateModule {
|
|
1099
|
+
private git;
|
|
1100
|
+
private config;
|
|
1101
|
+
private identity;
|
|
1102
|
+
private lint;
|
|
1103
|
+
private indexer;
|
|
1104
|
+
/**
|
|
1105
|
+
* Constructor with dependency injection
|
|
1106
|
+
*/
|
|
1107
|
+
constructor(dependencies: SyncStateModuleDependencies);
|
|
1108
|
+
/**
|
|
1109
|
+
* Static method to bootstrap .gitgov/ from gitgov-state branch.
|
|
1110
|
+
* Used when cloning a repo that has gitgov-state but .gitgov/ is not in the work branch.
|
|
1111
|
+
*
|
|
1112
|
+
* This method only requires GitModule and can be called before full SyncStateModule initialization.
|
|
1113
|
+
*
|
|
1114
|
+
* @param gitModule - GitModule instance for git operations
|
|
1115
|
+
* @param stateBranch - Name of the state branch (default: "gitgov-state")
|
|
1116
|
+
* @returns Promise<{ success: boolean; error?: string }>
|
|
1117
|
+
*/
|
|
1118
|
+
static bootstrapFromStateBranch(gitModule: IGitModule, stateBranch?: string): Promise<{
|
|
1119
|
+
success: boolean;
|
|
1120
|
+
error?: string;
|
|
1121
|
+
}>;
|
|
1122
|
+
/**
|
|
1123
|
+
* Gets the state branch name from configuration.
|
|
1124
|
+
* Default: "gitgov-state"
|
|
1125
|
+
*
|
|
1126
|
+
* [EARS-A4]
|
|
1127
|
+
*/
|
|
1128
|
+
getStateBranchName(): Promise<string>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Ensures that the gitgov-state branch exists both locally and remotely.
|
|
1131
|
+
* If it doesn't exist, creates it as an orphan branch.
|
|
1132
|
+
*
|
|
1133
|
+
* Use cases (4 edge cases):
|
|
1134
|
+
* 1. Doesn't exist locally or remotely → Create orphan branch + initial commit + push
|
|
1135
|
+
* 2. Exists remotely, not locally → Fetch + create local + set tracking
|
|
1136
|
+
* 3. Exists locally, not remotely → Push + set tracking
|
|
1137
|
+
* 4. Exists both → Verify tracking
|
|
1138
|
+
*
|
|
1139
|
+
* [EARS-A1, EARS-A2, EARS-A3]
|
|
1140
|
+
*/
|
|
1141
|
+
ensureStateBranch(): Promise<void>;
|
|
1142
|
+
/**
|
|
1143
|
+
* Creates the gitgov-state orphan branch with an empty initial commit.
|
|
1144
|
+
* Used by ensureStateBranch when the branch doesn't exist locally or remotely.
|
|
1145
|
+
*
|
|
1146
|
+
* [EARS-A1]
|
|
1147
|
+
*/
|
|
1148
|
+
private createOrphanStateBranch;
|
|
1149
|
+
/**
|
|
1150
|
+
* Calculates the file delta in .gitgov/ between the current branch and gitgov-state.
|
|
1151
|
+
*
|
|
1152
|
+
* [EARS-A5]
|
|
1153
|
+
*/
|
|
1154
|
+
calculateStateDelta(sourceBranch: string): Promise<StateDeltaFile[]>;
|
|
1155
|
+
/**
|
|
1156
|
+
* [EARS-B23] Detect file-level conflicts and identify remote-only changes.
|
|
1157
|
+
*
|
|
1158
|
+
* A conflict exists when:
|
|
1159
|
+
* 1. A file was modified by the remote during implicit pull
|
|
1160
|
+
* 2. AND the LOCAL USER also modified that same file (content in tempDir differs from what was in git before pull)
|
|
1161
|
+
*
|
|
1162
|
+
* This catches conflicts that git rebase can't detect because we copy files AFTER the pull.
|
|
1163
|
+
*
|
|
1164
|
+
* @param tempDir - Directory containing local .gitgov/ files (preserved before checkout)
|
|
1165
|
+
* @param repoRoot - Repository root path
|
|
1166
|
+
/**
|
|
1167
|
+
* Checks if a rebase is in progress.
|
|
1168
|
+
*
|
|
1169
|
+
* [EARS-D6]
|
|
1170
|
+
*/
|
|
1171
|
+
isRebaseInProgress(): Promise<boolean>;
|
|
1172
|
+
/**
|
|
1173
|
+
* Checks for absence of conflict markers in specified files.
|
|
1174
|
+
* Returns list of files that still have markers.
|
|
1175
|
+
*
|
|
1176
|
+
* [EARS-D7]
|
|
1177
|
+
*/
|
|
1178
|
+
checkConflictMarkers(filePaths: string[]): Promise<string[]>;
|
|
1179
|
+
/**
|
|
1180
|
+
* Gets the diff of conflicted files for manual analysis.
|
|
1181
|
+
* Useful so the actor can analyze conflicted changes before resolving.
|
|
1182
|
+
*
|
|
1183
|
+
* [EARS-E8]
|
|
1184
|
+
*/
|
|
1185
|
+
getConflictDiff(filePaths?: string[]): Promise<ConflictDiff>;
|
|
1186
|
+
/**
|
|
1187
|
+
* Verifies integrity of previous resolutions in gitgov-state history.
|
|
1188
|
+
* Returns list of violations if any exist.
|
|
1189
|
+
*
|
|
1190
|
+
* [EARS-E1, EARS-E2, EARS-E3]
|
|
1191
|
+
*/
|
|
1192
|
+
verifyResolutionIntegrity(): Promise<IntegrityViolation[]>;
|
|
1193
|
+
/**
|
|
1194
|
+
* Complete audit of gitgov-state status.
|
|
1195
|
+
* Verifies integrity of resolutions, signatures in Records, checksums and expected files.
|
|
1196
|
+
*
|
|
1197
|
+
* [EARS-E4, EARS-E5, EARS-E6, EARS-E7]
|
|
1198
|
+
*/
|
|
1199
|
+
auditState(options?: AuditStateOptions): Promise<AuditStateReport>;
|
|
1200
|
+
/**
|
|
1201
|
+
* Publishes local state changes to gitgov-state.
|
|
1202
|
+
* Implements 3 phases: verification, reconciliation, publication.
|
|
1203
|
+
*
|
|
1204
|
+
* [EARS-B1 through EARS-B7]
|
|
1205
|
+
*/
|
|
1206
|
+
pushState(options: SyncStatePushOptions): Promise<SyncStatePushResult>;
|
|
1207
|
+
/**
|
|
1208
|
+
* Pulls remote changes from gitgov-state to the local environment.
|
|
1209
|
+
* Includes automatic re-indexing if there are new changes.
|
|
1210
|
+
*
|
|
1211
|
+
* [EARS-C1 through EARS-C4]
|
|
1212
|
+
* [EARS-C5] Requires remote to be configured (pull without remote makes no sense)
|
|
1213
|
+
*/
|
|
1214
|
+
pullState(options?: SyncStatePullOptions): Promise<SyncStatePullResult>;
|
|
1215
|
+
/**
|
|
1216
|
+
* Resolves state conflicts in a governed manner (Git-Native).
|
|
1217
|
+
*
|
|
1218
|
+
* Git-Native Flow:
|
|
1219
|
+
* 1. User resolves conflicts using standard Git tools (edit files, remove markers)
|
|
1220
|
+
* 2. User stages resolved files: git add .gitgov/
|
|
1221
|
+
* 3. User runs: gitgov sync resolve --reason "reason"
|
|
1222
|
+
*
|
|
1223
|
+
* This method:
|
|
1224
|
+
* - Verifies that a rebase is in progress
|
|
1225
|
+
* - Checks that no conflict markers remain in staged files
|
|
1226
|
+
* - Updates resolved Records with new checksums and signatures
|
|
1227
|
+
* - Continues the git rebase (git rebase --continue)
|
|
1228
|
+
* - Creates a signed resolution commit
|
|
1229
|
+
* - Regenerates the index
|
|
1230
|
+
*
|
|
1231
|
+
* [EARS-D1 through EARS-D7]
|
|
1232
|
+
*/
|
|
1233
|
+
resolveConflict(options: SyncStateResolveOptions): Promise<SyncStateResolveResult>;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
interface WatcherStateModuleOptions {
|
|
1237
|
+
gitgovPath: string;
|
|
1238
|
+
debounceMs?: number;
|
|
1239
|
+
}
|
|
1240
|
+
interface WatcherStateModuleDependencies {
|
|
1241
|
+
eventBus: IEventStream;
|
|
1242
|
+
options: WatcherStateModuleOptions;
|
|
1243
|
+
}
|
|
1244
|
+
interface WatcherStateStatus {
|
|
1245
|
+
isRunning: boolean;
|
|
1246
|
+
watchedDirectories: string[];
|
|
1247
|
+
eventsEmitted: number;
|
|
1248
|
+
lastError: Error | undefined;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/**
|
|
1252
|
+
* IWatcherStateModule - State Watcher Interface
|
|
1253
|
+
*
|
|
1254
|
+
* Defines the contract for watching .gitgov/ changes and emitting events.
|
|
1255
|
+
* Unidirectional: read-only observation, never writes back.
|
|
1256
|
+
*
|
|
1257
|
+
* Implementations:
|
|
1258
|
+
* - FsWatcherStateModule: Uses chokidar fs watcher (watcher_state/fs/)
|
|
1259
|
+
* - Future: CloudWatcherStateModule via realtime subscription
|
|
1260
|
+
*
|
|
1261
|
+
* @module watcher_state
|
|
1262
|
+
*/
|
|
1263
|
+
|
|
1264
|
+
interface IWatcherStateModule {
|
|
1265
|
+
/** Start watching .gitgov/ directories for changes */
|
|
1266
|
+
start(): Promise<void>;
|
|
1267
|
+
/** Stop watching and release all resources */
|
|
1268
|
+
stop(): Promise<void>;
|
|
1269
|
+
/** Whether the watcher is currently active */
|
|
1270
|
+
isRunning(): boolean;
|
|
1271
|
+
/** Current status snapshot */
|
|
1272
|
+
getStatus(): WatcherStateStatus;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/**
|
|
1276
|
+
* FsWatcherStateModule — Filesystem watcher for .gitgov/ changes
|
|
1277
|
+
*
|
|
1278
|
+
* Watches .gitgov/ subdirectories using chokidar and emits events
|
|
1279
|
+
* to the EventBus after debounce + checksum validation.
|
|
1280
|
+
*/
|
|
1281
|
+
|
|
1282
|
+
declare class FsWatcherStateModule implements IWatcherStateModule {
|
|
1283
|
+
private eventBus;
|
|
1284
|
+
private gitgovPath;
|
|
1285
|
+
private debounceMs;
|
|
1286
|
+
private logger;
|
|
1287
|
+
private watchers;
|
|
1288
|
+
private watchedDirectories;
|
|
1289
|
+
private running;
|
|
1290
|
+
private debounceTimers;
|
|
1291
|
+
private checksums;
|
|
1292
|
+
private eventsEmitted;
|
|
1293
|
+
private lastError?;
|
|
1294
|
+
constructor(deps: WatcherStateModuleDependencies);
|
|
1295
|
+
/**
|
|
1296
|
+
* EARS-1: Creates watchers for existing directories in .gitgov/
|
|
1297
|
+
* EARS-2: Throws ProjectNotInitializedError if .gitgov/ doesn't exist
|
|
1298
|
+
*/
|
|
1299
|
+
start(): Promise<void>;
|
|
1300
|
+
/** EARS-5: Closes watchers + cancels timers */
|
|
1301
|
+
stop(): Promise<void>;
|
|
1302
|
+
isRunning(): boolean;
|
|
1303
|
+
getStatus(): WatcherStateStatus;
|
|
1304
|
+
/**
|
|
1305
|
+
* EARS-3: Emits event after debounce
|
|
1306
|
+
* EARS-6: Debounce — N rapid changes → 1 event
|
|
1307
|
+
*/
|
|
1308
|
+
private onFileChange;
|
|
1309
|
+
/**
|
|
1310
|
+
* EARS-3: Emit event to EventBus
|
|
1311
|
+
* EARS-4: Skip event on checksum mismatch
|
|
1312
|
+
* EARS-7: Handle errors gracefully
|
|
1313
|
+
*/
|
|
1314
|
+
private processFileChange;
|
|
1315
|
+
private emitEvent;
|
|
1316
|
+
private extractRecordType;
|
|
1317
|
+
private extractRecordId;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
/**
|
|
1321
|
+
* Filesystem-based Agent Runner - Executes agents based on their engine.type.
|
|
1322
|
+
*
|
|
1323
|
+
* Responsibilities:
|
|
1324
|
+
* - Load AgentRecords from .gitgov/agents/
|
|
1325
|
+
* - Execute via appropriate backend (local, api, mcp, custom)
|
|
1326
|
+
* - Capture responses and write ExecutionRecords
|
|
1327
|
+
* - Emit events via EventBus
|
|
1328
|
+
*/
|
|
1329
|
+
declare class FsAgentRunner implements IAgentRunner {
|
|
1330
|
+
private gitgovPath;
|
|
1331
|
+
private projectRoot;
|
|
1332
|
+
private identityAdapter;
|
|
1333
|
+
private executionAdapter;
|
|
1334
|
+
private eventBus;
|
|
1335
|
+
/** Protocol handlers for CustomBackend */
|
|
1336
|
+
readonly protocolHandlers: ProtocolHandlerRegistry | undefined;
|
|
1337
|
+
private runtimeHandlers;
|
|
1338
|
+
private localBackend;
|
|
1339
|
+
private apiBackend;
|
|
1340
|
+
private mcpBackend;
|
|
1341
|
+
private customBackend;
|
|
1342
|
+
constructor(deps: AgentRunnerDependencies);
|
|
1343
|
+
/**
|
|
1344
|
+
* Executes an agent once and returns the response.
|
|
1345
|
+
* TaskRecord must exist before calling this method.
|
|
1346
|
+
*/
|
|
1347
|
+
runOnce(opts: RunOptions): Promise<AgentResponse>;
|
|
1348
|
+
/**
|
|
1349
|
+
* [EARS-A1, A2] Loads AgentRecord from .gitgov/agents/agent-{id}.json
|
|
1350
|
+
*/
|
|
1351
|
+
private loadAgent;
|
|
1352
|
+
/**
|
|
1353
|
+
* [EARS-I4] Emits event via EventBus if available.
|
|
1354
|
+
* Works silently without EventBus.
|
|
1355
|
+
*/
|
|
1356
|
+
private emitEvent;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
/**
|
|
1360
|
+
* Filesystem AgentRunner implementation
|
|
1361
|
+
*
|
|
1362
|
+
* This module provides the filesystem-based implementation of IAgentRunner:
|
|
1363
|
+
* - FsAgentRunner: Loads AgentRecords from .gitgov/agents/
|
|
1364
|
+
* - createAgentRunner(): Factory function for DI
|
|
1365
|
+
*
|
|
1366
|
+
* Note: LocalBackend is re-exported from backends/ for convenience.
|
|
1367
|
+
* Use @gitgov/core for direct backend imports.
|
|
1368
|
+
*/
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* Factory function to create a filesystem-based AgentRunner.
|
|
1372
|
+
*/
|
|
1373
|
+
declare function createAgentRunner(deps: AgentRunnerDependencies): IAgentRunner;
|
|
1374
|
+
|
|
1375
|
+
export { DEFAULT_ID_ENCODER, type FileSystem, FsAgentRunner, AgentRunnerDependencies as FsAgentRunnerDependencies, FsConfigStore, type FsFixOptions, FsLintModule, type FsLintModuleDependencies, type FsLintOptions, FsProjectInitializer, FsRecordStore, FsSessionStore, FsSyncStateModule, FsWatcherStateModule, LocalGitModule as GitModule, GitModuleDependencies, type IFsLintModule, IGitModule, LocalGitModule, createAgentRunner, createConfigManager, createSessionManager, findGitgovRoot, findProjectRoot, getGitgovPath, isGitgovProject, resetDiscoveryCache };
|