fix(git-master): inject watermark only when enabled instead of overriding defaults
The watermark (commit footer and co-author) was inconsistently applied because: 1. The skill tool didn't receive gitMasterConfig 2. The approach was 'default ON, inject DISABLED override' which LLMs sometimes ignored This refactors to 'inject only when enabled' approach: - Remove hardcoded watermark section from base templates - Dynamically inject section 5.5 based on config values - Default is still ON (both true when no config) - When both disabled, no injection occurs (clean prompt) Also fixes missing config propagation to skill tool and createBuiltinAgents.
This commit is contained in:
@@ -160,8 +160,8 @@ describe("resolveMultipleSkillsAsync", () => {
|
||||
expect(result.resolved.get("playwright")).toContain("Playwright Browser Automation")
|
||||
})
|
||||
|
||||
it("should support git-master config injection", async () => {
|
||||
// #given: git-master skill with config override
|
||||
it("should NOT inject watermark when both options are disabled", async () => {
|
||||
// #given: git-master skill with watermark disabled
|
||||
const skillNames = ["git-master"]
|
||||
const options = {
|
||||
gitMasterConfig: {
|
||||
@@ -173,12 +173,84 @@ describe("resolveMultipleSkillsAsync", () => {
|
||||
// #when: resolving with git-master config
|
||||
const result = await resolveMultipleSkillsAsync(skillNames, options)
|
||||
|
||||
// #then: config values injected into template
|
||||
// #then: no watermark section injected
|
||||
expect(result.resolved.size).toBe(1)
|
||||
expect(result.notFound).toEqual([])
|
||||
const gitMasterContent = result.resolved.get("git-master")
|
||||
expect(gitMasterContent).toContain("commit_footer")
|
||||
expect(gitMasterContent).toContain("DISABLED")
|
||||
expect(gitMasterContent).not.toContain("Ultraworked with")
|
||||
expect(gitMasterContent).not.toContain("Co-authored-by: Sisyphus")
|
||||
})
|
||||
|
||||
it("should inject watermark when enabled (default)", async () => {
|
||||
// #given: git-master skill with default config (watermark enabled)
|
||||
const skillNames = ["git-master"]
|
||||
const options = {
|
||||
gitMasterConfig: {
|
||||
commit_footer: true,
|
||||
include_co_authored_by: true,
|
||||
},
|
||||
}
|
||||
|
||||
// #when: resolving with git-master config
|
||||
const result = await resolveMultipleSkillsAsync(skillNames, options)
|
||||
|
||||
// #then: watermark section is injected
|
||||
expect(result.resolved.size).toBe(1)
|
||||
const gitMasterContent = result.resolved.get("git-master")
|
||||
expect(gitMasterContent).toContain("Ultraworked with [Sisyphus]")
|
||||
expect(gitMasterContent).toContain("Co-authored-by: Sisyphus")
|
||||
})
|
||||
|
||||
it("should inject only footer when co-author is disabled", async () => {
|
||||
// #given: git-master skill with only footer enabled
|
||||
const skillNames = ["git-master"]
|
||||
const options = {
|
||||
gitMasterConfig: {
|
||||
commit_footer: true,
|
||||
include_co_authored_by: false,
|
||||
},
|
||||
}
|
||||
|
||||
// #when: resolving with git-master config
|
||||
const result = await resolveMultipleSkillsAsync(skillNames, options)
|
||||
|
||||
// #then: only footer is injected
|
||||
const gitMasterContent = result.resolved.get("git-master")
|
||||
expect(gitMasterContent).toContain("Ultraworked with [Sisyphus]")
|
||||
expect(gitMasterContent).not.toContain("Co-authored-by: Sisyphus")
|
||||
})
|
||||
|
||||
it("should inject watermark by default when no config provided", async () => {
|
||||
// #given: git-master skill with NO config (default behavior)
|
||||
const skillNames = ["git-master"]
|
||||
|
||||
// #when: resolving without any gitMasterConfig
|
||||
const result = await resolveMultipleSkillsAsync(skillNames)
|
||||
|
||||
// #then: watermark is injected (default is ON)
|
||||
expect(result.resolved.size).toBe(1)
|
||||
const gitMasterContent = result.resolved.get("git-master")
|
||||
expect(gitMasterContent).toContain("Ultraworked with [Sisyphus]")
|
||||
expect(gitMasterContent).toContain("Co-authored-by: Sisyphus")
|
||||
})
|
||||
|
||||
it("should inject only co-author when footer is disabled", async () => {
|
||||
// #given: git-master skill with only co-author enabled
|
||||
const skillNames = ["git-master"]
|
||||
const options = {
|
||||
gitMasterConfig: {
|
||||
commit_footer: false,
|
||||
include_co_authored_by: true,
|
||||
},
|
||||
}
|
||||
|
||||
// #when: resolving with git-master config
|
||||
const result = await resolveMultipleSkillsAsync(skillNames, options)
|
||||
|
||||
// #then: only co-author is injected
|
||||
const gitMasterContent = result.resolved.get("git-master")
|
||||
expect(gitMasterContent).not.toContain("Ultraworked with [Sisyphus]")
|
||||
expect(gitMasterContent).toContain("Co-authored-by: Sisyphus")
|
||||
})
|
||||
|
||||
it("should handle empty array", async () => {
|
||||
|
||||
@@ -59,22 +59,62 @@ async function extractSkillTemplate(skill: LoadedSkill): Promise<string> {
|
||||
|
||||
export { clearSkillCache, getAllSkills, extractSkillTemplate }
|
||||
|
||||
function injectGitMasterConfig(template: string, config?: GitMasterConfig): string {
|
||||
if (!config) return template
|
||||
export function injectGitMasterConfig(template: string, config?: GitMasterConfig): string {
|
||||
const commitFooter = config?.commit_footer ?? true
|
||||
const includeCoAuthoredBy = config?.include_co_authored_by ?? true
|
||||
|
||||
const commitFooter = config.commit_footer ?? true
|
||||
const includeCoAuthoredBy = config.include_co_authored_by ?? true
|
||||
if (!commitFooter && !includeCoAuthoredBy) {
|
||||
return template
|
||||
}
|
||||
|
||||
const configHeader = `## Git Master Configuration (from oh-my-opencode.json)
|
||||
const sections: string[] = []
|
||||
|
||||
**IMPORTANT: These values override the defaults in section 5.5:**
|
||||
- \`commit_footer\`: ${commitFooter} ${!commitFooter ? "(DISABLED - do NOT add footer)" : ""}
|
||||
- \`include_co_authored_by\`: ${includeCoAuthoredBy} ${!includeCoAuthoredBy ? "(DISABLED - do NOT add Co-authored-by)" : ""}
|
||||
sections.push(`### 5.5 Commit Footer & Co-Author`)
|
||||
sections.push(``)
|
||||
sections.push(`Add Sisyphus attribution to EVERY commit:`)
|
||||
sections.push(``)
|
||||
|
||||
---
|
||||
if (commitFooter) {
|
||||
sections.push(`1. **Footer in commit body:**`)
|
||||
sections.push("```")
|
||||
sections.push(`Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)`)
|
||||
sections.push("```")
|
||||
sections.push(``)
|
||||
}
|
||||
|
||||
`
|
||||
return configHeader + template
|
||||
if (includeCoAuthoredBy) {
|
||||
sections.push(`${commitFooter ? "2" : "1"}. **Co-authored-by trailer:**`)
|
||||
sections.push("```")
|
||||
sections.push(`Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>`)
|
||||
sections.push("```")
|
||||
sections.push(``)
|
||||
}
|
||||
|
||||
if (commitFooter && includeCoAuthoredBy) {
|
||||
sections.push(`**Example (both enabled):**`)
|
||||
sections.push("```bash")
|
||||
sections.push(`git commit -m "{Commit Message}" -m "Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)" -m "Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>"`)
|
||||
sections.push("```")
|
||||
} else if (commitFooter) {
|
||||
sections.push(`**Example:**`)
|
||||
sections.push("```bash")
|
||||
sections.push(`git commit -m "{Commit Message}" -m "Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)"`)
|
||||
sections.push("```")
|
||||
} else if (includeCoAuthoredBy) {
|
||||
sections.push(`**Example:**`)
|
||||
sections.push("```bash")
|
||||
sections.push(`git commit -m "{Commit Message}" -m "Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>"`)
|
||||
sections.push("```")
|
||||
}
|
||||
|
||||
const injection = sections.join("\n")
|
||||
|
||||
const insertionPoint = template.indexOf("```\n</execution>")
|
||||
if (insertionPoint !== -1) {
|
||||
return template.slice(0, insertionPoint) + "```\n\n" + injection + "\n</execution>" + template.slice(insertionPoint + "```\n</execution>".length)
|
||||
}
|
||||
|
||||
return template + "\n\n" + injection
|
||||
}
|
||||
|
||||
export function resolveSkillContent(skillName: string, options?: SkillResolutionOptions): string | null {
|
||||
@@ -82,8 +122,8 @@ export function resolveSkillContent(skillName: string, options?: SkillResolution
|
||||
const skill = skills.find((s) => s.name === skillName)
|
||||
if (!skill) return null
|
||||
|
||||
if (skillName === "git-master" && options?.gitMasterConfig) {
|
||||
return injectGitMasterConfig(skill.template, options.gitMasterConfig)
|
||||
if (skillName === "git-master") {
|
||||
return injectGitMasterConfig(skill.template, options?.gitMasterConfig)
|
||||
}
|
||||
|
||||
return skill.template
|
||||
@@ -102,8 +142,8 @@ export function resolveMultipleSkills(skillNames: string[], options?: SkillResol
|
||||
for (const name of skillNames) {
|
||||
const template = skillMap.get(name)
|
||||
if (template) {
|
||||
if (name === "git-master" && options?.gitMasterConfig) {
|
||||
resolved.set(name, injectGitMasterConfig(template, options.gitMasterConfig))
|
||||
if (name === "git-master") {
|
||||
resolved.set(name, injectGitMasterConfig(template, options?.gitMasterConfig))
|
||||
} else {
|
||||
resolved.set(name, template)
|
||||
}
|
||||
@@ -125,8 +165,8 @@ export async function resolveSkillContentAsync(
|
||||
|
||||
const template = await extractSkillTemplate(skill)
|
||||
|
||||
if (skillName === "git-master" && options?.gitMasterConfig) {
|
||||
return injectGitMasterConfig(template, options.gitMasterConfig)
|
||||
if (skillName === "git-master") {
|
||||
return injectGitMasterConfig(template, options?.gitMasterConfig)
|
||||
}
|
||||
|
||||
return template
|
||||
@@ -152,8 +192,8 @@ export async function resolveMultipleSkillsAsync(
|
||||
const skill = skillMap.get(name)
|
||||
if (skill) {
|
||||
const template = await extractSkillTemplate(skill)
|
||||
if (name === "git-master" && options?.gitMasterConfig) {
|
||||
resolved.set(name, injectGitMasterConfig(template, options.gitMasterConfig))
|
||||
if (name === "git-master") {
|
||||
resolved.set(name, injectGitMasterConfig(template, options?.gitMasterConfig))
|
||||
} else {
|
||||
resolved.set(name, template)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user