@@ -4,27 +4,53 @@ import { type SimpleGit, simpleGit } from 'simple-git';
44import { getDailyNoteFileName } from '../infra/date.js' ;
55import { logger } from '../infra/logger.js' ;
66
7+ /** Result returned after publishing files to a git repository. */
78export interface GitPublishResult {
9+ /** The branch that was checked out for the publish. */
810 branch : string ;
11+ /** Relative file paths that were written. */
912 fileNames : string [ ] ;
13+ /** Absolute file paths that were written. */
1014 filePaths : string [ ] ;
15+ /** Whether the changes were pushed to a remote. */
1116 pushed : boolean ;
1217}
1318
19+ /** A single file to be written into the repository. */
1420export interface FileWriteRequest {
21+ /** Relative path within the repository. */
1522 path : string ;
23+ /** UTF-8 content to write. */
1624 content : string ;
1725}
1826
27+ /** Options for controlling branch behaviour during publish. */
1928export interface PublishOptions {
29+ /** Target branch name (defaults to `'main'`). */
2030 branchName ?: string ;
31+ /** Base branch to create the target from if it doesn't exist (defaults to `'main'`). */
2132 baseBranch ?: string ;
2233}
2334
35+ /**
36+ * Manages git operations for writing and publishing generated content
37+ * to a target repository.
38+ *
39+ * Wraps `simple-git` to provide higher-level helpers for staging,
40+ * committing, and pushing files — used by the daily-note and artifact
41+ * publishing workflows.
42+ */
2443export class GitService {
2544 private git : SimpleGit | null = null ;
2645 private repoPath : string = '' ;
2746
47+ /**
48+ * Bind the service to a local repository path.
49+ *
50+ * @param repoPath - Absolute path to an existing git repository.
51+ * @returns `true` if the repository was successfully initialised,
52+ * `false` if the path is missing or not a git repo.
53+ */
2854 async initialize ( repoPath : string ) : Promise < boolean > {
2955 if ( ! existsSync ( repoPath ) ) {
3056 logger . warn ( `Target repository path does not exist: ${ repoPath } ` ) ;
@@ -48,6 +74,13 @@ export class GitService {
4874 }
4975 }
5076
77+ /**
78+ * Generate a daily note file, commit it, and push to the remote.
79+ *
80+ * @param content - Markdown content for the daily note.
81+ * @param commitMessage - Git commit message.
82+ * @returns A {@link GitPublishResult} on success, or `null` on failure.
83+ */
5184 async addCommitPush ( content : string , commitMessage : string ) : Promise < GitPublishResult | null > {
5285 if ( ! this . git ) {
5386 throw new Error ( 'Git service not initialized' ) ;
@@ -63,6 +96,17 @@ export class GitService {
6396 }
6497 }
6598
99+ /**
100+ * Write one or more files, commit them, and optionally push.
101+ *
102+ * Creates intermediate directories as needed. Uses an atomic
103+ * `--set-upstream` push when a remote is configured.
104+ *
105+ * @param files - Files to write and stage.
106+ * @param commitMessage - Git commit message.
107+ * @param options - Optional branch overrides.
108+ * @returns A {@link GitPublishResult} on success, or `null` on failure.
109+ */
66110 async writeAndPublish (
67111 files : FileWriteRequest [ ] ,
68112 commitMessage : string ,
@@ -108,6 +152,7 @@ export class GitService {
108152 }
109153 }
110154
155+ /** Return a JSON-formatted summary of the current git status. */
111156 async getStatus ( ) : Promise < string > {
112157 if ( ! this . git ) {
113158 throw new Error ( 'Git service not initialized' ) ;
@@ -117,6 +162,7 @@ export class GitService {
117162 return JSON . stringify ( status , null , 2 ) ;
118163 }
119164
165+ /** Check whether the working tree has any uncommitted changes. */
120166 async hasLocalChanges ( ) : Promise < boolean > {
121167 if ( ! this . git ) {
122168 throw new Error ( 'Git service not initialized' ) ;
0 commit comments