Skip to content

feat(cli): Hydrate tool args from session defaults#264

Merged
cameroncooke merged 4 commits intomainfrom
feat/cli-session-defaults
Mar 7, 2026
Merged

feat(cli): Hydrate tool args from session defaults#264
cameroncooke merged 4 commits intomainfrom
feat/cli-session-defaults

Conversation

@cameroncooke
Copy link
Collaborator

Hydrate CLI tool arguments from configured session defaults and keep required flags dynamic at runtime.

This updates the CLI to fill in tool arguments from the same effective defaults source the MCP path already uses: the active named profile when one is selected, otherwise the unnamed/global defaults. When a matching default exists, the CLI no longer marks that argument as required in tool help. When no default exists, the usual missing-argument behavior remains unchanged.

This also adds a per-invocation
`--profile` override so a CLI command can resolve defaults from a named profile without mutating config or changing the active profile. Explicit flags still override defaults,
`--json` still wins over flags, and daemon-routed tools are included because hydration happens before invocation routing.

I kept the session-management tools hidden from the CLI surface, so this change makes session defaults readable by CLI commands but not mutable through CLI tool commands. I also extracted the merge/pruning logic into a shared helper so the CLI and MCP/session-aware paths stay aligned instead of drifting.

Use configured session defaults when building and executing CLI tool\ncommands so required flags become optional only when a matching\ndefault exists. Keep the normal missing-argument behavior when no\ndefault is available and keep session-management tools hidden from\nthe CLI surface.\n\nAdd a per-invocation --profile override so CLI commands can resolve\ndefaults from a named profile without mutating config or changing\nthe active profile. This keeps help output and invocation behavior\naligned while matching existing MCP profile semantics.\n\nCo-Authored-By: OpenAI <noreply@openai.com>
Download the universal AXe release archive for bundling on all\nplatforms before falling back to the legacy archive. This fixes\nCI failures when the release only publishes the universal asset\nname and keeps the existing fallback path for older releases.\n\nCo-Authored-By: OpenAI <noreply@openai.com>
@cameroncooke cameroncooke marked this pull request as ready for review March 7, 2026 20:31
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

Open in StackBlitz

npm i https://pkg.pr.new/xcodebuildmcp@264

commit: 68487c3

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Naive argv parser can mismatch yargs profile resolution
    • Made readProfileOverrideFromProcessArgv respect -- terminators and validate that profile values don't start with - to match yargs semantics.
  • ✅ Fixed: resolveActiveCliSessionDefaults exported but never used in production
    • Removed unused resolveActiveCliSessionDefaults export and updated test to use resolveCliSessionDefaults directly.

Create PR

Or push these changes by commenting:

@cursor push b45e5deb45
Preview (b45e5deb45)
diff --git a/src/cli/__tests__/session-defaults.test.ts b/src/cli/__tests__/session-defaults.test.ts
--- a/src/cli/__tests__/session-defaults.test.ts
+++ b/src/cli/__tests__/session-defaults.test.ts
@@ -3,34 +3,36 @@
 import {
   mergeCliSessionDefaults,
   pickSchemaSessionDefaults,
-  resolveActiveCliSessionDefaults,
+  resolveCliSessionDefaults,
 } from '../session-defaults.ts';
 
 describe('CLI session defaults', () => {
   it('uses the active profile without overlaying global defaults', () => {
-    const defaults = resolveActiveCliSessionDefaults({
-      enabledWorkflows: [],
-      customWorkflows: {},
-      debug: false,
-      sentryDisabled: false,
-      experimentalWorkflowDiscovery: false,
-      disableSessionDefaults: true,
-      disableXcodeAutoSync: false,
-      uiDebuggerGuardMode: 'error',
-      incrementalBuildsEnabled: false,
-      dapRequestTimeoutMs: 30_000,
-      dapLogEvents: false,
-      launchJsonWaitMs: 8_000,
-      debuggerBackend: 'dap',
-      sessionDefaults: {
-        workspacePath: 'Global.xcworkspace',
-      },
-      sessionDefaultsProfiles: {
-        ios: {
-          scheme: 'ProfileScheme',
+    const defaults = resolveCliSessionDefaults({
+      runtimeConfig: {
+        enabledWorkflows: [],
+        customWorkflows: {},
+        debug: false,
+        sentryDisabled: false,
+        experimentalWorkflowDiscovery: false,
+        disableSessionDefaults: true,
+        disableXcodeAutoSync: false,
+        uiDebuggerGuardMode: 'error',
+        incrementalBuildsEnabled: false,
+        dapRequestTimeoutMs: 30_000,
+        dapLogEvents: false,
+        launchJsonWaitMs: 8_000,
+        debuggerBackend: 'dap',
+        sessionDefaults: {
+          workspacePath: 'Global.xcworkspace',
         },
+        sessionDefaultsProfiles: {
+          ios: {
+            scheme: 'ProfileScheme',
+          },
+        },
+        activeSessionDefaultsProfile: 'ios',
       },
-      activeSessionDefaultsProfile: 'ios',
     });
 
     expect(defaults).toEqual({ scheme: 'ProfileScheme' });

diff --git a/src/cli/register-tool-commands.ts b/src/cli/register-tool-commands.ts
--- a/src/cli/register-tool-commands.ts
+++ b/src/cli/register-tool-commands.ts
@@ -37,8 +37,15 @@
   const argv = process.argv.slice(2);
   for (let index = 0; index < argv.length; index += 1) {
     const token = argv[index];
+    if (token === '--') {
+      break;
+    }
     if (token === '--profile') {
-      return argv[index + 1];
+      const nextToken = argv[index + 1];
+      if (nextToken && !nextToken.startsWith('-')) {
+        return nextToken;
+      }
+      return undefined;
     }
     if (token.startsWith('--profile=')) {
       return token.slice('--profile='.length);

diff --git a/src/cli/session-defaults.ts b/src/cli/session-defaults.ts
--- a/src/cli/session-defaults.ts
+++ b/src/cli/session-defaults.ts
@@ -24,12 +24,6 @@
   return { ...(opts.runtimeConfig.sessionDefaults ?? {}) };
 }
 
-export function resolveActiveCliSessionDefaults(
-  runtimeConfig: ResolvedRuntimeConfig,
-): Partial<SessionDefaults> {
-  return resolveCliSessionDefaults({ runtimeConfig });
-}
-
 export function isKnownCliSessionDefaultsProfile(
   runtimeConfig: ResolvedRuntimeConfig,
   profileName: string,
This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Use yargs-parser for builder-time --profile resolution so help-time\nrequiredness stays aligned with handler-time parsing. This removes\nthe manual argv scan that could diverge from command execution.\n\nAlso remove the unused resolveActiveCliSessionDefaults wrapper and\npoint the tests at the shared resolver directly.\n\nCo-Authored-By: OpenAI <noreply@openai.com>
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@cameroncooke cameroncooke merged commit 367bec1 into main Mar 7, 2026
9 checks passed
@cameroncooke cameroncooke deleted the feat/cli-session-defaults branch March 7, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant