Skip to content

feat(cli): provide manual session UUID via command line arg#26060

Merged
cocosheng-g merged 12 commits intomainfrom
uuid-arg
Apr 27, 2026
Merged

feat(cli): provide manual session UUID via command line arg#26060
cocosheng-g merged 12 commits intomainfrom
uuid-arg

Conversation

@cocosheng-g
Copy link
Copy Markdown
Contributor

@cocosheng-g cocosheng-g commented Apr 27, 2026

Fixes #19602

Allows users to manually provide a specific session UUID using the --session-id CLI flag. If provided alongside --resume, an error is returned to prevent ambiguity. Ensures this ID takes priority when creating a new session.

Testing

  • Successfully added comprehensive unit tests for parseArguments in config.test.ts
  • Verified logic properly triggers conflict errors when both --resume and --session-id are provided
  • Added mock args for --session-id in gemini.test.tsx
  • Manually verified the CLI behavior:
    • Creating a new session with a valid custom UUID succeeds.
    • Attempting to use a duplicate ID correctly throws an error.
    • Path traversal characters and invalid special characters are caught early during argument parsing.
    • Conflicting flags (--resume and --session-id) are correctly identified and rejected.

@cocosheng-g cocosheng-g requested a review from a team as a code owner April 27, 2026 17:06
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

Size Change: +1.99 kB (+0.01%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-6N6VON4E.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-BT4ZALV4.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-GE7TRVLB.js 0 B -673 kB (removed) 🏆
./bundle/chunk-IDZRDY23.js 0 B -2.73 MB (removed) 🏆
./bundle/chunk-PIKRZ7PR.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-RTK2UIQA.js 0 B -14.7 MB (removed) 🏆
./bundle/core-ONWS5ED4.js 0 B -48.1 kB (removed) 🏆
./bundle/devtoolsService-7QLF4TIY.js 0 B -27.8 kB (removed) 🏆
./bundle/gemini-CZAHRFG4.js 0 B -573 kB (removed) 🏆
./bundle/interactiveCli-VIUHNVCP.js 0 B -1.31 MB (removed) 🏆
./bundle/liteRtServerManager-4EWVAH7Q.js 0 B -2.08 kB (removed) 🏆
./bundle/oauth2-provider-JOSZ5C5N.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-5QBDBU4G.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-A75L6UTA.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-F2D3QUAC.js 673 kB +673 kB (new file) 🆕
./bundle/chunk-NTM5XNKI.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-QFKSC5UW.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-UUI5O5HY.js 2.73 MB +2.73 MB (new file) 🆕
./bundle/core-4EKN7FMB.js 48.1 kB +48.1 kB (new file) 🆕
./bundle/devtoolsService-TARZWFIL.js 27.8 kB +27.8 kB (new file) 🆕
./bundle/gemini-XINJ5CEW.js 574 kB +574 kB (new file) 🆕
./bundle/interactiveCli-P2EPG7RZ.js 1.31 MB +1.31 MB (new file) 🆕
./bundle/liteRtServerManager-56Y7YANN.js 2.08 kB +2.08 kB (new file) 🆕
./bundle/oauth2-provider-N3G6QOJA.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-MTD736U4.js 1.97 MB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-LMPPOO3F.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 4.97 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-NSOLCG4U.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-A65L475V.js 0 B -622 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-Z7HLUSN3.js 932 B +932 B (new file) 🆕
./bundle/start-TDQ3ULZ5.js 622 B +622 B (new file) 🆕

compressed-size-action

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the summary. You can try again by commenting /gemini summary.

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds a --session-id flag to the CLI for manual session UUID specification. It includes logic to prevent conflicts with the --resume flag and ensures that provided session IDs are unique. Review feedback highlights a critical path traversal vulnerability due to the lack of input sanitization for the session ID, recommending strict validation and the use of nargs: 1 for the CLI option.

Comment thread packages/cli/src/gemini.tsx
Comment thread packages/cli/src/config/config.ts
@cocosheng-g cocosheng-g self-assigned this Apr 27, 2026
@gemini-cli gemini-cli Bot added the area/core Issues related to User Interface, OS Support, Core Functionality label Apr 27, 2026
@cocosheng-g cocosheng-g requested a review from devr0306 April 27, 2026 18:09
@devr0306
Copy link
Copy Markdown
Contributor

devr0306 commented Apr 27, 2026

From /frontend-review

PR Review: feat(cli): provide manual session UUID via command line arg

Nice work on implementing manual session IDs! This is a great addition for users who need predictable session tracking.

Suggestions for Improvement:

  1. Yargs Configuration (config.ts):
    Most string-based options in config.ts use nargs: 1 to ensure exactly one value is consumed. Adding nargs: 1 to the session-id option would maintain consistency and prevent edge cases where subsequent flags might be swallowed.

  2. Early Input Validation:
    While ChatRecordingService performs sanitization, it would be safer and more user-friendly to validate the session-id early in parseArguments or resolveSessionId. Rejecting IDs with invalid characters (e.g., path traversal characters) with a clear error is preferable to silent sanitization.

  3. Test Style & Cleanup (gemini.test.tsx & config.test.ts):

    • Imports: In gemini.test.tsx, consider moving the SessionSelector and resolveSessionId imports to the top level instead of using dynamic await import inside the it blocks, to match the existing style of the file.
    • Mock Restoration: In config.test.ts, ensure all mocks (like console.error and process.exit) are consistently restored in an afterEach block using vi.restoreAllMocks() rather than manual restoration at the end of each test, to align with the project's strict testing guidelines.

Minor Observation:

The logic in resolveSessionId correctly prevents duplicate session IDs by checking existing sessions, which is excellent for data integrity.

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

@devr0306 addressed all comments

@devr0306
Copy link
Copy Markdown
Contributor

devr0306 commented Apr 27, 2026

Suggestions from /review-frontend

Thank you for the PR! This is a great addition that addresses #19602.

The implementation and tests are solid. I have two suggestions to improve validation consistency and performance:

1. Consolidate Session ID Validation

Currently, there are two different validation checks for the session ID:

  • In config.ts, the coerce function checks for path traversal characters (/[/\\..]/).
  • In gemini.tsx, resolveSessionId uses a stricter regex (/^[a-zA-Z0-9-_]+$/).

We should consolidate this by moving the stricter regex check into the coerce function in config.ts. This enforces the rule earlier in the argument parsing phase and simplifies the logic in gemini.tsx.

Suggested change in packages/cli/src/config/config.ts:

        .option('session-id', {
          type: 'string',
          nargs: 1,
          description: 'Start a new session with a manually provided UUID.',
          coerce: (value: string): string => {
            const trimmed = value.trim();
            if (!trimmed) {
              throw new Error('The --session-id option cannot be empty.');
            }
            if (!/^[a-zA-Z0-9-_]+$/.test(trimmed)) {
              throw new Error(
                'Invalid session ID "' +
                  trimmed +
                  '": Only alphanumeric characters, dashes, and underscores are allowed.',
              );
            }
            return trimmed;
          },
        })

(You can then remove the regex check from resolveSessionId in gemini.tsx).

2. Optimize Session Existence Check

In gemini.tsx, the check for an existing session ID currently reads and parses all session files:

const sessions = await sessionSelector.listSessions();
if (sessions.some((s) => s.id === sessionIdArg)) { ... }

If a user has many past sessions, this can become slow. We can optimize this by checking for the specific file directly using fs.stat or by adding an efficient sessionExists(id) method to SessionSelector.

Suggested change (adding to packages/cli/src/utils/sessionUtils.ts):

  async sessionExists(id: string): Promise<boolean> {
    const chatsDir = path.join(this.storage.getProjectTempDir(), 'chats');
    const files = await fs.readdir(chatsDir).catch(() => []);
    return files.some(file => file.startsWith(SESSION_FILE_PREFIX + id + '-'));
  }

Then update gemini.tsx to use it:

    if (await sessionSelector.sessionExists(sessionIdArg)) {
      coreEvents.emitFeedback(
        'error',
        `Error starting session: Session ID "${sessionIdArg}" already exists. Use --resume to resume it, or provide a different ID.`,
      );

Let me know if you have any questions!

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

addressed all

Copy link
Copy Markdown
Contributor

@devr0306 devr0306 left a comment

Choose a reason for hiding this comment

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

LGTM

@cocosheng-g cocosheng-g enabled auto-merge April 27, 2026 20:02
@cocosheng-g cocosheng-g added this pull request to the merge queue Apr 27, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 27, 2026
@cocosheng-g cocosheng-g enabled auto-merge April 27, 2026 20:37
@cocosheng-g cocosheng-g added this pull request to the merge queue Apr 27, 2026
Merged via the queue into main with commit 6cc0b1b Apr 27, 2026
27 checks passed
@cocosheng-g cocosheng-g deleted the uuid-arg branch April 27, 2026 21:18
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Manually provide new session UUID via command line arg

2 participants