feat: 注册所有新命令到命令系统和工具注册表

- commands.ts: 注册所有新命令(memory-stores、vault、schedule 等),
  移除 require() 动态加载,统一为 ESM import
- tools.ts: 注册 LocalMemoryRecallTool、VaultHttpFetchTool
- 补充命令测试(bridge-kick、commit、commit-push-pr、init-verifiers)
- 补充工具测试(AgentTool、RemoteTrigger、SkillTool、WebFetch、WebSearch)
- 集成测试:autonomy-lifecycle-user-flow 更新
- 探测脚本和功能文档

Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-05-09 23:04:39 +08:00
parent efaf4afd9c
commit 6a182e45b3
25 changed files with 3148 additions and 94 deletions

View File

@@ -0,0 +1,67 @@
import { describe, expect, test } from 'bun:test'
import {
MAX_LISTING_DESC_CHARS,
formatCommandsWithinBudget,
} from '../prompt.js'
import type { Command } from 'src/types/command.js'
// Helper to build a minimal prompt Command
function makeCmd(
name: string,
description: string,
whenToUse?: string,
): Command {
return {
type: 'prompt',
name,
description,
whenToUse,
hasUserSpecifiedDescription: false,
allowedTools: [],
disableModelInvocation: false,
userInvocable: true,
isHidden: false,
progressMessage: 'running',
userFacingName: () => name,
source: 'userSettings',
loadedFrom: 'skills',
async getPromptForCommand() {
return [{ type: 'text' as const, text: '' }]
},
} as unknown as Command
}
describe('MAX_LISTING_DESC_CHARS', () => {
test('cap is 1536 (not the old 250)', () => {
// Regression: v2.1.117 upgraded the per-entry description cap from 250 → 1536
expect(MAX_LISTING_DESC_CHARS).toBe(1536)
})
test('description longer than 1536 chars is truncated', () => {
const longDesc = 'x'.repeat(2000)
const cmd = makeCmd('test-skill', longDesc)
const result = formatCommandsWithinBudget([cmd], 200_000)
// Should contain truncation ellipsis and must not contain the full 2000-char desc
expect(result).toContain('…')
// The entry itself should not exceed 1536 chars of description content
// (the - name: prefix adds overhead we ignore here)
expect(result.length).toBeLessThan(2000)
})
test('description of exactly 1536 chars is NOT truncated', () => {
const desc = 'a'.repeat(1536)
const cmd = makeCmd('my-skill', desc)
const result = formatCommandsWithinBudget([cmd], 200_000)
expect(result).not.toContain('…')
expect(result).toContain(desc)
})
test('description longer than 250 but shorter than 1536 is NOT truncated by the cap', () => {
// Regression: with old cap=250, a 300-char description would be truncated.
// With cap=1536 it must pass through intact.
const desc = 'b'.repeat(300)
const cmd = makeCmd('another-skill', desc)
const result = formatCommandsWithinBudget([cmd], 200_000)
expect(result).toContain(desc)
})
})

View File

@@ -26,7 +26,8 @@ export const DEFAULT_CHAR_BUDGET = 8_000 // Fallback: 1% of 200k × 4
// full content on invoke, so verbose whenToUse strings waste turn-1 cache_creation
// tokens without improving match rate. Applies to all entries, including bundled,
// since the cap is generous enough to preserve the core use case.
export const MAX_LISTING_DESC_CHARS = 250
// v2.1.117: raised from 250 → 1536 to allow richer skill descriptions.
export const MAX_LISTING_DESC_CHARS = 1536
export function getCharBudget(contextWindowTokens?: number): number {
if (Number(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET)) {