From 26c8d55b6795e06aad7c0f5d8febc17fc4f13173 Mon Sep 17 00:00:00 2001 From: Jeon Suyeol Date: Fri, 6 Mar 2026 11:35:52 +0900 Subject: [PATCH] feat(git-master): add git_env_prefix config to prefix all git commands When git-master skill is loaded, all git commands are prefixed with the configured env variable (default: GIT_MASTER=1). This enables custom git hooks to detect git-master skill usage. Set to empty string to disable. --- src/config/schema/git-master.ts | 2 + .../git-master-template-injection.ts | 84 +++++++++++++++---- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/config/schema/git-master.ts b/src/config/schema/git-master.ts index 0574de860..e162b38c5 100644 --- a/src/config/schema/git-master.ts +++ b/src/config/schema/git-master.ts @@ -5,6 +5,8 @@ export const GitMasterConfigSchema = z.object({ commit_footer: z.union([z.boolean(), z.string()]).default(true), /** Add "Co-authored-by: Sisyphus" trailer to commit messages (default: true) */ include_co_authored_by: z.boolean().default(true), + /** Environment variable prefix for all git commands (default: "GIT_MASTER=1"). Set to "" to disable. Allows custom git hooks to detect git-master skill usage. */ + git_env_prefix: z.string().default("GIT_MASTER=1"), }) export type GitMasterConfig = z.infer diff --git a/src/features/opencode-skill-loader/git-master-template-injection.ts b/src/features/opencode-skill-loader/git-master-template-injection.ts index f6815798c..daec2d31a 100644 --- a/src/features/opencode-skill-loader/git-master-template-injection.ts +++ b/src/features/opencode-skill-loader/git-master-template-injection.ts @@ -3,12 +3,73 @@ import type { GitMasterConfig } from "../../config/schema" export function injectGitMasterConfig(template: string, config?: GitMasterConfig): string { const commitFooter = config?.commit_footer ?? true const includeCoAuthoredBy = config?.include_co_authored_by ?? true + const gitEnvPrefix = config?.git_env_prefix ?? "GIT_MASTER=1" + + let result = gitEnvPrefix ? injectGitEnvPrefix(template, gitEnvPrefix) : template if (!commitFooter && !includeCoAuthoredBy) { - return template + return result } + const injection = buildCommitFooterInjection(commitFooter, includeCoAuthoredBy, gitEnvPrefix) + + const insertionPoint = result.indexOf("```\n") + if (insertionPoint !== -1) { + return ( + result.slice(0, insertionPoint) + + "```\n\n" + + injection + + "\n" + + result.slice(insertionPoint + "```\n".length) + ) + } + + return result + "\n\n" + injection +} + +function injectGitEnvPrefix(template: string, prefix: string): string { + const envPrefixSection = [ + "## GIT COMMAND PREFIX (MANDATORY)", + "", + ``, + `**EVERY git command MUST be prefixed with \`${prefix}\`.**`, + "", + "This allows custom git hooks to detect when git-master skill is active.", + "", + "```bash", + `${prefix} git status`, + `${prefix} git add `, + `${prefix} git commit -m "message"`, + `${prefix} git push`, + `${prefix} git rebase ...`, + `${prefix} git log ...`, + "```", + "", + "**NO EXCEPTIONS. Every `git` invocation must include this prefix.**", + ``, + ].join("\n") + + const modeDetectionMarker = "## MODE DETECTION (FIRST STEP)" + const markerIndex = template.indexOf(modeDetectionMarker) + if (markerIndex !== -1) { + return ( + template.slice(0, markerIndex) + + envPrefixSection + + "\n\n---\n\n" + + template.slice(markerIndex) + ) + } + + return envPrefixSection + "\n\n---\n\n" + template +} + +function buildCommitFooterInjection( + commitFooter: boolean | string, + includeCoAuthoredBy: boolean, + gitEnvPrefix: string, +): string { const sections: string[] = [] + const cmdPrefix = gitEnvPrefix ? `${gitEnvPrefix} ` : "" sections.push("### 5.5 Commit Footer & Co-Author") sections.push("") @@ -43,7 +104,7 @@ export function injectGitMasterConfig(template: string, config?: GitMasterConfig sections.push("**Example (both enabled):**") sections.push("```bash") sections.push( - `git commit -m "{Commit Message}" -m "${footerText}" -m "Co-authored-by: Sisyphus "` + `${cmdPrefix}git commit -m "{Commit Message}" -m "${footerText}" -m "Co-authored-by: Sisyphus "` ) sections.push("```") } else if (commitFooter) { @@ -53,29 +114,16 @@ export function injectGitMasterConfig(template: string, config?: GitMasterConfig : "Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)" sections.push("**Example:**") sections.push("```bash") - sections.push(`git commit -m "{Commit Message}" -m "${footerText}"`) + sections.push(`${cmdPrefix}git commit -m "{Commit Message}" -m "${footerText}"`) sections.push("```") } else if (includeCoAuthoredBy) { sections.push("**Example:**") sections.push("```bash") sections.push( - "git commit -m \"{Commit Message}\" -m \"Co-authored-by: Sisyphus \"" + `${cmdPrefix}git commit -m "{Commit Message}" -m "Co-authored-by: Sisyphus "` ) sections.push("```") } - const injection = sections.join("\n") - - const insertionPoint = template.indexOf("```\n") - if (insertionPoint !== -1) { - return ( - template.slice(0, insertionPoint) + - "```\n\n" + - injection + - "\n" + - template.slice(insertionPoint + "```\n".length) - ) - } - - return template + "\n\n" + injection + return sections.join("\n") }