@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.
@@ -0,0 +1,807 @@
1
+ /**
2
+ * RecordStore<T> - Generic interface for record persistence
3
+ *
4
+ * Abstracts CRUD operations without assuming storage backend.
5
+ * Each implementation decides how to persist (fs, memory, db, remote).
6
+ */
7
+ interface RecordStore<T> {
8
+ /**
9
+ * Gets a record by ID
10
+ * @returns The record or null if it doesn't exist
11
+ */
12
+ get(id: string): Promise<T | null>;
13
+ /**
14
+ * Persists a record
15
+ * @param id - Unique identifier
16
+ * @param value - The record to persist
17
+ */
18
+ put(id: string, value: T): Promise<void>;
19
+ /**
20
+ * Deletes a record
21
+ * @param id - Identifier of the record to delete
22
+ */
23
+ delete(id: string): Promise<void>;
24
+ /**
25
+ * Lists all record IDs
26
+ * @returns Array of IDs
27
+ */
28
+ list(): Promise<string[]>;
29
+ /**
30
+ * Checks if a record exists
31
+ * @param id - Identifier to check
32
+ */
33
+ exists(id: string): Promise<boolean>;
34
+ }
35
+
36
+ /**
37
+ * ConfigManager Types
38
+ *
39
+ * @see packages/blueprints/03_products/protocol/10_appendices/config_file.md
40
+ */
41
+ /**
42
+ * GitGovernance Configuration
43
+ * Based on config_file.md blueprint
44
+ */
45
+ type GitGovConfig = {
46
+ protocolVersion: string;
47
+ projectId: string;
48
+ projectName: string;
49
+ rootCycle: string;
50
+ state?: {
51
+ branch?: string;
52
+ sync?: {
53
+ strategy?: "manual" | "immediate" | "batched";
54
+ maxRetries?: number;
55
+ pushIntervalSeconds?: number;
56
+ batchIntervalSeconds?: number;
57
+ };
58
+ defaults?: {
59
+ pullScheduler?: {
60
+ defaultIntervalSeconds?: number;
61
+ defaultEnabled?: boolean;
62
+ defaultContinueOnNetworkError?: boolean;
63
+ defaultStopOnConflict?: boolean;
64
+ };
65
+ fileWatcher?: {
66
+ defaultDebounceMs?: number;
67
+ defaultIgnoredPatterns?: string[];
68
+ };
69
+ };
70
+ audit?: {
71
+ lastFullAuditCommit?: string;
72
+ lastFullAuditTimestamp?: string;
73
+ lastFullAuditFindingsCount?: number;
74
+ };
75
+ };
76
+ };
77
+ /**
78
+ * Audit state stored in config.json for incremental mode
79
+ */
80
+ type AuditState = {
81
+ lastFullAuditCommit: string | null;
82
+ lastFullAuditTimestamp: string | null;
83
+ lastFullAuditFindingsCount: number | null;
84
+ };
85
+ /**
86
+ * Sync configuration from config.json
87
+ */
88
+ type SyncConfig = {
89
+ strategy: "manual" | "immediate" | "batched";
90
+ maxRetries: number;
91
+ pushIntervalSeconds: number;
92
+ batchIntervalSeconds: number;
93
+ };
94
+ /**
95
+ * Sync defaults from config.json
96
+ */
97
+ type SyncDefaults = {
98
+ pullScheduler: {
99
+ defaultIntervalSeconds: number;
100
+ defaultEnabled: boolean;
101
+ defaultContinueOnNetworkError: boolean;
102
+ defaultStopOnConflict: boolean;
103
+ };
104
+ fileWatcher: {
105
+ defaultDebounceMs: number;
106
+ defaultIgnoredPatterns: string[];
107
+ };
108
+ };
109
+ /**
110
+ * Audit state update payload
111
+ */
112
+ type AuditStateUpdate = {
113
+ lastFullAuditCommit: string;
114
+ lastFullAuditTimestamp: string;
115
+ lastFullAuditFindingsCount: number;
116
+ };
117
+ /**
118
+ * IConfigManager interface
119
+ *
120
+ * Provides typed access to GitGovernance project configuration.
121
+ * Configuration is versioned in Git and shared between collaborators.
122
+ */
123
+ interface IConfigManager {
124
+ /**
125
+ * Load GitGovernance configuration
126
+ */
127
+ loadConfig(): Promise<GitGovConfig | null>;
128
+ /**
129
+ * Get root cycle from configuration
130
+ */
131
+ getRootCycle(): Promise<string | null>;
132
+ /**
133
+ * Get project information from configuration
134
+ */
135
+ getProjectInfo(): Promise<{
136
+ id: string;
137
+ name: string;
138
+ } | null>;
139
+ /**
140
+ * Get sync configuration from config.json
141
+ * Returns sync strategy and related settings with defaults
142
+ */
143
+ getSyncConfig(): Promise<SyncConfig | null>;
144
+ /**
145
+ * Get sync defaults from config.json
146
+ * Returns recommended defaults for pullScheduler and fileWatcher
147
+ */
148
+ getSyncDefaults(): Promise<SyncDefaults>;
149
+ /**
150
+ * Get audit state from config.json
151
+ * Returns last full audit commit and timestamp for incremental mode
152
+ */
153
+ getAuditState(): Promise<AuditState>;
154
+ /**
155
+ * Update audit state in config.json after a full audit
156
+ * This is used to enable incremental audits
157
+ */
158
+ updateAuditState(auditState: AuditStateUpdate): Promise<void>;
159
+ /**
160
+ * Get state branch name from configuration
161
+ */
162
+ getStateBranch(): Promise<string>;
163
+ }
164
+
165
+ /**
166
+ * SessionManager Types
167
+ *
168
+ * @see packages/blueprints/03_products/protocol/10_appendices/session_state.md
169
+ */
170
+ /**
171
+ * Sync status for an actor's synchronization state.
172
+ */
173
+ type SyncStatus = {
174
+ lastSyncPush?: string;
175
+ lastSyncPull?: string;
176
+ status?: 'synced' | 'pending' | 'pulling' | 'pushing' | 'conflict';
177
+ lastError?: string;
178
+ };
179
+ /**
180
+ * State for a specific actor on this machine.
181
+ */
182
+ type ActorState = {
183
+ activeTaskId?: string | undefined;
184
+ activeCycleId?: string | undefined;
185
+ lastSync?: string;
186
+ syncStatus?: SyncStatus;
187
+ [key: string]: unknown;
188
+ };
189
+ /**
190
+ * GitGovernance Session State
191
+ * Based on session_state.md blueprint
192
+ */
193
+ type GitGovSession = {
194
+ cloud?: {
195
+ sessionToken?: string;
196
+ };
197
+ lastSession?: {
198
+ actorId: string;
199
+ timestamp: string;
200
+ };
201
+ actorState?: Record<string, ActorState>;
202
+ syncPreferences?: {
203
+ pullScheduler?: {
204
+ enabled?: boolean;
205
+ pullIntervalSeconds?: number;
206
+ continueOnNetworkError?: boolean;
207
+ stopOnConflict?: boolean;
208
+ };
209
+ fileWatcher?: {
210
+ enabled?: boolean;
211
+ debounceMs?: number;
212
+ ignoredPatterns?: string[];
213
+ };
214
+ };
215
+ };
216
+ /**
217
+ * Sync preferences update payload
218
+ */
219
+ type SyncPreferencesUpdate = {
220
+ pullScheduler?: Partial<{
221
+ enabled: boolean;
222
+ pullIntervalSeconds: number;
223
+ continueOnNetworkError: boolean;
224
+ stopOnConflict: boolean;
225
+ }>;
226
+ fileWatcher?: Partial<{
227
+ enabled: boolean;
228
+ debounceMs: number;
229
+ ignoredPatterns: string[];
230
+ }>;
231
+ };
232
+ /**
233
+ * ISessionManager interface
234
+ *
235
+ * Provides typed access to GitGovernance session state.
236
+ * Session state is ephemeral, machine-local, and NOT versioned in Git.
237
+ */
238
+ interface ISessionManager {
239
+ /**
240
+ * Load GitGovernance session state
241
+ * [EARS-B9] Auto-detects actor from .key files if no session or no actorId exists
242
+ */
243
+ loadSession(): Promise<GitGovSession | null>;
244
+ /**
245
+ * [EARS-B9] Detect actor from .key files in .gitgov/actors/
246
+ */
247
+ detectActorFromKeyFiles(): Promise<string | null>;
248
+ /**
249
+ * Get actor state for a specific actor
250
+ */
251
+ getActorState(actorId: string): Promise<ActorState | null>;
252
+ /**
253
+ * Update actor state for a specific actor
254
+ */
255
+ updateActorState(actorId: string, state: Partial<ActorState>): Promise<void>;
256
+ /**
257
+ * Get cloud session token
258
+ */
259
+ getCloudSessionToken(): Promise<string | null>;
260
+ /**
261
+ * Get sync preferences from session
262
+ */
263
+ getSyncPreferences(): Promise<GitGovSession['syncPreferences'] | null>;
264
+ /**
265
+ * Update sync preferences in .session.json
266
+ * These are local machine preferences that override project defaults
267
+ */
268
+ updateSyncPreferences(preferences: SyncPreferencesUpdate): Promise<void>;
269
+ /**
270
+ * Get last session info (last human who interacted)
271
+ */
272
+ getLastSession(): Promise<{
273
+ actorId: string;
274
+ timestamp: string;
275
+ } | null>;
276
+ }
277
+
278
+ /**
279
+ * SessionStore - Session persistence abstraction
280
+ *
281
+ * Interface for storing and retrieving local session state (.session.json).
282
+ * Session state is ephemeral, machine-local, and NOT versioned in Git.
283
+ *
284
+ * Implementations:
285
+ * - FsSessionStore: Filesystem-based (production)
286
+ * - MemorySessionStore: In-memory (tests, serverless)
287
+ *
288
+ * @see packages/blueprints/03_products/protocol/10_appendices/session_state.md
289
+ */
290
+
291
+ /**
292
+ * Interface for session state persistence.
293
+ *
294
+ * Session state includes:
295
+ * - Actor state (activeTaskId, activeCycleId, syncStatus)
296
+ * - Sync preferences (pullScheduler, fileWatcher settings)
297
+ * - Cloud session tokens
298
+ * - Last session information
299
+ *
300
+ * Unlike ConfigStore, SessionStore handles ephemeral, machine-local state
301
+ * that is NOT shared between collaborators.
302
+ */
303
+ interface SessionStore {
304
+ /**
305
+ * Load session state from storage.
306
+ *
307
+ * @returns GitGovSession object or null if not found
308
+ */
309
+ loadSession(): Promise<GitGovSession | null>;
310
+ /**
311
+ * Save session state to storage.
312
+ *
313
+ * @param session - The session state to persist
314
+ */
315
+ saveSession(session: GitGovSession): Promise<void>;
316
+ /**
317
+ * Detect actor from private key files.
318
+ *
319
+ * Optional method for implementations that support actor auto-detection
320
+ * from .key files in the actors directory.
321
+ *
322
+ * @returns Actor ID (e.g., "human:camilo-v2") or null if not detectable
323
+ */
324
+ detectActorFromKeyFiles?(): Promise<string | null>;
325
+ }
326
+
327
+ /**
328
+ * ConfigStore Interface
329
+ *
330
+ * Abstraction for config.json persistence.
331
+ * Enables backend-agnostic access to GitGovernance project configuration
332
+ * (filesystem, memory for tests, or future cloud backends).
333
+ *
334
+ * NOTE: Session state (.session.json) is handled by SessionStore, not ConfigStore.
335
+ * This separation allows different backends for config (immutable, versioned)
336
+ * vs session (ephemeral, local).
337
+ *
338
+ * @see packages/blueprints/03_products/core/specs/modules/config_session_module.md
339
+ * @see packages/blueprints/03_products/protocol/10_appendices/config_file.md
340
+ */
341
+
342
+ /**
343
+ * Interface for project configuration persistence.
344
+ *
345
+ * ConfigStore manages the project config.json file which is:
346
+ * - Versioned in Git (shared between collaborators)
347
+ * - Contains project-level settings (protocolVersion, projectId, rootCycle, etc.)
348
+ * - Rarely changes after initial setup
349
+ *
350
+ * Implementations:
351
+ * - FsConfigStore: Filesystem-based (.gitgov/config.json)
352
+ * - MemoryConfigStore: In-memory for tests
353
+ *
354
+ * @example
355
+ * ```typescript
356
+ * // Production with filesystem
357
+ * const store = new FsConfigStore('/path/to/project');
358
+ * const config = await store.loadConfig();
359
+ *
360
+ * // Tests with memory
361
+ * const store = new MemoryConfigStore();
362
+ * store.setConfig({ protocolVersion: '1.0', ... });
363
+ * ```
364
+ */
365
+ interface ConfigStore {
366
+ /**
367
+ * Load project configuration from config.json
368
+ *
369
+ * @returns GitGovConfig or null if not found/invalid
370
+ */
371
+ loadConfig(): Promise<GitGovConfig | null>;
372
+ /**
373
+ * Save project configuration to config.json
374
+ *
375
+ * @param config - Configuration to persist
376
+ */
377
+ saveConfig(config: GitGovConfig): Promise<void>;
378
+ }
379
+
380
+ /**
381
+ * KeyProvider Interface
382
+ *
383
+ * Abstracts private key storage for Actor signing operations.
384
+ * Enables different backends: filesystem (development), environment variables (serverless),
385
+ * or cloud KMS (enterprise).
386
+ *
387
+ * @module key_provider
388
+ */
389
+ /**
390
+ * Error codes for KeyProvider operations.
391
+ */
392
+ type KeyProviderErrorCode = 'KEY_NOT_FOUND' | 'KEY_READ_ERROR' | 'KEY_WRITE_ERROR' | 'KEY_DELETE_ERROR' | 'INVALID_KEY_FORMAT' | 'INVALID_ACTOR_ID';
393
+ /**
394
+ * Error thrown when key operations fail.
395
+ */
396
+ declare class KeyProviderError extends Error {
397
+ readonly code: KeyProviderErrorCode;
398
+ readonly actorId?: string | undefined;
399
+ constructor(message: string, code: KeyProviderErrorCode, actorId?: string | undefined);
400
+ }
401
+ /**
402
+ * Interface for managing private key storage.
403
+ * Implementations handle the actual persistence mechanism.
404
+ *
405
+ * @example
406
+ * ```typescript
407
+ * // Filesystem backend (development)
408
+ * const provider = new FsKeyProvider({ actorsDir: '.gitgov/actors' });
409
+ *
410
+ * // Environment backend (serverless)
411
+ * const provider = new EnvKeyProvider({ prefix: 'GITGOV_KEY_' });
412
+ *
413
+ * // Usage
414
+ * const privateKey = await provider.getPrivateKey('actor:human:alice');
415
+ * if (privateKey) {
416
+ * const signature = signPayload(payload, privateKey, actorId, role);
417
+ * }
418
+ * ```
419
+ */
420
+ interface KeyProvider {
421
+ /**
422
+ * Retrieves the private key for an actor.
423
+ * @param actorId - The actor's ID (e.g., 'actor:human:alice')
424
+ * @returns The base64-encoded private key, or null if not found
425
+ */
426
+ getPrivateKey(actorId: string): Promise<string | null>;
427
+ /**
428
+ * Stores a private key for an actor.
429
+ * @param actorId - The actor's ID
430
+ * @param privateKey - The base64-encoded private key
431
+ * @throws KeyProviderError if write fails
432
+ */
433
+ setPrivateKey(actorId: string, privateKey: string): Promise<void>;
434
+ /**
435
+ * Checks if a private key exists for an actor.
436
+ * @param actorId - The actor's ID
437
+ * @returns true if key exists, false otherwise
438
+ */
439
+ hasPrivateKey(actorId: string): Promise<boolean>;
440
+ /**
441
+ * Deletes the private key for an actor.
442
+ * @param actorId - The actor's ID
443
+ * @returns true if key was deleted, false if it didn't exist
444
+ */
445
+ deletePrivateKey(actorId: string): Promise<boolean>;
446
+ }
447
+
448
+ /**
449
+ * Options for file listing.
450
+ */
451
+ type FileListOptions = {
452
+ /** Glob patterns to ignore (e.g., ['node_modules/**']) */
453
+ ignore?: string[];
454
+ /** Only return files (not directories). Default: true */
455
+ onlyFiles?: boolean;
456
+ /** Return absolute paths instead of relative. Default: false */
457
+ absolute?: boolean;
458
+ /** Maximum depth to traverse. Default: unlimited */
459
+ maxDepth?: number;
460
+ };
461
+ /**
462
+ * File statistics returned by stat().
463
+ */
464
+ type FileStats = {
465
+ /** File size in bytes */
466
+ size: number;
467
+ /** Last modification time as timestamp (ms since epoch) */
468
+ mtime: number;
469
+ /** Whether it's a file (not directory) */
470
+ isFile: boolean;
471
+ };
472
+ /**
473
+ * Options for FsFileLister.
474
+ */
475
+ type FsFileListerOptions = {
476
+ /** Base directory for all operations */
477
+ cwd: string;
478
+ };
479
+ /**
480
+ * Options for MemoryFileLister.
481
+ */
482
+ type MemoryFileListerOptions = {
483
+ /** Map of filePath -> content */
484
+ files?: Map<string, string> | Record<string, string>;
485
+ /** Map of filePath -> stats (optional, generated if not provided) */
486
+ stats?: Map<string, FileStats>;
487
+ };
488
+
489
+ /**
490
+ * FileLister Interface
491
+ *
492
+ * Abstracts file listing and reading operations for serverless compatibility.
493
+ * Enables modules like ScopeSelector and IndexerAdapter to work without
494
+ * direct filesystem dependencies.
495
+ *
496
+ * @module file_lister
497
+ */
498
+
499
+ /**
500
+ * Interface for listing and reading files.
501
+ * Abstracts filesystem operations for serverless compatibility.
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * // Filesystem backend (development/CLI)
506
+ * import { FsFileLister } from '@gitgov/core/fs';
507
+ * const lister = new FsFileLister({ cwd: '/path/to/project' });
508
+ *
509
+ * // Memory backend (testing)
510
+ * import { MemoryFileLister } from '@gitgov/core/memory';
511
+ * const lister = new MemoryFileLister({ files: { 'src/index.ts': 'code...' } });
512
+ *
513
+ * // Usage
514
+ * const files = await lister.list(['**\/*.ts']);
515
+ * const content = await lister.read('src/index.ts');
516
+ * ```
517
+ */
518
+ interface FileLister {
519
+ /**
520
+ * [EARS-FL01] Lists files matching glob patterns.
521
+ * @param patterns - Glob patterns to match (e.g., ['**\/*.ts', 'src/**'])
522
+ * @param options - Optional configuration for listing
523
+ * @returns Array of file paths relative to cwd
524
+ */
525
+ list(patterns: string[], options?: FileListOptions): Promise<string[]>;
526
+ /**
527
+ * [EARS-FL02] Checks if a file exists.
528
+ * @param filePath - Path relative to cwd
529
+ * @returns true if file exists, false otherwise
530
+ */
531
+ exists(filePath: string): Promise<boolean>;
532
+ /**
533
+ * [EARS-FL03] Reads file content as string.
534
+ * @param filePath - Path relative to cwd
535
+ * @returns File content as UTF-8 string
536
+ * @throws FileListerError if file doesn't exist or can't be read
537
+ */
538
+ read(filePath: string): Promise<string>;
539
+ /**
540
+ * [EARS-FL04] Gets file statistics.
541
+ * @param filePath - Path relative to cwd
542
+ * @returns File stats (size, mtime)
543
+ * @throws FileListerError if file doesn't exist
544
+ */
545
+ stat(filePath: string): Promise<FileStats>;
546
+ }
547
+
548
+ /**
549
+ * Type Definitions for GitModule
550
+ *
551
+ * These types define the contracts for Git operations,
552
+ * dependencies, and data structures used throughout the module.
553
+ */
554
+ /**
555
+ * Options for executing shell commands
556
+ */
557
+ type ExecOptions = {
558
+ /** Working directory for the command */
559
+ cwd?: string;
560
+ /** Additional environment variables */
561
+ env?: Record<string, string>;
562
+ /** Timeout in milliseconds */
563
+ timeout?: number;
564
+ };
565
+ /**
566
+ * Result of executing a shell command
567
+ */
568
+ type ExecResult = {
569
+ /** Exit code (0 = success) */
570
+ exitCode: number;
571
+ /** Standard output */
572
+ stdout: string;
573
+ /** Standard error output */
574
+ stderr: string;
575
+ };
576
+ /**
577
+ * Dependencies required by LocalGitModule
578
+ *
579
+ * This module uses dependency injection to allow testing with mocks
580
+ * and support different execution environments.
581
+ */
582
+ type GitModuleDependencies = {
583
+ /** Path to the Git repository root (optional, auto-detected if not provided) */
584
+ repoRoot?: string;
585
+ /** Function to execute shell commands (required) */
586
+ execCommand: (command: string, args: string[], options?: ExecOptions) => Promise<ExecResult>;
587
+ };
588
+ /**
589
+ * Options for retrieving commit history
590
+ */
591
+ type GetCommitHistoryOptions = {
592
+ /** Maximum number of commits to return */
593
+ maxCount?: number;
594
+ /** Path filter (e.g., ".gitgov/") */
595
+ pathFilter?: string;
596
+ /** Output format (default: "json") */
597
+ format?: 'json' | 'text';
598
+ };
599
+ /**
600
+ * Information about a commit in the history
601
+ */
602
+ type CommitInfo = {
603
+ /** Commit hash */
604
+ hash: string;
605
+ /** Commit message */
606
+ message: string;
607
+ /** Commit author (name <email>) */
608
+ author: string;
609
+ /** Commit date (ISO 8601) */
610
+ date: string;
611
+ /** List of modified files (optional) */
612
+ files?: string[];
613
+ };
614
+ /**
615
+ * Information about a changed file
616
+ */
617
+ type ChangedFile = {
618
+ /** Change status: A (Added), M (Modified), D (Deleted) */
619
+ status: 'A' | 'M' | 'D';
620
+ /** File path relative to repository root */
621
+ file: string;
622
+ };
623
+ /**
624
+ * Author information for commits
625
+ */
626
+ type CommitAuthor = {
627
+ /** Author name */
628
+ name: string;
629
+ /** Author email */
630
+ email: string;
631
+ };
632
+
633
+ /**
634
+ * Custom Error Classes for GitModule
635
+ *
636
+ * These errors provide typed exceptions for better error handling
637
+ * and diagnostics in the Git module operations.
638
+ */
639
+ /**
640
+ * Base error class for all Git-related errors
641
+ */
642
+ declare class GitError extends Error {
643
+ constructor(message: string);
644
+ }
645
+ /**
646
+ * Error thrown when a Git command fails
647
+ */
648
+ declare class GitCommandError extends GitError {
649
+ readonly stderr: string;
650
+ readonly stdout?: string | undefined;
651
+ readonly command?: string | undefined;
652
+ constructor(message: string, stderr?: string, command?: string | undefined, stdout?: string);
653
+ }
654
+ /**
655
+ * Error thrown when a branch does not exist
656
+ */
657
+ declare class BranchNotFoundError extends GitError {
658
+ readonly branchName: string;
659
+ constructor(branchName: string);
660
+ }
661
+ /**
662
+ * Error thrown when a file does not exist in a commit
663
+ */
664
+ declare class FileNotFoundError extends GitError {
665
+ readonly filePath: string;
666
+ readonly commitHash: string;
667
+ constructor(filePath: string, commitHash: string);
668
+ }
669
+ /**
670
+ * Error thrown when a merge conflict occurs
671
+ */
672
+ declare class MergeConflictError extends GitError {
673
+ readonly conflictedFiles: string[];
674
+ constructor(conflictedFiles: string[]);
675
+ }
676
+ /**
677
+ * Error thrown when a rebase conflict occurs
678
+ */
679
+ declare class RebaseConflictError extends GitError {
680
+ readonly conflictedFiles: string[];
681
+ constructor(conflictedFiles: string[]);
682
+ }
683
+ /**
684
+ * Error thrown when trying to continue/abort a rebase that is not in progress
685
+ */
686
+ declare class RebaseNotInProgressError extends GitError {
687
+ constructor();
688
+ }
689
+ /**
690
+ * Error thrown when trying to create a branch that already exists
691
+ */
692
+ declare class BranchAlreadyExistsError extends GitError {
693
+ readonly branchName: string;
694
+ constructor(branchName: string);
695
+ }
696
+
697
+ /**
698
+ * GitModule - Low-level Git Operations
699
+ *
700
+ * This module provides backend-agnostic access to Git operations.
701
+ *
702
+ * IMPORTANT: This module only exports the interface and types.
703
+ * For implementations, use:
704
+ * - @gitgov/core/fs for LocalGitModule (CLI-based)
705
+ * - @gitgov/core/memory for MemoryGitModule (testing)
706
+ *
707
+ * @example
708
+ * ```typescript
709
+ * // Import interface and types
710
+ * import type { IGitModule } from '@gitgov/core';
711
+ *
712
+ * // Import CLI implementation from fs entry point
713
+ * import { LocalGitModule } from '@gitgov/core/fs';
714
+ *
715
+ * // Import memory implementation from memory entry point
716
+ * import { MemoryGitModule } from '@gitgov/core/memory';
717
+ * ```
718
+ *
719
+ * @module git
720
+ */
721
+
722
+ /**
723
+ * IGitModule - Interface for Git operations
724
+ *
725
+ * Implementations:
726
+ * - LocalGitModule: Uses execCommand to run git CLI (production)
727
+ * - MemoryGitModule: In-memory mock for unit tests
728
+ * - Future: GitHubGitModule for SaaS API-based operations
729
+ *
730
+ * All methods are async to support both local CLI execution
731
+ * and future API-based implementations (GitHub REST/GraphQL).
732
+ */
733
+ interface IGitModule {
734
+ exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
735
+ init(): Promise<void>;
736
+ getRepoRoot(): Promise<string>;
737
+ getCurrentBranch(): Promise<string>;
738
+ getCommitHash(ref?: string): Promise<string>;
739
+ setConfig(key: string, value: string, scope?: 'local' | 'global' | 'system'): Promise<void>;
740
+ getMergeBase(branchA: string, branchB: string): Promise<string>;
741
+ getChangedFiles(fromCommit: string, toCommit: string, pathFilter: string): Promise<ChangedFile[]>;
742
+ getStagedFiles(): Promise<string[]>;
743
+ getFileContent(commitHash: string, filePath: string): Promise<string>;
744
+ getCommitHistory(branch: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
745
+ getCommitHistoryRange(fromHash: string, toHash: string, options?: GetCommitHistoryOptions): Promise<CommitInfo[]>;
746
+ getCommitMessage(commitHash: string): Promise<string>;
747
+ hasUncommittedChanges(pathFilter?: string): Promise<boolean>;
748
+ isRebaseInProgress(): Promise<boolean>;
749
+ branchExists(branchName: string): Promise<boolean>;
750
+ listRemoteBranches(remoteName: string): Promise<string[]>;
751
+ isRemoteConfigured(remoteName: string): Promise<boolean>;
752
+ getBranchRemote(branchName: string): Promise<string | null>;
753
+ getConflictedFiles(): Promise<string[]>;
754
+ checkoutBranch(branchName: string): Promise<void>;
755
+ stash(message?: string): Promise<string | null>;
756
+ stashPop(): Promise<boolean>;
757
+ stashDrop(stashHash?: string): Promise<void>;
758
+ checkoutOrphanBranch(branchName: string): Promise<void>;
759
+ fetch(remote: string): Promise<void>;
760
+ pull(remote: string, branchName: string): Promise<void>;
761
+ pullRebase(remote: string, branchName: string): Promise<void>;
762
+ resetHard(target: string): Promise<void>;
763
+ checkoutFilesFromBranch(sourceBranch: string, filePaths: string[]): Promise<void>;
764
+ add(filePaths: string[], options?: {
765
+ force?: boolean;
766
+ }): Promise<void>;
767
+ rm(filePaths: string[]): Promise<void>;
768
+ commit(message: string, author?: CommitAuthor): Promise<string>;
769
+ commitAllowEmpty(message: string, author?: CommitAuthor): Promise<string>;
770
+ push(remote: string, branchName: string): Promise<void>;
771
+ pushWithUpstream(remote: string, branchName: string): Promise<void>;
772
+ setUpstream(branchName: string, remote: string, remoteBranch: string): Promise<void>;
773
+ rebaseContinue(): Promise<string>;
774
+ rebaseAbort(): Promise<void>;
775
+ createBranch(branchName: string, startPoint?: string): Promise<void>;
776
+ rebase(targetBranch: string): Promise<void>;
777
+ }
778
+
779
+ type index_BranchAlreadyExistsError = BranchAlreadyExistsError;
780
+ declare const index_BranchAlreadyExistsError: typeof BranchAlreadyExistsError;
781
+ type index_BranchNotFoundError = BranchNotFoundError;
782
+ declare const index_BranchNotFoundError: typeof BranchNotFoundError;
783
+ type index_ChangedFile = ChangedFile;
784
+ type index_CommitAuthor = CommitAuthor;
785
+ type index_CommitInfo = CommitInfo;
786
+ type index_ExecOptions = ExecOptions;
787
+ type index_ExecResult = ExecResult;
788
+ type index_FileNotFoundError = FileNotFoundError;
789
+ declare const index_FileNotFoundError: typeof FileNotFoundError;
790
+ type index_GetCommitHistoryOptions = GetCommitHistoryOptions;
791
+ type index_GitCommandError = GitCommandError;
792
+ declare const index_GitCommandError: typeof GitCommandError;
793
+ type index_GitError = GitError;
794
+ declare const index_GitError: typeof GitError;
795
+ type index_GitModuleDependencies = GitModuleDependencies;
796
+ type index_IGitModule = IGitModule;
797
+ type index_MergeConflictError = MergeConflictError;
798
+ declare const index_MergeConflictError: typeof MergeConflictError;
799
+ type index_RebaseConflictError = RebaseConflictError;
800
+ declare const index_RebaseConflictError: typeof RebaseConflictError;
801
+ type index_RebaseNotInProgressError = RebaseNotInProgressError;
802
+ declare const index_RebaseNotInProgressError: typeof RebaseNotInProgressError;
803
+ declare namespace index {
804
+ export { index_BranchAlreadyExistsError as BranchAlreadyExistsError, index_BranchNotFoundError as BranchNotFoundError, type index_ChangedFile as ChangedFile, type index_CommitAuthor as CommitAuthor, type index_CommitInfo as CommitInfo, type index_ExecOptions as ExecOptions, type index_ExecResult as ExecResult, index_FileNotFoundError as FileNotFoundError, type index_GetCommitHistoryOptions as GetCommitHistoryOptions, index_GitCommandError as GitCommandError, index_GitError as GitError, type index_GitModuleDependencies as GitModuleDependencies, type index_IGitModule as IGitModule, index_MergeConflictError as MergeConflictError, index_RebaseConflictError as RebaseConflictError, index_RebaseNotInProgressError as RebaseNotInProgressError };
805
+ }
806
+
807
+ export { type ActorState as A, type ConfigStore as C, type ExecOptions as E, type FsFileListerOptions as F, type GitGovConfig as G, type IGitModule as I, type KeyProvider as K, type MemoryFileListerOptions as M, type RecordStore as R, type SessionStore as S, type GitGovSession as a, type GitModuleDependencies as b, type ExecResult as c, type ChangedFile as d, type GetCommitHistoryOptions as e, type CommitInfo as f, type CommitAuthor as g, type ISessionManager as h, type SyncPreferencesUpdate as i, type SyncStatus as j, type AuditState as k, type AuditStateUpdate as l, type IConfigManager as m, type SyncConfig as n, type SyncDefaults as o, KeyProviderError as p, type KeyProviderErrorCode as q, type FileListOptions as r, type FileLister as s, type FileStats as t, index as u };