mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 08:45:50 +00:00
fixup: 处理 PR #386 review 中尚未覆盖的 4 项
- src/cli/print.ts: cron onFire 改用 createAutonomyQueuedPromptIfNoActiveSource 并以 prompt 文本作为 sourceId,避免同一定时提示在前一次 run 仍活跃时被重复 入队叠加;顺手移除 4 个已没人引用的 dead import (commitAutonomyQueuedPrompt / prepareAutonomyTurnPrompt / markAutonomyRunCancelled / createAutonomyQueuedPrompt) - src/services/compact/postCompactCleanup.ts: 在 void import().then() 处加 注释,明确 sweepFileContentCache 是有意的 fire-and-forget,函数对外保持 同步签名是设计而非疏忽 - src/utils/autonomyFlows.ts: 给 selectPersistedAutonomyFlows 的两阶段排序 加文档注释(先按 active+updatedAt 选 top-N,再统一按 updatedAt 重排) - tests/integration/autonomy-lifecycle-user-flow.test.ts: stderr 断言失败时 把实际 stderr 内容写进 message,方便 CI 失败时定位
This commit is contained in:
@@ -321,11 +321,8 @@ import {
|
|||||||
} from 'src/utils/queryProfiler.js'
|
} from 'src/utils/queryProfiler.js'
|
||||||
import { asSessionId } from 'src/types/ids.js'
|
import { asSessionId } from 'src/types/ids.js'
|
||||||
import {
|
import {
|
||||||
commitAutonomyQueuedPrompt,
|
|
||||||
createAutonomyQueuedPrompt,
|
|
||||||
createAutonomyQueuedPromptIfNoActiveSource,
|
createAutonomyQueuedPromptIfNoActiveSource,
|
||||||
createProactiveAutonomyCommands,
|
createProactiveAutonomyCommands,
|
||||||
markAutonomyRunCancelled,
|
|
||||||
markAutonomyRunFailed,
|
markAutonomyRunFailed,
|
||||||
} from 'src/utils/autonomyRuns.js'
|
} from 'src/utils/autonomyRuns.js'
|
||||||
import {
|
import {
|
||||||
@@ -333,7 +330,6 @@ import {
|
|||||||
claimConsumableQueuedAutonomyCommands,
|
claimConsumableQueuedAutonomyCommands,
|
||||||
finalizeAutonomyCommandsForTurn,
|
finalizeAutonomyCommandsForTurn,
|
||||||
} from 'src/utils/autonomyQueueLifecycle.js'
|
} from 'src/utils/autonomyQueueLifecycle.js'
|
||||||
import { prepareAutonomyTurnPrompt } from 'src/utils/autonomyAuthority.js'
|
|
||||||
import { jsonStringify } from '../utils/slowOperations.js'
|
import { jsonStringify } from '../utils/slowOperations.js'
|
||||||
import { skillChangeDetector } from '../utils/skills/skillChangeDetector.js'
|
import { skillChangeDetector } from '../utils/skills/skillChangeDetector.js'
|
||||||
import { getCommands, clearCommandsCache } from '../commands.js'
|
import { getCommands, clearCommandsCache } from '../commands.js'
|
||||||
@@ -2827,17 +2823,22 @@ function runHeadlessStreaming(
|
|||||||
onFire: prompt => {
|
onFire: prompt => {
|
||||||
if (inputClosed) return
|
if (inputClosed) return
|
||||||
void (async () => {
|
void (async () => {
|
||||||
const prepared = await prepareAutonomyTurnPrompt({
|
// Use the prompt itself as the dedup source: legacy KAIROS-style
|
||||||
|
// cron entries fire the same prompt repeatedly, and without a
|
||||||
|
// dedicated task id the prompt text is what uniquely identifies
|
||||||
|
// the entry. Without source-dedup, repeated fires would stack
|
||||||
|
// additional runs while an earlier one is still active. Match the
|
||||||
|
// onFireTask branch below to keep the two paths consistent.
|
||||||
|
const command = await createAutonomyQueuedPromptIfNoActiveSource({
|
||||||
basePrompt: prompt,
|
basePrompt: prompt,
|
||||||
trigger: 'scheduled-task',
|
trigger: 'scheduled-task',
|
||||||
currentDir: cwd(),
|
currentDir: cwd(),
|
||||||
})
|
sourceId: prompt,
|
||||||
if (inputClosed) return
|
sourceLabel: prompt,
|
||||||
const command = await commitAutonomyQueuedPrompt({
|
|
||||||
prepared,
|
|
||||||
currentDir: cwd(),
|
|
||||||
workload: WORKLOAD_CRON,
|
workload: WORKLOAD_CRON,
|
||||||
|
shouldCreate: () => !inputClosed,
|
||||||
})
|
})
|
||||||
|
if (!command) return
|
||||||
if (inputClosed) {
|
if (inputClosed) {
|
||||||
await cancelQueuedAutonomyCommands({ commands: [command] })
|
await cancelQueuedAutonomyCommands({ commands: [command] })
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ export function runPostCompactCleanup(querySource?: QuerySource): void {
|
|||||||
// cacheUtils resets. See compactConversation() for full rationale.
|
// cacheUtils resets. See compactConversation() for full rationale.
|
||||||
clearBetaTracingState()
|
clearBetaTracingState()
|
||||||
if (feature('COMMIT_ATTRIBUTION')) {
|
if (feature('COMMIT_ATTRIBUTION')) {
|
||||||
|
// Intentionally fire-and-forget: the file-content cache sweep is a
|
||||||
|
// best-effort memory release whose completion no caller depends on.
|
||||||
|
// Keeping `runPostCompactCleanup` synchronous lets compaction call sites
|
||||||
|
// (REPL post-compact handler, /compact command, autoCompact) finish their
|
||||||
|
// own state transitions without an extra microtask round-trip — the sweep
|
||||||
|
// catches up on the next event-loop tick.
|
||||||
void import('../../utils/attributionHooks.js').then(m =>
|
void import('../../utils/attributionHooks.js').then(m =>
|
||||||
m.sweepFileContentCache(),
|
m.sweepFileContentCache(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -170,6 +170,12 @@ function isManagedFlowStatusActive(status: AutonomyFlowStatus): boolean {
|
|||||||
function selectPersistedAutonomyFlows(
|
function selectPersistedAutonomyFlows(
|
||||||
flows: AutonomyFlowRecord[],
|
flows: AutonomyFlowRecord[],
|
||||||
): AutonomyFlowRecord[] {
|
): AutonomyFlowRecord[] {
|
||||||
|
// Two-phase sort. Phase 1: priority sort (active flows first, then by
|
||||||
|
// updatedAt desc) selects the AUTONOMY_FLOWS_MAX most-relevant records to
|
||||||
|
// retain — active flows are guaranteed a slot before any inactive flow is
|
||||||
|
// considered. Phase 2: re-sort the retained slice by updatedAt desc only,
|
||||||
|
// so the persisted file is in plain reverse-chronological order regardless
|
||||||
|
// of activity status. Listings/UI consume the persisted order directly.
|
||||||
const retained = flows
|
const retained = flows
|
||||||
.slice()
|
.slice()
|
||||||
.map(cloneFlowRecord)
|
.map(cloneFlowRecord)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ async function runAutonomyCli(args: string[]): Promise<string> {
|
|||||||
proc.exited,
|
proc.exited,
|
||||||
])
|
])
|
||||||
|
|
||||||
expect(stderr).toBe('')
|
expect(stderr, `unexpected stderr output:\n${stderr}`).toBe('')
|
||||||
expect(exitCode).toBe(0)
|
expect(exitCode, `non-zero exit ${exitCode}; stderr:\n${stderr}`).toBe(0)
|
||||||
return stdout
|
return stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user