fix(commands): 修复路由顺序导致 /content 端点被遮蔽的问题
- 将 /:name{.+}/execute 和 /:name{.+}/content 路由移到 /:name{.+} 之前
- Hono 的 {.+} 模式会贪婪匹配,导致 /test/content 被解析为 name='test/content'
- 更新测试用例以正确测试 /content 端点功能
This commit is contained in:
@@ -275,54 +275,9 @@ commandsRouter.post('/reload', async (c) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /commands/:name - 获取命令详情
|
||||
* 使用 {.+} 匹配包含 / 的命令名(如 deploy/staging)
|
||||
*/
|
||||
commandsRouter.get('/:name{.+}', async (c) => {
|
||||
const name = c.req.param('name');
|
||||
const module = await initCommandModule();
|
||||
|
||||
if (!module) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'Command module not available',
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
|
||||
const registry = module.getCommandRegistry();
|
||||
const command = registry.get(name);
|
||||
|
||||
if (!command) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: `Command not found: ${name}`,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
// Return sanitized command info (exclude template for security)
|
||||
return c.json({
|
||||
success: true,
|
||||
data: {
|
||||
name: command.name,
|
||||
description: command.description,
|
||||
agent: command.agent,
|
||||
model: command.model,
|
||||
subtask: command.subtask,
|
||||
source: command.source,
|
||||
hasTemplate: !!command.template,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /commands/:name/execute - 执行命令(渲染模板)
|
||||
* 注意:带后缀的路由必须在 /:name{.+} 之前定义,否则会被 {.+} 匹配
|
||||
*/
|
||||
commandsRouter.post('/:name{.+}/execute', async (c) => {
|
||||
const name = c.req.param('name');
|
||||
@@ -381,6 +336,91 @@ commandsRouter.post('/:name{.+}/execute', async (c) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /commands/:name/content - 获取命令完整内容(包含 template)
|
||||
* 注意:带后缀的路由必须在 /:name{.+} 之前定义,否则会被 {.+} 匹配
|
||||
*/
|
||||
commandsRouter.get('/:name{.+}/content', async (c) => {
|
||||
const name = c.req.param('name');
|
||||
const module = await initCommandModule();
|
||||
|
||||
if (!module) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'Command module not available',
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
|
||||
const config = getConfig();
|
||||
const manager = module.createCommandManager(config.workdir);
|
||||
const result = await manager.getContent(name);
|
||||
|
||||
if (result.success) {
|
||||
return c.json({
|
||||
success: true,
|
||||
data: result.data,
|
||||
});
|
||||
} else {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: result.error,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /commands/:name - 获取命令详情
|
||||
* 使用 {.+} 匹配包含 / 的命令名(如 deploy/staging)
|
||||
* 注意:这个通用路由必须在所有带后缀的路由之后定义
|
||||
*/
|
||||
commandsRouter.get('/:name{.+}', async (c) => {
|
||||
const name = c.req.param('name');
|
||||
const module = await initCommandModule();
|
||||
|
||||
if (!module) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'Command module not available',
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
|
||||
const registry = module.getCommandRegistry();
|
||||
const command = registry.get(name);
|
||||
|
||||
if (!command) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: `Command not found: ${name}`,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
|
||||
// Return sanitized command info (exclude template for security)
|
||||
return c.json({
|
||||
success: true,
|
||||
data: {
|
||||
name: command.name,
|
||||
description: command.description,
|
||||
agent: command.agent,
|
||||
model: command.model,
|
||||
subtask: command.subtask,
|
||||
source: command.source,
|
||||
hasTemplate: !!command.template,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// CRUD 操作
|
||||
// ============================================================================
|
||||
@@ -437,43 +477,6 @@ commandsRouter.post('/', async (c) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /commands/:name/content - 获取命令完整内容(包含 template)
|
||||
*/
|
||||
commandsRouter.get('/:name{.+}/content', async (c) => {
|
||||
const name = c.req.param('name');
|
||||
const module = await initCommandModule();
|
||||
|
||||
if (!module) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'Command module not available',
|
||||
},
|
||||
503
|
||||
);
|
||||
}
|
||||
|
||||
const config = getConfig();
|
||||
const manager = module.createCommandManager(config.workdir);
|
||||
const result = await manager.getContent(name);
|
||||
|
||||
if (result.success) {
|
||||
return c.json({
|
||||
success: true,
|
||||
data: result.data,
|
||||
});
|
||||
} else {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
error: result.error,
|
||||
},
|
||||
404
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* PUT /commands/:name - 更新命令
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user