diff --git a/src/cli/main.js b/src/cli/main.js index 3836c67..208c8e9 100755 --- a/src/cli/main.js +++ b/src/cli/main.js @@ -48,13 +48,17 @@ const { AGENTS_MARKER_END, GITIGNORE_MARKER_START, GITIGNORE_MARKER_END, + SHARED_VSCODE_SETTINGS_RELATIVE, + REPO_SCAN_IGNORED_FOLDERS_SETTING, AGENT_WORKTREE_RELATIVE_DIRS, + MANAGED_REPO_SCAN_IGNORED_FOLDERS, MANAGED_GITIGNORE_PATHS, REPO_SCAFFOLD_DIRECTORIES, OMX_SCAFFOLD_DIRECTORIES, OMX_SCAFFOLD_FILES, TARGETED_FORCEABLE_MANAGED_PATHS, DEPRECATED_COMMAND_ALIASES, + envFlagIsTruthy, defaultAgentWorktreeRelativeDir, AI_SETUP_PROMPT, AI_SETUP_COMMANDS, @@ -123,15 +127,6 @@ let sandboxApi; let toolchainApi; let finishApi; -const SHARED_VSCODE_SETTINGS_RELATIVE = path.posix.join('.vscode', 'settings.json'); -const REPO_SCAN_IGNORED_FOLDERS_SETTING = 'git.repositoryScanIgnoredFolders'; -const MANAGED_REPO_SCAN_IGNORED_FOLDERS = [ - '.omx/agent-worktrees', - '**/.omx/agent-worktrees', - '.omc/agent-worktrees', - '**/.omc/agent-worktrees', -]; - function getSandboxApi() { if (!sandboxApi) { sandboxApi = sandboxModule.createSandboxApi({ @@ -1080,6 +1075,10 @@ function protectedBaseSandboxWorktreePath(repoRoot, branchName) { return path.join(repoRoot, defaultAgentWorktreeRelativeDir(), branchName.replace(/\//g, '__')); } +function gitRefExists(repoRoot, ref) { + return run('git', ['-C', repoRoot, 'show-ref', '--verify', '--quiet', ref]).status === 0; +} + function resolveProtectedBaseSandboxStartRef(repoRoot, baseBranch) { run('git', ['-C', repoRoot, 'fetch', 'origin', baseBranch, '--quiet'], { timeout: 20_000 }); if (gitRefExists(repoRoot, `refs/remotes/origin/${baseBranch}`)) { @@ -3273,11 +3272,11 @@ function parseNpmVersionOutput(stdout) { } function checkForGuardexUpdate() { - if (parseBooleanLike(process.env.GUARDEX_SKIP_UPDATE_CHECK) === true) { + if (envFlagIsTruthy(process.env.GUARDEX_SKIP_UPDATE_CHECK)) { return { checked: false, reason: 'disabled' }; } - const forceCheck = parseBooleanLike(process.env.GUARDEX_FORCE_UPDATE_CHECK) === true; + const forceCheck = envFlagIsTruthy(process.env.GUARDEX_FORCE_UPDATE_CHECK); if (!forceCheck && !isInteractiveTerminal()) { return { checked: false, reason: 'non-interactive' }; } @@ -3397,12 +3396,11 @@ function restartIntoUpdatedGuardex(expectedVersion) { } function checkForOpenSpecPackageUpdate() { - if (parseBooleanLike(process.env.GUARDEX_SKIP_OPENSPEC_UPDATE_CHECK) === true) { + if (envFlagIsTruthy(process.env.GUARDEX_SKIP_OPENSPEC_UPDATE_CHECK)) { return { checked: false, reason: 'disabled' }; } - const forceCheck = - parseBooleanLike(process.env.GUARDEX_FORCE_OPENSPEC_UPDATE_CHECK) === true; + const forceCheck = envFlagIsTruthy(process.env.GUARDEX_FORCE_OPENSPEC_UPDATE_CHECK); if (!forceCheck && !isInteractiveTerminal()) { return { checked: false, reason: 'non-interactive' }; } @@ -3627,10 +3625,6 @@ function installGlobalToolchain(options) { return getToolchainApi().installGlobalToolchain(options); } -function gitRefExists(repoRoot, refName) { - return gitRun(repoRoot, ['show-ref', '--verify', '--quiet', refName], { allowFailure: true }).status === 0; -} - function findStaleLockPaths(repoRoot, locks) { const stale = []; @@ -4915,16 +4909,9 @@ function setup(rawArgs) { dryRun: perRepoOptions.dryRun, }); printScanResult(scanResult, false); - if (autoFinishSummary.enabled) { - console.log( - `[${TOOL_NAME}] Auto-finish sweep (base=${currentBaseBranch}): attempted=${autoFinishSummary.attempted}, completed=${autoFinishSummary.completed}, skipped=${autoFinishSummary.skipped}, failed=${autoFinishSummary.failed}`, - ); - for (const detail of autoFinishSummary.details) { - console.log(`[${TOOL_NAME}] ${detail}`); - } - } else if (autoFinishSummary.details.length > 0) { - console.log(`[${TOOL_NAME}] ${autoFinishSummary.details[0]}`); - } + printAutoFinishSummary(autoFinishSummary, { + baseBranch: currentBaseBranch, + }); printSetupRepoHints(scanResult.repoRoot, currentBaseBranch, repoLabel); aggregateErrors += scanResult.errors; diff --git a/src/context.js b/src/context.js index 0471617..2530708 100644 --- a/src/context.js +++ b/src/context.js @@ -71,7 +71,7 @@ const REQUIRED_SYSTEM_TOOLS = [ }, ]; const MAINTAINER_RELEASE_REPO = path.resolve( - process.env.GUARDEX_RELEASE_REPO || path.resolve(PACKAGE_ROOT), + process.env.GUARDEX_RELEASE_REPO || PACKAGE_ROOT, ); const NPM_BIN = process.env.GUARDEX_NPM_BIN || 'npm'; const OPENSPEC_BIN = process.env.GUARDEX_OPENSPEC_BIN || 'openspec'; @@ -242,10 +242,18 @@ const GITIGNORE_MARKER_START = '# multiagent-safety:START'; const GITIGNORE_MARKER_END = '# multiagent-safety:END'; const CODEX_WORKTREE_RELATIVE_DIR = path.join('.omx', 'agent-worktrees'); const CLAUDE_WORKTREE_RELATIVE_DIR = path.join('.omc', 'agent-worktrees'); +const SHARED_VSCODE_SETTINGS_RELATIVE = path.posix.join('.vscode', 'settings.json'); +const REPO_SCAN_IGNORED_FOLDERS_SETTING = 'git.repositoryScanIgnoredFolders'; const AGENT_WORKTREE_RELATIVE_DIRS = [ CODEX_WORKTREE_RELATIVE_DIR, CLAUDE_WORKTREE_RELATIVE_DIR, ]; +const MANAGED_REPO_SCAN_IGNORED_FOLDERS = [ + '.omx/agent-worktrees', + '**/.omx/agent-worktrees', + '.omc/agent-worktrees', + '**/.omc/agent-worktrees', +]; const MANAGED_GITIGNORE_PATHS = [ '.omx/', '.omc/', @@ -483,7 +491,10 @@ module.exports = { GITIGNORE_MARKER_END, CODEX_WORKTREE_RELATIVE_DIR, CLAUDE_WORKTREE_RELATIVE_DIR, + SHARED_VSCODE_SETTINGS_RELATIVE, + REPO_SCAN_IGNORED_FOLDERS_SETTING, AGENT_WORKTREE_RELATIVE_DIRS, + MANAGED_REPO_SCAN_IGNORED_FOLDERS, MANAGED_GITIGNORE_PATHS, REPO_SCAFFOLD_DIRECTORIES, OMX_SCAFFOLD_DIRECTORIES, diff --git a/test/metadata.test.js b/test/metadata.test.js index 18340da..397da9e 100644 --- a/test/metadata.test.js +++ b/test/metadata.test.js @@ -156,10 +156,11 @@ test('package manifest ships the extracted src runtime', () => { assert.match(pkg.files.join('\n'), /^src$/m); }); -test('doctor CLI parser stays in src/cli args while dead legacy audit stubs stay removed from main runtime', () => { +test('doctor CLI parser stays in src/cli args while the main doctor command stays routable and dead legacy audit stubs stay removed', () => { const argsSource = fs.readFileSync(path.join(repoRoot, 'src', 'cli', 'args.js'), 'utf8'); const cliSource = fs.readFileSync(path.join(repoRoot, 'src', 'cli', 'main.js'), 'utf8'); assert.match(argsSource, /function parseDoctorArgs\(rawArgs(?:, options = \{\})?\)/); + assert.match(cliSource, /function doctor\(rawArgs\)/); assert.doesNotMatch(cliSource, /function doctorAudit\(rawArgs\)/); assert.doesNotMatch(cliSource, /function installMany\(rawArgs\)/); assert.doesNotMatch(cliSource, /function initWorkspace\(rawArgs\)/);