Bare /gsd and /gsd next now check for a remote auto-mode session via readSessionLockData before attempting to start step-mode. If another process holds the lock, a steering menu is shown instead of competing for the lock and killing the running session. Also fixes the guided-flow "all slices discussed" message to detect active auto-mode and direct users to /gsd status instead of bare /gsd. Closes #1507 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c2d46a951b
commit
eb2939760f
2 changed files with 43 additions and 2 deletions
|
|
@ -48,6 +48,7 @@ import { computeProgressScore, formatProgressLine } from "./progress-score.js";
|
|||
import { runEnvironmentChecks } from "./doctor-environment.js";
|
||||
import { handleLogs } from "./commands-logs.js";
|
||||
import { handleStart, handleTemplates, getTemplateCompletions } from "./commands-workflow-templates.js";
|
||||
import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
|
||||
|
||||
|
||||
/** Resolve the effective project root, accounting for worktree paths. */
|
||||
|
|
@ -69,6 +70,39 @@ export function projectRoot(): string {
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if another process holds the auto-mode session lock.
|
||||
* Returns the lock data if a remote session is alive, null otherwise.
|
||||
*/
|
||||
function getRemoteAutoSession(basePath: string): { pid: number } | null {
|
||||
const lockData = readSessionLockData(basePath);
|
||||
if (!lockData) return null;
|
||||
if (lockData.pid === process.pid) return null;
|
||||
if (!isSessionLockProcessAlive(lockData)) return null;
|
||||
return { pid: lockData.pid };
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a steering menu when auto-mode is running in another process.
|
||||
* Returns true if a remote session was detected (caller should return early).
|
||||
*/
|
||||
function notifyRemoteAutoActive(ctx: ExtensionCommandContext, basePath: string): boolean {
|
||||
const remote = getRemoteAutoSession(basePath);
|
||||
if (!remote) return false;
|
||||
ctx.ui.notify(
|
||||
`Auto-mode is running in another process (PID ${remote.pid}).\n` +
|
||||
`Use these commands to interact with it:\n` +
|
||||
` /gsd status — check progress\n` +
|
||||
` /gsd discuss — discuss architecture decisions\n` +
|
||||
` /gsd queue — queue the next milestone\n` +
|
||||
` /gsd steer — apply an override to active work\n` +
|
||||
` /gsd capture — fire-and-forget thought\n` +
|
||||
` /gsd stop — stop auto-mode`,
|
||||
"warning",
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function registerGSDCommand(pi: ExtensionAPI): void {
|
||||
pi.registerCommand("gsd", {
|
||||
description: "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|visualize|queue|quick|capture|triage|dispatch|history|undo|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|update",
|
||||
|
|
@ -512,6 +546,7 @@ export async function handleGSDCommand(
|
|||
await handleDryRun(ctx, projectRoot());
|
||||
return;
|
||||
}
|
||||
if (notifyRemoteAutoActive(ctx, projectRoot())) return;
|
||||
const verboseMode = trimmed.includes("--verbose");
|
||||
const debugMode = trimmed.includes("--debug");
|
||||
if (debugMode) enableDebug(projectRoot());
|
||||
|
|
@ -906,7 +941,7 @@ Examples:
|
|||
}
|
||||
|
||||
if (trimmed === "") {
|
||||
// Bare /gsd defaults to step mode
|
||||
if (notifyRemoteAutoActive(ctx, projectRoot())) return;
|
||||
await startAuto(ctx, pi, projectRoot(), false, { step: true });
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from "./paths.js";
|
||||
import { join } from "node:path";
|
||||
import { readFileSync, existsSync, mkdirSync, readdirSync, rmSync, unlinkSync } from "node:fs";
|
||||
import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
|
||||
import { nativeIsRepo, nativeInit } from "./native-git-bridge.js";
|
||||
import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
|
||||
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
||||
|
|
@ -516,8 +517,13 @@ export async function showDiscuss(
|
|||
// If all pending slices are discussed, notify and exit instead of looping
|
||||
const allDiscussed = pendingSlices.every(s => discussedMap.get(s.id));
|
||||
if (allDiscussed) {
|
||||
const lockData = readSessionLockData(basePath);
|
||||
const remoteAutoRunning = lockData && lockData.pid !== process.pid && isSessionLockProcessAlive(lockData);
|
||||
const nextStep = remoteAutoRunning
|
||||
? "Auto-mode is already running — use /gsd status to check progress."
|
||||
: "Run /gsd to start planning.";
|
||||
ctx.ui.notify(
|
||||
`All ${pendingSlices.length} slices discussed. Run /gsd to start planning.`,
|
||||
`All ${pendingSlices.length} slices discussed. ${nextStep}`,
|
||||
"info",
|
||||
);
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue