init
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import memoize from 'lodash-es/memoize.js'
|
||||
import { basename } from 'path'
|
||||
import type { OutputStyleConfig } from '../constants/outputStyles.js'
|
||||
import { logForDebugging } from '../utils/debug.js'
|
||||
import { coerceDescriptionToString } from '../utils/frontmatterParser.js'
|
||||
import { logError } from '../utils/log.js'
|
||||
import {
|
||||
extractDescriptionFromMarkdown,
|
||||
loadMarkdownFilesForSubdir,
|
||||
} from '../utils/markdownConfigLoader.js'
|
||||
import { clearPluginOutputStyleCache } from '../utils/plugins/loadPluginOutputStyles.js'
|
||||
|
||||
/**
|
||||
* Loads markdown files from .claude/output-styles directories throughout the project
|
||||
* and from ~/.claude/output-styles directory and converts them to output styles.
|
||||
*
|
||||
* Each filename becomes a style name, and the file content becomes the style prompt.
|
||||
* The frontmatter provides name and description.
|
||||
*
|
||||
* Structure:
|
||||
* - Project .claude/output-styles/*.md -> project styles
|
||||
* - User ~/.claude/output-styles/*.md -> user styles (overridden by project styles)
|
||||
*
|
||||
* @param cwd Current working directory for project directory traversal
|
||||
*/
|
||||
export const getOutputStyleDirStyles = memoize(
|
||||
async (cwd: string): Promise<OutputStyleConfig[]> => {
|
||||
try {
|
||||
const markdownFiles = await loadMarkdownFilesForSubdir(
|
||||
'output-styles',
|
||||
cwd,
|
||||
)
|
||||
|
||||
const styles = markdownFiles
|
||||
.map(({ filePath, frontmatter, content, source }) => {
|
||||
try {
|
||||
const fileName = basename(filePath)
|
||||
const styleName = fileName.replace(/\.md$/, '')
|
||||
|
||||
// Get style configuration from frontmatter
|
||||
const name = (frontmatter['name'] || styleName) as string
|
||||
const description =
|
||||
coerceDescriptionToString(
|
||||
frontmatter['description'],
|
||||
styleName,
|
||||
) ??
|
||||
extractDescriptionFromMarkdown(
|
||||
content,
|
||||
`Custom ${styleName} output style`,
|
||||
)
|
||||
|
||||
// Parse keep-coding-instructions flag (supports both boolean and string values)
|
||||
const keepCodingInstructionsRaw =
|
||||
frontmatter['keep-coding-instructions']
|
||||
const keepCodingInstructions =
|
||||
keepCodingInstructionsRaw === true ||
|
||||
keepCodingInstructionsRaw === 'true'
|
||||
? true
|
||||
: keepCodingInstructionsRaw === false ||
|
||||
keepCodingInstructionsRaw === 'false'
|
||||
? false
|
||||
: undefined
|
||||
|
||||
// Warn if force-for-plugin is set on non-plugin output style
|
||||
if (frontmatter['force-for-plugin'] !== undefined) {
|
||||
logForDebugging(
|
||||
`Output style "${name}" has force-for-plugin set, but this option only applies to plugin output styles. Ignoring.`,
|
||||
{ level: 'warn' },
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
description,
|
||||
prompt: content.trim(),
|
||||
source,
|
||||
keepCodingInstructions,
|
||||
}
|
||||
} catch (error) {
|
||||
logError(error)
|
||||
return null
|
||||
}
|
||||
})
|
||||
.filter(style => style !== null)
|
||||
|
||||
return styles
|
||||
} catch (error) {
|
||||
logError(error)
|
||||
return []
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
export function clearOutputStyleCaches(): void {
|
||||
getOutputStyleDirStyles.cache?.clear?.()
|
||||
loadMarkdownFilesForSubdir.cache?.clear?.()
|
||||
clearPluginOutputStyleCache()
|
||||
}
|
||||
Reference in New Issue
Block a user