Command Completion Notifier
Command Completion Notifier is a Visual Studio Code extension that watches commands executed in the integrated terminal and notifies you when configured work finishes.
It uses the stable VS Code terminal shell integration API. It does not poll, use fixed delays, scan for generic words such as done, send data to external services, or collect telemetry.
Features
- Detects real command start and end events through shell integration.
- Reports the command, result, exit code, duration, terminal, workspace, and finish time.
- Delivers real Windows toast notifications in the bottom-right corner and Notification Center.
- Matches commands exactly, by prefix, or by regular expression.
- Tracks concurrent commands independently across multiple terminals.
- Filters short commands with a configurable minimum duration.
- Can notify always, only when VS Code is not focused, or when the terminal is not active.
- Plays an optional local system sound, including while VS Code is minimized.
- Supports one-time
outputPattern notifications for persistent development servers.
- Masks common secret arguments or hides all command arguments.
- Provides actions to open the terminal, view an error, copy the command, or show the extension log.
- Adds enable, disable, test, settings, and tracked-command commands to the Command Palette.
- Includes an optional status bar indicator.
How detection works
The extension listens to these stable VS Code API events:
vscode.window.onDidStartTerminalShellExecution
vscode.window.onDidEndTerminalShellExecution
vscode.window.onDidCloseTerminal
Each start event exposes a TerminalShellExecution, its command line, current working directory, and terminal. The matching end event exposes the exit code. Duration is measured between those two real events.
For outputPattern rules, the extension calls TerminalShellExecution.read() immediately after the start event. It removes terminal control sequences and keeps only the latest 8 KB in memory while looking for the configured readiness expression. The buffer is discarded when the command ends or its terminal closes.
Project structure
.
├── .vscode/
│ ├── launch.json
│ └── tasks.json
├── src/
│ ├── configuration.ts
│ ├── executionTracker.ts
│ ├── extension.ts
│ ├── messageFormatter.ts
│ ├── notificationService.ts
│ ├── ruleMatcher.ts
│ ├── sanitizer.ts
│ ├── soundService.ts
│ ├── statusBarController.ts
│ ├── terminalListener.ts
│ ├── types.ts
│ └── windowsToastService.ts
├── test/
│ ├── executionTracker.test.ts
│ ├── messageFormatter.test.ts
│ ├── ruleMatcher.test.ts
│ ├── sanitizer.test.ts
│ ├── soundService.test.ts
│ └── windowsToastService.test.ts
├── package.json
├── tsconfig.json
└── README.md
The architecture keeps VS Code activation, terminal events, execution state, rule evaluation, configuration, notification presentation, and privacy helpers in separate modules.
Requirements
- Visual Studio Code 1.93 or newer.
- Shell integration enabled in VS Code.
- A supported shell with command detection.
VS Code currently documents rich shell integration for:
- Windows: PowerShell and Git Bash.
- Linux and macOS: Bash, Fish, PowerShell, and Zsh.
Shell integration can be enabled with:
{
"terminal.integrated.shellIntegration.enabled": true
}
If command decorations appear beside terminal commands, command detection is usually active. Hover a terminal tab and select Show Details to inspect its shell integration quality.
Install dependencies
npm install
Compile
npm run compile
For continuous compilation:
npm run watch
Run in the Extension Development Host
- Open this folder in VS Code.
- Press
F5.
- In the new Extension Development Host window, open an integrated terminal.
- Run a configured command.
The launch configuration compiles the extension before starting the host.
Settings
| Setting |
Default |
Description |
commandCompletionNotifier.enabled |
true |
Enables or disables tracking and notifications. |
commandCompletionNotifier.commands |
Common build commands |
Simple prefix rules. |
commandCompletionNotifier.rules |
[] |
Advanced matching and completion rules. |
commandCompletionNotifier.minimumDurationSeconds |
10 |
Ignores faster completions. Use 0 to always notify. |
commandCompletionNotifier.notifyWhen |
windowNotFocused |
always, windowNotFocused, or terminalNotVisible. |
commandCompletionNotifier.notificationType |
vscode |
vscode, a native Windows toast with windows, or both channels with both. Non-Windows systems fall back to VS Code notifications. |
commandCompletionNotifier.playSound |
true |
Plays a local system sound when a command notification is emitted. |
commandCompletionNotifier.hideCommandArguments |
false |
Replaces every argument with an ellipsis in notifications and logs. |
commandCompletionNotifier.sensitiveArgumentNames |
Common secret flags |
Masks values passed to configured argument names. |
commandCompletionNotifier.showStatusBar |
true |
Shows the on/off indicator. |
Advanced rules are evaluated before simple entries in commands. The first matching rule wins.
Configuration examples
Simple command prefixes
{
"commandCompletionNotifier.enabled": true,
"commandCompletionNotifier.commands": [
"docker compose build",
"npm install",
"npm run build",
"pnpm build",
"go test",
"go build"
],
"commandCompletionNotifier.minimumDurationSeconds": 10,
"commandCompletionNotifier.notifyWhen": "windowNotFocused",
"commandCompletionNotifier.notificationType": "windows",
"commandCompletionNotifier.playSound": true
}
An entry such as docker compose matches docker compose build, docker compose up --build, and other command lines that begin with that text.
Exact, prefix, and regular expression rules
{
"commandCompletionNotifier.rules": [
{
"pattern": "^docker compose (build|pull)",
"matchType": "regex",
"notifyOnSuccess": true,
"notifyOnFailure": true
},
{
"pattern": "npm run build",
"matchType": "exact",
"notifyOnSuccess": true,
"notifyOnFailure": true
},
{
"pattern": "npm install",
"matchType": "startsWith",
"notifyOnSuccess": true,
"notifyOnFailure": true
}
]
}
Regular expressions are case-insensitive. Invalid rules are ignored and explained in the Command Completion Notifier output channel.
Persistent processes
Commands such as docker compose up, npm run dev, next dev, and vite may not exit until you stop them. Use outputPattern to notify once when their output indicates readiness:
{
"commandCompletionNotifier.rules": [
{
"pattern": "docker compose up",
"matchType": "startsWith",
"completionMode": "outputPattern",
"readyPattern": "Started|ready|listening",
"notifyMessage": "The containers are ready"
},
{
"pattern": "npm run dev",
"matchType": "exact",
"completionMode": "outputPattern",
"readyPattern": "Ready in|Local:"
}
]
}
The readiness notification is emitted at most once for each shell execution. A processExit rule notifies only when the process actually ends.
Privacy
{
"commandCompletionNotifier.hideCommandArguments": false,
"commandCompletionNotifier.sensitiveArgumentNames": [
"--password",
"--token",
"--secret",
"--api-key"
]
}
For example, deploy --token abc123 is displayed as deploy --token ***. Set hideCommandArguments to true to display only the executable.
The original command remains in memory only while its execution is tracked so that the Copy Command action can work. Terminal output is not saved to disk or written to the output channel.
Command Palette commands
- Command Completion Notifier: Enable
- Command Completion Notifier: Disable
- Command Completion Notifier: Test Notification
- Command Completion Notifier: Open Settings
- Command Completion Notifier: Show Tracked Commands
Tests
Run the automated suite:
npm test
Run strict TypeScript validation:
npm run check
The test notification command also plays the configured sound, making it the quickest way to verify local audio.
The suite covers exact, prefix, and regular expression matching; minimum duration; success, failure, and unknown exit status; multiple terminals; output patterns split across chunks; duplicate prevention; terminal closure; sensitive argument masking; message formatting; invalid configuration; and safe platform-specific sound commands.
Manual Windows test
Set the minimum duration to zero and add a matching rule:
{
"commandCompletionNotifier.minimumDurationSeconds": 0,
"commandCompletionNotifier.notifyWhen": "always",
"commandCompletionNotifier.commands": [
"ping 127.0.0.1"
]
}
Then run:
ping 127.0.0.1 -n 6
Also validate with actual commands available in your workspace, such as:
docker compose build
npm run build
Build and install a VSIX
Create the package:
npm run package
Install it from a terminal:
code --install-extension command-completion-notifier-0.3.2.vsix
Or open the Extensions view in VS Code, open the ... menu, choose Install from VSIX..., and select the generated file.
Known limitations
- Shell integration is required. The extension deliberately does not guess completion when shell integration is unavailable.
- Command detection quality depends on the shell integration implementation. Rich integration provides the most reliable command line and exit code.
- Shell integration may not activate in unsupported shells, old shell versions, nested shells, complex prompt setups, or ordinary SSH sessions launched inside a local terminal.
- An undefined exit code is reported as an unknown exit status and follows
notifyOnFailure.
- Exact terminal panel visibility is not exposed by the stable VS Code API.
terminalNotVisible conservatively means that the command's terminal is not the active terminal.
- A chained line such as
npm install && npm run build is treated as one shell execution in this version.
- Output patterns are regular expressions matched against a temporary 8 KB rolling tail. They can still produce false positives if the expression is too broad.
- Native Windows notifications require notifications to be enabled for Visual Studio Code in Windows Settings. Do Not Disturb or Focus Assist can suppress the popup while still placing it in Notification Center.
- Native Windows notifications are informational in this release. Interactive terminal actions remain available on VS Code notifications when
notificationType is vscode or both.
- The Windows toast is attributed to the installed Visual Studio Code application. VS Code Insiders uses its separate registered application ID.
- If Windows rejects a native toast, the extension records a warning and shows a VS Code notification instead.
- Sounds require VS Code to remain running. They work while the window is minimized or unfocused, but not after VS Code is closed.
- Windows sounds use a fixed, hidden Windows PowerShell system-sound command. No terminal command text or user data is interpolated into it.
- macOS uses the built-in
afplay utility. Linux tries canberra-gtk-play, then paplay; some minimal Linux installations may not have either audio player.
- Commands run outside the VS Code integrated terminal are outside the extension's scope.
Compatibility
| Platform |
Notification |
Supported shell integration |
| Windows 10/11 |
VS Code notification, native Windows toast, and local system sound |
PowerShell and Git Bash |
| Linux |
VS Code notification and local sound when a supported player is installed |
Bash, Fish, PowerShell, and Zsh |
| macOS |
VS Code notification and local system sound |
Bash, Fish, PowerShell, and Zsh |
Other shells may work if they emit shell integration sequences that VS Code recognizes, but they are not guaranteed.
Recommended next steps
- Add native toast buttons that can safely focus the matching terminal.
- Add integration tests in an Extension Development Host for supported shells.
- Add per-workspace rule overrides and rule-specific minimum durations.
- Add a privacy-preserving option to disable the Copy Command action.
Official references