feat: add diff stats and archive actions to workspace sidebar
This commit is contained in:
@@ -1415,6 +1415,16 @@ export class ClaudeAgentClient implements AgentClient {
|
||||
} catch {
|
||||
this.claudePath = null;
|
||||
}
|
||||
if (this.claudePath) {
|
||||
try {
|
||||
const version = execSync(`${this.claudePath} --version`, { encoding: "utf8" }).trim();
|
||||
this.logger.info({ claudePath: this.claudePath, version }, "Resolved Claude binary");
|
||||
} catch {
|
||||
this.logger.info({ claudePath: this.claudePath }, "Resolved Claude binary (version unknown)");
|
||||
}
|
||||
} else {
|
||||
this.logger.warn("Claude binary not found via 'which claude'; SDK will use bundled binary");
|
||||
}
|
||||
}
|
||||
|
||||
async createSession(config: AgentSessionConfig): Promise<AgentSession> {
|
||||
|
||||
@@ -137,6 +137,7 @@ import {
|
||||
import { createAgentWorktree, runAsyncWorktreeBootstrap } from './worktree-bootstrap.js'
|
||||
import {
|
||||
getCheckoutDiff,
|
||||
getCheckoutShortstat,
|
||||
getCheckoutStatus,
|
||||
listBranchSuggestions,
|
||||
NotGitRepoError,
|
||||
@@ -5253,6 +5254,13 @@ export class Session {
|
||||
// Fall back to the persisted label if checkout metadata is unavailable.
|
||||
}
|
||||
|
||||
let diffStat: { additions: number; deletions: number } | null = null
|
||||
try {
|
||||
diffStat = await getCheckoutShortstat(workspace.cwd)
|
||||
} catch {
|
||||
// Non-critical — leave null on failure.
|
||||
}
|
||||
|
||||
return {
|
||||
id: workspace.workspaceId,
|
||||
projectId: workspace.projectId,
|
||||
@@ -5263,6 +5271,7 @@ export class Session {
|
||||
name: displayName,
|
||||
status: 'done',
|
||||
activityAt: null,
|
||||
diffStat,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1490,6 +1490,10 @@ export const WorkspaceDescriptorPayloadSchema = z.object({
|
||||
name: z.string(),
|
||||
status: WorkspaceStateBucketSchema,
|
||||
activityAt: z.string().nullable(),
|
||||
diffStat: z.object({
|
||||
additions: z.number(),
|
||||
deletions: z.number(),
|
||||
}).nullable().optional(),
|
||||
})
|
||||
|
||||
export const AgentUpdateMessageSchema = z.object({
|
||||
|
||||
@@ -1087,6 +1087,77 @@ export async function getCheckoutStatusLite(
|
||||
};
|
||||
}
|
||||
|
||||
export interface CheckoutShortstat {
|
||||
additions: number;
|
||||
deletions: number;
|
||||
}
|
||||
|
||||
export async function getCheckoutShortstat(
|
||||
cwd: string,
|
||||
context?: CheckoutContext
|
||||
): Promise<CheckoutShortstat | null> {
|
||||
try {
|
||||
await requireGitRepo(cwd);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
const configured = await getConfiguredBaseRefForCwd(cwd, context);
|
||||
const baseRef = configured.baseRef ?? (await resolveBaseRef(cwd));
|
||||
if (!baseRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentBranch = await getCurrentBranch(cwd);
|
||||
if (currentBranch === baseRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let mergeBase: string;
|
||||
try {
|
||||
const { stdout } = await execAsync(`git merge-base HEAD ${baseRef}`, {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
});
|
||||
mergeBase = stdout.trim();
|
||||
if (!mergeBase) {
|
||||
return null;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const { stdout } = await execAsync(`git diff --shortstat ${mergeBase}`, {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
});
|
||||
const text = stdout.trim();
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let additions = 0;
|
||||
let deletions = 0;
|
||||
const addMatch = text.match(/(\d+)\s+insertion/);
|
||||
if (addMatch) {
|
||||
additions = Number.parseInt(addMatch[1]!, 10);
|
||||
}
|
||||
const delMatch = text.match(/(\d+)\s+deletion/);
|
||||
if (delMatch) {
|
||||
deletions = Number.parseInt(delMatch[1]!, 10);
|
||||
}
|
||||
|
||||
if (additions === 0 && deletions === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { additions, deletions };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCheckoutDiff(
|
||||
cwd: string,
|
||||
compare: CheckoutDiffCompare,
|
||||
|
||||
Reference in New Issue
Block a user