fix(dispatch): resolve plugin namespace parsing, template substitution, and discovery duplication
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
import { existsSync, readdirSync, readFileSync } from "fs"
|
||||
import { basename, join } from "path"
|
||||
import { parseFrontmatter, sanitizeModelField, getOpenCodeConfigDir } from "../../shared"
|
||||
import {
|
||||
parseFrontmatter,
|
||||
sanitizeModelField,
|
||||
getOpenCodeConfigDir,
|
||||
discoverPluginCommandDefinitions,
|
||||
} from "../../shared"
|
||||
import type { CommandFrontmatter } from "../../features/claude-code-command-loader/types"
|
||||
import { isMarkdownFile } from "../../shared/file-utils"
|
||||
import { getClaudeConfigDir } from "../../shared"
|
||||
import { loadBuiltinCommands } from "../../features/builtin-commands"
|
||||
import {
|
||||
discoverInstalledPlugins,
|
||||
loadPluginCommands,
|
||||
loadPluginSkillsAsCommands,
|
||||
} from "../../features/claude-code-plugin-loader"
|
||||
import type { CommandInfo, CommandMetadata, CommandScope } from "./types"
|
||||
|
||||
export interface CommandDiscoveryOptions {
|
||||
@@ -59,18 +59,7 @@ function discoverCommandsFromDir(commandsDir: string, scope: CommandScope): Comm
|
||||
}
|
||||
|
||||
function discoverPluginCommands(options?: CommandDiscoveryOptions): CommandInfo[] {
|
||||
if (options?.pluginsEnabled === false) {
|
||||
return []
|
||||
}
|
||||
|
||||
const { plugins } = discoverInstalledPlugins({
|
||||
enabledPluginsOverride: options?.enabledPluginsOverride,
|
||||
})
|
||||
|
||||
const pluginDefinitions = {
|
||||
...loadPluginCommands(plugins),
|
||||
...loadPluginSkillsAsCommands(plugins),
|
||||
}
|
||||
const pluginDefinitions = discoverPluginCommandDefinitions(options)
|
||||
|
||||
return Object.entries(pluginDefinitions).map(([name, definition]) => ({
|
||||
name,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { formatLoadedCommand } from "./command-output-formatter"
|
||||
import type { CommandInfo } from "./types"
|
||||
|
||||
describe("command output formatter", () => {
|
||||
describe("#given command template includes argument placeholders", () => {
|
||||
it("#then replaces both placeholder forms", async () => {
|
||||
// given
|
||||
const command: CommandInfo = {
|
||||
name: "daplug:templated",
|
||||
metadata: {
|
||||
name: "daplug:templated",
|
||||
description: "Templated plugin command",
|
||||
},
|
||||
content: "Echo $ARGUMENTS and ${user_message}.",
|
||||
scope: "plugin",
|
||||
}
|
||||
|
||||
// when
|
||||
const output = await formatLoadedCommand(command, "ship it")
|
||||
|
||||
// then
|
||||
expect(output).toContain("Echo ship it and ship it.")
|
||||
expect(output).not.toContain("$ARGUMENTS")
|
||||
expect(output).not.toContain("${user_message}")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -49,7 +49,9 @@ export async function formatLoadedCommand(
|
||||
|
||||
let finalContent = resolvedContent.trim()
|
||||
if (userMessage) {
|
||||
finalContent = finalContent.replace(/\$\{user_message\}/g, userMessage)
|
||||
finalContent = finalContent
|
||||
.replace(/\$\{user_message\}/g, userMessage)
|
||||
.replace(/\$ARGUMENTS/g, userMessage)
|
||||
}
|
||||
|
||||
sections.push(finalContent)
|
||||
|
||||
Reference in New Issue
Block a user