fix: allow notify reactions when auto is false, clean up reserved IDs on spawn failure
- Reactions with action: "notify" bypass the auto: false gate so merge-ready notifications fire for approved-and-green config - All spawn failure paths now delete the reserved session metadata file Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
65787f08e3
commit
07b3a553f7
|
|
@ -418,8 +418,11 @@ export function createLifecycleManager(deps: LifecycleManagerDeps): LifecycleMan
|
|||
? { ...globalReaction, ...projectReaction }
|
||||
: globalReaction;
|
||||
|
||||
if (reactionConfig && reactionConfig.auto !== false && reactionConfig.action) {
|
||||
await executeReaction(event, reactionKey, reactionConfig as ReactionConfig);
|
||||
if (reactionConfig && reactionConfig.action) {
|
||||
// auto: false skips automated agent actions but still allows notifications
|
||||
if (reactionConfig.auto !== false || reactionConfig.action === "notify") {
|
||||
await executeReaction(event, reactionKey, reactionConfig as ReactionConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -467,8 +470,10 @@ export function createLifecycleManager(deps: LifecycleManagerDeps): LifecycleMan
|
|||
const reactionKey = eventToReactionKey("summary.all_complete");
|
||||
if (reactionKey) {
|
||||
const reactionConfig = config.reactions[reactionKey];
|
||||
if (reactionConfig && reactionConfig.auto !== false && reactionConfig.action) {
|
||||
await executeReaction(event, reactionKey, reactionConfig as ReactionConfig);
|
||||
if (reactionConfig && reactionConfig.action) {
|
||||
if (reactionConfig.auto !== false || reactionConfig.action === "notify") {
|
||||
await executeReaction(event, reactionKey, reactionConfig as ReactionConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,28 +192,38 @@ export function createSessionManager(deps: SessionManagerDeps): SessionManager {
|
|||
// Create workspace (if workspace plugin is available)
|
||||
let workspacePath = project.path;
|
||||
if (plugins.workspace) {
|
||||
const wsInfo = await plugins.workspace.create({
|
||||
projectId: spawnConfig.projectId,
|
||||
project,
|
||||
sessionId,
|
||||
branch,
|
||||
});
|
||||
workspacePath = wsInfo.path;
|
||||
try {
|
||||
const wsInfo = await plugins.workspace.create({
|
||||
projectId: spawnConfig.projectId,
|
||||
project,
|
||||
sessionId,
|
||||
branch,
|
||||
});
|
||||
workspacePath = wsInfo.path;
|
||||
|
||||
// Run post-create hooks — clean up workspace on failure (skip if project root)
|
||||
if (plugins.workspace.postCreate) {
|
||||
try {
|
||||
await plugins.workspace.postCreate(wsInfo, project);
|
||||
} catch (err) {
|
||||
if (workspacePath !== project.path) {
|
||||
try {
|
||||
await plugins.workspace.destroy(workspacePath);
|
||||
} catch {
|
||||
/* best effort */
|
||||
// Run post-create hooks — clean up workspace on failure
|
||||
if (plugins.workspace.postCreate) {
|
||||
try {
|
||||
await plugins.workspace.postCreate(wsInfo, project);
|
||||
} catch (err) {
|
||||
if (workspacePath !== project.path) {
|
||||
try {
|
||||
await plugins.workspace.destroy(workspacePath);
|
||||
} catch {
|
||||
/* best effort */
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
} catch (err) {
|
||||
// Clean up reserved session ID on workspace failure
|
||||
try {
|
||||
deleteMetadata(config.dataDir, sessionId, false);
|
||||
} catch {
|
||||
/* best effort */
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +252,7 @@ export function createSessionManager(deps: SessionManagerDeps): SessionManager {
|
|||
},
|
||||
});
|
||||
} catch (err) {
|
||||
// Clean up workspace if agent config or runtime creation failed
|
||||
// Clean up workspace and reserved ID if agent config or runtime creation failed
|
||||
if (plugins.workspace && workspacePath !== project.path) {
|
||||
try {
|
||||
await plugins.workspace.destroy(workspacePath);
|
||||
|
|
@ -250,6 +260,11 @@ export function createSessionManager(deps: SessionManagerDeps): SessionManager {
|
|||
/* best effort */
|
||||
}
|
||||
}
|
||||
try {
|
||||
deleteMetadata(config.dataDir, sessionId, false);
|
||||
} catch {
|
||||
/* best effort */
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue