Step 8: Interactive Shell — Complete (WI-0 through WI-5)#561
Merged
tnaum-ms merged 28 commits intofeature/shell-integrationfrom Apr 9, 2026
Merged
Step 8: Interactive Shell — Complete (WI-0 through WI-5)#561tnaum-ms merged 28 commits intofeature/shell-integrationfrom
tnaum-ms merged 28 commits intofeature/shell-integrationfrom
Conversation
…references - Remove src/commands/launchShell/ directory (legacy external mongosh launcher) - Replace launchShell command registration with openInteractiveShell stub in ClustersExtension.ts - Remove documentDB.mongoShell.* settings from package.json and extensionVariables.ts - Add documentDB.shell.display.colorOutput and documentDB.shell.display.autocompletion settings - Update all package.json menu contributions from launchShell to openInteractiveShell - Rename mongoShell -> shellCommand across AI service types, query insights, and webview types - Mark WI-0 as in-progress in plan file
…eout migration - Rename mongoShell -> shellCommand in promptTemplates.ts (LLM JSON schema) - Rename mongoShell local vars/comments in transformations.ts - Migrate documentDB.mongoShell.timeout -> documentDB.shell.timeout (used by PlaygroundEvaluator) - Remove mongosh prerequisite from README.md - Regenerate l10n bundle (removed stale mongoShell entries, added new strings) - All builds, lint, prettier, l10n, and tests pass (98/98)
…r, add persistent mode - Extract core worker lifecycle/IPC logic from PlaygroundEvaluator into WorkerSessionManager (spawn, init, eval, shutdown, timeout, token relay) - PlaygroundEvaluator now delegates to WorkerSessionManager (persistent: false) - Add persistent: boolean to ShellRuntimeOptions and workerTypes InitMessage - DocumentDBShellRuntime supports persistent mode: reuses ShellInstanceState, ShellEvaluator, and vm.Context across evaluate() calls - Add ShellSessionManager (persistent: true) for interactive shell sessions - Add tests for DocumentDBShellRuntime persistent/non-persistent modes - Add tests for WorkerSessionManager initial state and dispose - All 82 existing + new tests pass, no regressions
Implement the interactive shell REPL UI using VS Code's Pseudoterminal API. New files: - DocumentDBShellPty.ts: Pseudoterminal implementation (REPL loop, prompt rendering, eval dispatch, special result handling, Ctrl+C) - ShellInputHandler.ts: Line editing, cursor movement, command history, word navigation, Ctrl+U/K/W editing shortcuts - ShellOutputFormatter.ts: EJSON deserialization, ANSI color-coded JSON output, CursorIterationResult unwrapping, help/error/system formatting Tests: 69 new tests (37 + 17 + 15) covering all three components.
Add two new command patterns to the shell-runtime CommandInterceptor:
- exit/quit: returns { type: 'exit' } result to signal shell close
- cls/clear: returns { type: 'clear' } result to signal screen clear
Both patterns support optional trailing semicolons and whitespace.
Negative tests ensure function calls, property access, and substrings
are not intercepted.
Also update HelpProvider to include shell commands section:
help, exit/quit, cls/clear, it, use <db>.
Tests: 36 CommandInterceptor tests (was 12), all HelpProvider tests pass.
Implement the openInteractiveShell command that opens a DocumentDB interactive shell terminal from the tree view context menu. New files: - src/commands/openInteractiveShell/openInteractiveShell.ts Handles cluster, database, and collection tree nodes. Extracts connection info using clusterId (stable, not treeId), verifies credentials, creates a DocumentDBShellPty, and opens a terminal. Cluster-level invocations use 'test' as default database name. - src/commands/openInteractiveShell/openInteractiveShell.test.ts 9 tests covering all node types, no-node case, and missing credentials. Modified: - ClustersExtension.ts: Replace stub registration with real command using withTreeNodeCommandCorrelation for telemetry. - l10n/bundle.l10n.json: Updated with new user-facing strings.
Split HelpProvider content by surface ('playground' | 'shell'):
- Playground: keyboard shortcuts, block tips, console output panel
- Shell: exit/quit, cls/clear, it, use <db>, session persistence tips
- Shared: collection access, query/write/index/cursor/database/BSON
The surface is derived from the persistent option in
DocumentDBShellRuntime: persistent=true → shell, false → playground.
HelpProvider constructor now takes an optional HelpSurface parameter
(defaults to 'playground' for backward compatibility).
Tests updated: 20 HelpProvider tests (was 14), covering both surfaces.
4.5.1: Suppress null after print() / side-effect-only expressions
- Add printableIsUndefined flag to SerializableExecutionResult
- Worker detects result.printable === undefined before EJSON serialization
(EJSON.stringify(undefined) produces 'null', losing the distinction)
- ShellOutputFormatter returns empty string when flag is set
4.5.2: Connection banner with authentication details
- ShellSessionManager.initialize() now returns ShellConnectionMetadata
(host, authMechanism, isEmulator)
- Host extracted safely from connection string (no credential exposure)
- PTY shows: Connected to host | Authentication: SCRAM/Entra ID | Database
4.5.3: Fix prompt not updating after 'use <db>'
- Bug: updateDatabaseFromResult checked result.type === 'string', but
@MongoSH returns type: null for all primitives including the 'switched
to db <name>' string. Removed the incorrect type guard.
72 tests pass (3 new).
…thentication prompts
…ery results After a find/findOne query with a known namespace, the shell appends a clickable action line: '📊 Open collection [db.coll] in Collection View'. - ShellTerminalLinkProvider: TerminalLinkProvider matching the action line pattern, opens Collection View via internal command on click - DocumentDBShellPty: writes action line after Cursor/Document results with source.namespace; tracks active action line state - Terminal registry: maps Terminal → PTY info for the link provider - 16 tests (10 link provider + 6 PTY action line tests) - Query pre-fill deferred to future work (§3.1 in terminal enhancements)
- Show username in banner for SCRAM auth (User: admin | Authentication: SCRAM | Database: mydb) - For Entra ID, show auth method without username (as before) - Update terminal tab name dynamically after connection to include user: 'DocumentDB: user@cluster/db' - Add username field to ShellConnectionMetadata, sourced from CredentialCache - Add onDidChangeName to PTY for dynamic terminal name updates
- Add setTerminal, getTerminalInfo, onDidChangeName to DocumentDBShellPty mock - Mock registerShellTerminal in openInteractiveShell tests - Fix pre-existing test: 'Authenticating and connecting' → 'Connecting and authenticating'
Contributor
There was a problem hiding this comment.
Pull request overview
Implements Step 8 “Interactive Shell” as an in-extension REPL hosted in a VS Code pseudoterminal, backed by the existing worker-thread eval pipeline with a new persistent runtime mode. This also removes the legacy external mongosh launcher/settings and updates Query Insights/AI payload fields from mongoShell → shellCommand.
Changes:
- Added an interactive shell PTY with line editing/history, formatted output, and session lifecycle management.
- Refactored worker infrastructure into a reusable
WorkerSessionManager, and addedpersistenteval mode to the shell runtime. - Replaced the legacy
launchShellcommand/settings and updated Query Insights + prompt templates to useshellCommand.
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| src/webviews/documentdb/collectionView/types/queryInsights.ts | Renames query insight payload fields to shellCommand. |
| src/services/ai/types.ts | Renames AI index recommendation field to shellCommand. |
| src/services/ai/QueryInsightsAIService.ts | Updates modify-index payload validation/parsing to use shellCommand. |
| src/extensionVariables.ts | Removes legacy mongo shell settings keys; adds documentDB.shell.timeout key constant. |
| src/documentdb/shell/ShellTerminalLinkProvider.ts | Adds terminal link provider + registry for “Open collection …” action lines. |
| src/documentdb/shell/ShellTerminalLinkProvider.test.ts | Unit tests for terminal link detection and command execution. |
| src/documentdb/shell/ShellSessionManager.ts | Adds shell-specific session wrapper around worker manager (persistent context). |
| src/documentdb/shell/ShellOutputFormatter.ts | Adds output formatting (EJSON, optional ANSI coloring, cursor “it” hint). |
| src/documentdb/shell/ShellOutputFormatter.test.ts | Tests for formatter behavior and color/no-color modes. |
| src/documentdb/shell/ShellInputHandler.ts | Adds line editing, cursor movement, history navigation, word ops for PTY input. |
| src/documentdb/shell/ShellInputHandler.test.ts | Tests for input handling and editing operations. |
| src/documentdb/shell/DocumentDBShellPty.ts | Implements PTY REPL loop, prompt handling, interrupts, action line emission. |
| src/documentdb/shell/DocumentDBShellPty.test.ts | Tests for PTY lifecycle, eval flow, special results, action line output. |
| src/documentdb/queryInsights/transformations.ts | Wires shellCommand into ImprovementCards and action payloads. |
| src/documentdb/playground/workerTypes.ts | Adds printableIsUndefined + persistent init option to worker protocol. |
| src/documentdb/playground/WorkerSessionManager.ts | New reusable worker lifecycle/IPC manager extracted from playground evaluator. |
| src/documentdb/playground/WorkerSessionManager.test.ts | Basic unit tests for worker manager initial state/dispose. |
| src/documentdb/playground/playgroundWorker.ts | Supports persistent runtime option + preserves undefined via flag. |
| src/documentdb/playground/PlaygroundEvaluator.ts | Refactors to use WorkerSessionManager and keeps playground semantics. |
| src/documentdb/ClustersExtension.ts | Registers new openInteractiveShell command and terminal link provider. |
| src/commands/openInteractiveShell/openInteractiveShell.ts | Adds command to open PTY shell from cluster/db/collection nodes. |
| src/commands/openInteractiveShell/openInteractiveShell.test.ts | Tests command behavior, telemetry props, and credential gating. |
| src/commands/llmEnhancedCommands/promptTemplates.ts | Updates prompt schema/rules from mongoShell → shellCommand. |
| src/commands/launchShell/launchShell.ts | Removes legacy external mongosh launcher implementation. |
| README.md | Removes external mongosh prerequisite note (legacy launcher removed). |
| packages/documentdb-shell-runtime/src/types.ts | Adds persistent option to runtime API. |
| packages/documentdb-shell-runtime/src/index.ts | Exposes HelpSurface type. |
| packages/documentdb-shell-runtime/src/HelpProvider.ts | Adds surface-aware help content (playground vs shell). |
| packages/documentdb-shell-runtime/src/HelpProvider.test.ts | Adds tests for both help surfaces + getHelpResult behavior. |
| packages/documentdb-shell-runtime/src/DocumentDBShellRuntime.ts | Implements persistent evaluation mode and surface-aware interceptor help. |
| packages/documentdb-shell-runtime/src/DocumentDBShellRuntime.test.ts | Tests persistent vs fresh context behavior and disposal. |
| packages/documentdb-shell-runtime/src/CommandInterceptor.ts | Adds interception for exit/quit and cls/clear (plus help). |
| packages/documentdb-shell-runtime/src/CommandInterceptor.test.ts | Adds tests for new interception patterns. |
| packages/documentdb-shell-runtime/README.md | Documents runtime modes and usage. |
| packages/documentdb-shell-runtime/package.json | Updates package description to match new scope. |
| package.json | Contributes new command, menus, and new shell settings; removes legacy shell settings. |
| l10n/bundle.l10n.json | Adds/removes localized strings for interactive shell UX and Query Insights updates. |
…Ctrl+C during eval - Add _terminatingIntentionally flag to WorkerSessionManager to suppress onWorkerExit callback during intentional kills (Ctrl+C, timeout, dispose) - Allow Ctrl+C to bypass the _enabled guard in ShellInputHandler so users can cancel running evaluations - Reset evaluating state and re-enable input after Ctrl+C kill - Fixes: shell no longer shows 'ended unexpectedly' on Ctrl+C or timeout - Fixes: Ctrl+C now cancels long-running queries instead of being swallowed Addresses review findings #2 and #14.
…es Ctrl+C/timeout) - Add _activeDatabase field to ShellSessionManager, initialized from connectionInfo - Update _activeDatabase when PTY detects a 'use <db>' result - Use _activeDatabase (not original connectionInfo.databaseName) for both buildInitMessage() and evaluate(), so worker re-init uses the correct database - Add setActiveDatabase mock to PTY test suite Addresses review finding #1.
- Extend EXIT_PATTERN regex to match exit(), quit(), exit();, quit(); - Previously these bypassed the interceptor and went to @MongoSH, which called process.exit() in the worker, producing a crash-like exit - Update tests to verify the new function-call forms are intercepted Addresses review finding #7.
- Set _inputHandler.setEnabled(false) at the start of open() - Re-enable input after successful init (before showing prompt) - Re-enable input on init failure (before closing terminal) - Prevents user input from triggering a concurrent initialize() call Addresses review finding #8.
…ll sessions - Replace hardcoded expiresInSeconds: 0 with actual expiration from the JWT - Parse the exp claim from the access token payload - Fall back to 3500 seconds (~1 hour) if JWT parsing fails - Eliminates redundant token acquisition on every database operation in persistent shell sessions (previously every command triggered a full IPC + auth API round-trip) Addresses review finding #9.
… handling - Replace 📊 emoji with 🔗 (link icon) to suggest clickability - Make action line format locale-independent: '🔗 [db.collection]' (no English text to translate — tooltip remains localized) - Regex in ShellTerminalLinkProvider now matches the sentinel prefix instead of hard-coded English text - Fix Unicode input handling: use for...of iteration instead of data[i] to correctly handle surrogate pairs (emoji, CJK Extension B) Addresses review findings #3 and #10.
Remove mockInitialize.mockResolvedValue(undefined) overrides so tests exercise the connected-shell code path with real metadata instead of falling into the error/failure path. Addresses review finding #5.
- Cache username from initialization metadata in _username field - Extract updateTerminalTitle() helper called from both init and updateDatabaseFromResult() - Terminal tabs now reflect the active database after switching Addresses review finding #6.
Change regex from /\S+/ to /.+/ to capture database names containing spaces (e.g., 'my db'). Addresses review finding #11.
Addresses review finding #12.
Addresses review finding #13.
The eraseActionLine method was a no-op (only reset a flag). Remove the method, the _hasActiveActionLine field, and the call site. Action lines in scroll-back remain clickable, which is the intended behavior. Addresses PR thread item B (r3057731102, r3057760296).
…r message - Change getShellTimeoutMs() local fallback from 120 to 30 (matches the contributed setting default in package.json) - Timeout error message now tells users the timeout is configurable in Settings > DocumentDB > Shell > Timeout Addresses PR thread item D (r3057731255, r3057764942).
Collaborator
Author
Review findings addressedAll findings from the code review have been addressed in the latest commits. Summary: High priority (correctness)
Medium priority (robustness)
Low priority (polish)
Acknowledged / deferred
|
… Reconnecting message Three user-facing issues fixed: 1. print() output now gets a newline before the next prompt. Track _lastOutputHadTrailingNewline from console output and emit \r\n before the prompt if the last output didn't end with one. 2. Ctrl+C no longer shows 'Worker terminated' error. Set _interrupted flag in handleInterrupt() so evaluateInput()'s catch and handleLineInput()'s finally both skip their output/prompt when the interruption was intentional. 3. After Ctrl+C, show 'Reconnecting...' while the worker respawns. Add onReconnecting callback to ShellSessionCallbacks, fired from evaluate() when re-initialization is needed after a worker kill.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Interactive Shell Implementation (Step 8) ✅
Implements the Interactive Shell feature — a REPL experience within a VS Code terminal, integrated with the extension's connection management and shell-runtime eval engine.
Full plan:
docs/plan/08-interactive-shell.mdWork Items
What's New
Interactive Shell (Pseudoterminal)
dbreference survive across commandshelp,exit/quit,cls/clear,show dbs,show collections,use <db>,ituse <db>)documentDB.shell.display.colorOutputDocumentDB: user@cluster/dbWorker Infrastructure
WorkerSessionManagerfromPlaygroundEvaluator— shared by playground (fresh context) and shell (persistent context)persistent: truemode enables@mongoshstate persistence across evaluationsTerminal Links
📊 Open collection [db.collection] in Collection Viewaction lineShellTerminalLinkProvidermatches the action line pattern and opens Collection View on clickCommandInterceptor
exit/quit→ signal shell closecls/clear→ clear terminal screenLaunch Points
testdatabase)Removed
launchShellcommand (external process launcher)documentDB.mongoShell.path,documentDB.mongoShell.args,documentDB.mongoShell.timeoutsettingsmongoShellwithshellCommandin AI service types and prompt templatesNew Settings
documentDB.shell.display.colorOutputdocumentDB.shell.display.autocompletionTerminalCompletionProviderdocumentDB.shell.timeoutTest Coverage
use <db>, action lineexit,quit,cls,clearpatternsPart of umbrella PR #508.