mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 13:55:50 +00:00
* feat: 适配 zed acp 协议 * docs: 完善 acp 文档 * feat: integrate feature branches + daemon/job 命令层级化 + 跨平台后台引擎 Cherry-picked from origin/lint/preview (637c908), excluding lint-only changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: correct detectMimeFromBase64 to decode raw bytes from base64 Cherry-picked from origin/lint/preview (ee36954). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: daemon 子进程 spawn 跨平台修复 + CliLaunchSpec 集中化重构 Cherry-picked from origin/lint/preview (c5f52cd), excluding lint-only formatting changes. - 新建 src/utils/cliLaunch.ts: 集中化 CLI 子进程启动层 - 修复 --daemon-worker=kind 等号格式解析 - 修复 daemon/bg fast path 缺少 setShellIfWindows() - 修复 checkPathExists 用 existsSync 替代 execSync('dir') - 7 个 spawn 站点迁移到 CliLaunchSpec Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: merge tsconfig.base.json into tsconfig.json with full compiler options The cherry-pick from637c908dropped jsx/strict/etc settings when removing tsconfig.base.json. This commit restores them in a single tsconfig.json. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: merge tsconfig.base.json into tsconfig.json with full compiler options The cherry-pick from637c908dropped jsx/strict/etc settings when removing tsconfig.base.json. This commit restores them in a single tsconfig.json. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
126 lines
3.4 KiB
TypeScript
126 lines
3.4 KiB
TypeScript
import type { Command, LocalCommandCall } from '../types/command.js'
|
|
import {
|
|
formatAutonomyFlowDetail,
|
|
formatAutonomyFlowsList,
|
|
formatAutonomyFlowsStatus,
|
|
getAutonomyFlowById,
|
|
listAutonomyFlows,
|
|
requestManagedAutonomyFlowCancel,
|
|
} from '../utils/autonomyFlows.js'
|
|
import {
|
|
formatAutonomyRunsList,
|
|
formatAutonomyRunsStatus,
|
|
listAutonomyRuns,
|
|
markAutonomyRunCancelled,
|
|
resumeManagedAutonomyFlowPrompt,
|
|
} from '../utils/autonomyRuns.js'
|
|
import {
|
|
enqueuePendingNotification,
|
|
removeByFilter,
|
|
} from '../utils/messageQueueManager.js'
|
|
|
|
function parseRunsLimit(raw?: string): number {
|
|
const parsed = Number.parseInt(raw ?? '', 10)
|
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
return 10
|
|
}
|
|
return Math.min(parsed, 50)
|
|
}
|
|
|
|
const call: LocalCommandCall = async (args: string) => {
|
|
const [subcommand = 'status', arg1, arg2] = args.trim().split(/\s+/, 3)
|
|
const runs = await listAutonomyRuns()
|
|
const flows = await listAutonomyFlows()
|
|
|
|
if (subcommand === 'runs') {
|
|
return {
|
|
type: 'text',
|
|
value: formatAutonomyRunsList(runs, parseRunsLimit(arg1)),
|
|
}
|
|
}
|
|
|
|
if (subcommand === 'flows') {
|
|
return {
|
|
type: 'text',
|
|
value: formatAutonomyFlowsList(flows, parseRunsLimit(arg1)),
|
|
}
|
|
}
|
|
|
|
if (subcommand === 'flow') {
|
|
if (arg1 === 'cancel') {
|
|
const flowId = arg2 ?? ''
|
|
const cancelled = await requestManagedAutonomyFlowCancel({ flowId })
|
|
if (!cancelled) {
|
|
return {
|
|
type: 'text',
|
|
value: 'Autonomy flow not found.',
|
|
}
|
|
}
|
|
if (!cancelled.accepted) {
|
|
return {
|
|
type: 'text',
|
|
value: `Autonomy flow ${flowId} is already terminal (${cancelled.flow.status}).`,
|
|
}
|
|
}
|
|
const removed = removeByFilter(cmd => cmd.autonomy?.flowId === flowId)
|
|
for (const command of removed) {
|
|
if (command.autonomy?.runId) {
|
|
await markAutonomyRunCancelled(command.autonomy.runId)
|
|
}
|
|
}
|
|
return {
|
|
type: 'text',
|
|
value:
|
|
cancelled.flow.status === 'running'
|
|
? `Cancellation requested for flow ${flowId}. The current step is still running, and no new steps will be started.`
|
|
: `Cancelled flow ${flowId}. Removed ${removed.length} queued step(s).`,
|
|
}
|
|
}
|
|
|
|
if (arg1 === 'resume') {
|
|
const flowId = arg2 ?? ''
|
|
const command = await resumeManagedAutonomyFlowPrompt({ flowId })
|
|
if (!command) {
|
|
return {
|
|
type: 'text',
|
|
value: 'Autonomy flow is not waiting or was not found.',
|
|
}
|
|
}
|
|
enqueuePendingNotification(command)
|
|
return {
|
|
type: 'text',
|
|
value: `Queued the next managed step for flow ${flowId}.`,
|
|
}
|
|
}
|
|
|
|
return {
|
|
type: 'text',
|
|
value: formatAutonomyFlowDetail(await getAutonomyFlowById(arg1 ?? '')),
|
|
}
|
|
}
|
|
|
|
if (subcommand !== 'status' && subcommand !== '') {
|
|
return {
|
|
type: 'text',
|
|
value:
|
|
'Usage: /autonomy [status|runs [limit]|flows [limit]|flow <id>|flow cancel <id>|flow resume <id>]',
|
|
}
|
|
}
|
|
|
|
return {
|
|
type: 'text',
|
|
value: [formatAutonomyRunsStatus(runs), formatAutonomyFlowsStatus(flows)].join('\n'),
|
|
}
|
|
}
|
|
|
|
const autonomy = {
|
|
type: 'local',
|
|
name: 'autonomy',
|
|
description:
|
|
'Inspect automatic autonomy runs recorded for proactive ticks and scheduled tasks',
|
|
supportsNonInteractive: true,
|
|
load: () => Promise.resolve({ call }),
|
|
} satisfies Command
|
|
|
|
export default autonomy
|