Fix agent close persistence, whitespace diff filtering, and diff param cleanup
- Persist snapshot before emitting closed agent to avoid data loss - Flush after branch rename so state hits disk immediately - Filter phantom whitespace-only files from ignore-whitespace diffs - Only include ignoreWhitespace param when true to keep payloads clean - Add createFeature test helper for AgentFeature construction
This commit is contained in:
@@ -2226,15 +2226,20 @@ export class DaemonClient {
|
|||||||
baseRef?: string;
|
baseRef?: string;
|
||||||
ignoreWhitespace?: boolean;
|
ignoreWhitespace?: boolean;
|
||||||
}): { mode: "uncommitted" | "base"; baseRef?: string; ignoreWhitespace?: boolean } {
|
}): { mode: "uncommitted" | "base"; baseRef?: string; ignoreWhitespace?: boolean } {
|
||||||
const ignoreWhitespace = compare.ignoreWhitespace === true;
|
|
||||||
if (compare.mode === "uncommitted") {
|
if (compare.mode === "uncommitted") {
|
||||||
return { mode: "uncommitted", ignoreWhitespace };
|
return compare.ignoreWhitespace === true
|
||||||
|
? { mode: "uncommitted", ignoreWhitespace: true }
|
||||||
|
: { mode: "uncommitted" };
|
||||||
}
|
}
|
||||||
const trimmedBaseRef = compare.baseRef?.trim();
|
const trimmedBaseRef = compare.baseRef?.trim();
|
||||||
if (!trimmedBaseRef) {
|
if (!trimmedBaseRef) {
|
||||||
return { mode: "base", ignoreWhitespace };
|
return compare.ignoreWhitespace === true
|
||||||
|
? { mode: "base", ignoreWhitespace: true }
|
||||||
|
: { mode: "base" };
|
||||||
}
|
}
|
||||||
return { mode: "base", baseRef: trimmedBaseRef, ignoreWhitespace };
|
return compare.ignoreWhitespace === true
|
||||||
|
? { mode: "base", baseRef: trimmedBaseRef, ignoreWhitespace: true }
|
||||||
|
: { mode: "base", baseRef: trimmedBaseRef };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCheckoutDiff(
|
async getCheckoutDiff(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { AgentManager } from "./agent-manager.js";
|
|||||||
import { AgentStorage } from "./agent-storage.js";
|
import { AgentStorage } from "./agent-storage.js";
|
||||||
import type {
|
import type {
|
||||||
AgentClient,
|
AgentClient,
|
||||||
|
AgentFeature,
|
||||||
AgentLaunchContext,
|
AgentLaunchContext,
|
||||||
AgentPersistenceHandle,
|
AgentPersistenceHandle,
|
||||||
AgentRunResult,
|
AgentRunResult,
|
||||||
@@ -47,6 +48,15 @@ const TEST_CAPABILITIES = {
|
|||||||
supportsToolInvocations: false,
|
supportsToolInvocations: false,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
function createFeature(args: { id: string; label: string; value: boolean }): AgentFeature {
|
||||||
|
return {
|
||||||
|
type: "toggle",
|
||||||
|
id: args.id,
|
||||||
|
label: args.label,
|
||||||
|
value: args.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function seedWorkspace(
|
async function seedWorkspace(
|
||||||
database: PaseoDatabaseHandle,
|
database: PaseoDatabaseHandle,
|
||||||
options: { directory: string },
|
options: { directory: string },
|
||||||
|
|||||||
@@ -725,7 +725,8 @@ export class AgentManager {
|
|||||||
const closedAgent = this.prepareAgentForClosure(agent, "agent closed");
|
const closedAgent = this.prepareAgentForClosure(agent, "agent closed");
|
||||||
await agent.session.close();
|
await agent.session.close();
|
||||||
this.timelineStore.delete(agentId);
|
this.timelineStore.delete(agentId);
|
||||||
this.emitClosedAgent(closedAgent);
|
await this.persistSnapshot(closedAgent);
|
||||||
|
this.emitClosedAgent(closedAgent, { persist: false });
|
||||||
this.logger.trace({ agentId }, "closeAgent: completed");
|
this.logger.trace({ agentId }, "closeAgent: completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1944,8 +1945,8 @@ export class AgentManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitClosedAgent(agent: ManagedAgentClosed): void {
|
private emitClosedAgent(agent: ManagedAgentClosed, options?: { persist?: boolean }): void {
|
||||||
this.emitState(agent);
|
this.emitState(agent, options);
|
||||||
}
|
}
|
||||||
private subscribeToSession(agent: ActiveManagedAgent): void {
|
private subscribeToSession(agent: ActiveManagedAgent): void {
|
||||||
if (agent.unsubscribeSession) {
|
if (agent.unsubscribeSession) {
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ export async function generateAndApplyAgentMetadata(
|
|||||||
try {
|
try {
|
||||||
await renameCurrentBranchImpl(options.cwd, normalizedBranch);
|
await renameCurrentBranchImpl(options.cwd, normalizedBranch);
|
||||||
options.agentManager.notifyAgentState(options.agentId);
|
options.agentManager.notifyAgentState(options.agentId);
|
||||||
|
await options.agentManager.flush();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
options.logger.warn(
|
options.logger.warn(
|
||||||
{ err: error, agentId: options.agentId, branch: normalizedBranch },
|
{ err: error, agentId: options.agentId, branch: normalizedBranch },
|
||||||
|
|||||||
@@ -1547,6 +1547,16 @@ export async function getCheckoutDiff(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `git diff -w --name-status` can still surface paths whose only changes were
|
||||||
|
// whitespace. Skip those empty tracked entries so callers don't see phantom files.
|
||||||
|
if (
|
||||||
|
ignoreWhitespace &&
|
||||||
|
change.status.startsWith("M") &&
|
||||||
|
(!stat || (!stat.isBinary && stat.additions === 0 && stat.deletions === 0))
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
structured.push({
|
structured.push({
|
||||||
path: change.path,
|
path: change.path,
|
||||||
isNew: change.isNew,
|
isNew: change.isNew,
|
||||||
|
|||||||
Reference in New Issue
Block a user