teams-cli 0.2.1__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {teams_cli-0.2.1 → teams_cli-0.2.3}/.github/workflows/ci.yml +10 -0
  2. {teams_cli-0.2.1 → teams_cli-0.2.3}/CHANGELOG.md +28 -0
  3. {teams_cli-0.2.1 → teams_cli-0.2.3}/Cargo.lock +1 -1
  4. {teams_cli-0.2.1 → teams_cli-0.2.3}/Cargo.toml +1 -1
  5. {teams_cli-0.2.1 → teams_cli-0.2.3}/PKG-INFO +124 -11
  6. {teams_cli-0.2.1 → teams_cli-0.2.3}/README.md +123 -10
  7. teams_cli-0.2.3/src/auth/pass.rs +494 -0
  8. teams_cli-0.2.3/src/auth/process.rs +81 -0
  9. teams_cli-0.2.3/src/auth/wsl.rs +152 -0
  10. teams_cli-0.2.3/src/auth/wsl_credentials.ps1 +46 -0
  11. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/auth.rs +238 -21
  12. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/cli.rs +20 -6
  13. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/config.rs +46 -0
  14. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/browser.rs +458 -37
  15. teams_cli-0.2.3/src/desktop/browser_children.rs +455 -0
  16. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/browser_install.rs +43 -1
  17. teams_cli-0.2.3/src/desktop/browser_lifetime.rs +465 -0
  18. teams_cli-0.2.3/src/desktop/browser_setup.rs +138 -0
  19. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/connection.rs +38 -1
  20. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop.rs +74 -5
  21. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/lib.rs +1 -0
  22. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/main.rs +511 -116
  23. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/schema.rs +35 -7
  24. teams_cli-0.2.3/src/setup/capabilities.rs +178 -0
  25. teams_cli-0.2.3/src/setup.rs +1275 -0
  26. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/tui.rs +180 -3
  27. teams_cli-0.2.3/tests/browser_lifetime.rs +993 -0
  28. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/cli.rs +106 -3
  29. teams_cli-0.2.3/tests/credentials.rs +249 -0
  30. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/desktop.rs +4 -5
  31. teams_cli-0.2.3/tests/pass_credentials.sh +24 -0
  32. teams_cli-0.2.3/tests/wsl_credentials.test.ps1 +35 -0
  33. {teams_cli-0.2.1 → teams_cli-0.2.3}/.github/workflows/dependencies.yml +0 -0
  34. {teams_cli-0.2.1 → teams_cli-0.2.3}/.github/workflows/release.yml +0 -0
  35. {teams_cli-0.2.1 → teams_cli-0.2.3}/.gitignore +0 -0
  36. {teams_cli-0.2.1 → teams_cli-0.2.3}/.mise.toml +0 -0
  37. {teams_cli-0.2.1 → teams_cli-0.2.3}/LICENSE +0 -0
  38. {teams_cli-0.2.1 → teams_cli-0.2.3}/Makefile +0 -0
  39. {teams_cli-0.2.1 → teams_cli-0.2.3}/build.rs +0 -0
  40. {teams_cli-0.2.1 → teams_cli-0.2.3}/docs/releases.md +0 -0
  41. {teams_cli-0.2.1 → teams_cli-0.2.3}/examples/validate_schema.rs +0 -0
  42. {teams_cli-0.2.1 → teams_cli-0.2.3}/pyproject.toml +0 -0
  43. {teams_cli-0.2.1 → teams_cli-0.2.3}/scripts/smoke-release.py +0 -0
  44. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/backend.rs +0 -0
  45. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/delivery.rs +0 -0
  46. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/avatars.rs +0 -0
  47. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/browser_core.rs +0 -0
  48. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/cdp.rs +0 -0
  49. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/connection.ps1 +0 -0
  50. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/helper.rs +0 -0
  51. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/install.rs +0 -0
  52. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/macos.rs +0 -0
  53. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/owner.rs +0 -0
  54. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/session.rs +0 -0
  55. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop/windows.rs +0 -0
  56. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop.js +0 -0
  57. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop_cache.js +0 -0
  58. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop_core.js +0 -0
  59. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop_people.js +0 -0
  60. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/desktop_send.js +0 -0
  61. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/error.rs +0 -0
  62. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/graph.rs +0 -0
  63. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/output.rs +0 -0
  64. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/render.rs +0 -0
  65. {teams_cli-0.2.1 → teams_cli-0.2.3}/src/teams_cli_alias.rs +0 -0
  66. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/connection.rs +0 -0
  67. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/connection.test.ps1 +0 -0
  68. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/desktop_scripts.rs +0 -0
  69. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/desktop_scripts.test.cjs +0 -0
  70. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/fixtures/clispec-v0.3.json +0 -0
  71. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/js/people.test.mjs +0 -0
  72. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/package_alias.rs +0 -0
  73. {teams_cli-0.2.1 → teams_cli-0.2.3}/tests/release_smoke.rs +0 -0
  74. {teams_cli-0.2.1 → teams_cli-0.2.3}/vership.toml +0 -0
@@ -24,6 +24,16 @@ jobs:
24
24
  components: rustfmt, clippy
25
25
  - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
26
26
  - run: cargo test --locked --all-targets
27
+ - name: Verify pass and GPG credential encryption
28
+ if: runner.os == 'Linux'
29
+ run: |
30
+ sudo apt-get update -qq
31
+ sudo apt-get install -y --no-install-recommends pass
32
+ bash tests/pass_credentials.sh
33
+ - name: Verify WSL credential encryption
34
+ if: runner.os == 'Windows'
35
+ shell: powershell
36
+ run: ./tests/wsl_credentials.test.ps1
27
37
 
28
38
  quality:
29
39
  name: Formatting and lints
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.3](https://github.com/rvben/teams-cli/compare/v0.2.2...v0.2.3) - 2026-10-16
11
+
12
+ ### Fixed
13
+
14
+ - Close extension-managed browser sessions after the last client exits, including crashes and editor reloads, while retaining saved sign-in and browsers started independently.
15
+ - Track shared clients and active CLI reads before shutdown. Recover interrupted cleanup and stop individually verified browser helpers, including hung processes, without signalling unrelated applications.
16
+
17
+ ## [0.2.2](https://github.com/rvben/teams-cli/compare/v0.2.1...v0.2.2) - 2026-10-15
18
+
19
+ ### Added
20
+
21
+ - Guided `teams init` asks for Work/school or Personal, chooses a separate browser port, offers explicit send permission, and opens the inbox after verified sign-in.
22
+ - Browser setup can opt in to reopening its saved session with `teams`; existing profiles, native Teams and scripted reads keep their connection behaviour. Explicit setup supports `--auto-start`.
23
+ - Offer initialized `pass` stores during new Graph setup on Linux, WSL and macOS, with explicit `--credential-store pass` and `--pass-store-dir` options. Save the backend and absolute directory per profile, verify GPG encryption/decryption before sign-in, and preserve encrypted credentials on failed updates.
24
+
25
+ ### Fixed
26
+
27
+ - Report credential-helper failures distinctly from missing sign-ins; bound helper operations and preserve the chosen backend across sign-in, refresh and logout.
28
+ - Store WSL Graph credentials with Windows DPAPI through PowerShell, so callback and device-code sign-in, token refresh, and logout do not require D-Bus or Secret Service.
29
+
30
+ ### Changed
31
+
32
+ - Guided setup offers separate accounts or explicit connection updates, preserves Graph registration and channel-history access, resumes interrupted browser sign-in on the original port, and verifies fresh Graph credentials before saving them with rollback on config failure.
33
+ - Cold work-browser inbox startup checks sign-in renewal in the background; failures pause sending and offer sign-in while preserving drafts. First-run `teams tui` uses guided setup, including headless Graph recovery and environment-override checks.
34
+ - Guided setup checks local browser/display support, Teams installation and Windows interop, and matching lightweight browser downloads before allowing a connection choice. Unavailable options explain their requirements; supported alternatives are selected automatically.
35
+ - Guided Graph setup verifies chat access before saving connection settings. Desktop/browser sending opt-in now requires a send-interface probe; guided setup offers an explicit read-only alternative if it fails, without sending a test message.
36
+ - Reject personal-only lightweight browser/work-school combinations before saving even with `--no-login`.
37
+
10
38
  ## [0.2.1](https://github.com/rvben/teams-cli/compare/v0.2.0...v0.2.1) - 2026-10-15
11
39
 
12
40
  ### Added
@@ -3187,7 +3187,7 @@ dependencies = [
3187
3187
 
3188
3188
  [[package]]
3189
3189
  name = "teams-cli"
3190
- version = "0.2.1"
3190
+ version = "0.2.3"
3191
3191
  dependencies = [
3192
3192
  "assert_cmd",
3193
3193
  "base64 0.23.1",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "teams-cli"
3
- version = "0.2.1"
3
+ version = "0.2.3"
4
4
  edition = "2024"
5
5
  rust-version = "1.90"
6
6
  description = "A Microsoft Teams CLI and TUI designed equally for humans and agents"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: teams-cli
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  License-File: LICENSE
@@ -62,23 +62,76 @@ Run `teams` in a terminal on first use, or start explicitly:
62
62
  teams init
63
63
  ```
64
64
 
65
- `teams-cli` includes a maintained multitenant Microsoft Entra public-client registration, so normal setup does not require creating an app or copying a client ID:
65
+ Choose **Work or school** or **Personal**, choose whether to enable sending, and
66
+ follow sign-in. Setup checks this machine first and gives unavailable connections
67
+ no selectable number, with an explanation of what they need. It chooses a separate
68
+ browser port and opens your inbox once chats are readable. After that, just run:
66
69
 
67
70
  ```console
68
- teams init
71
+ teams
69
72
  ```
70
73
 
71
- For a personal Microsoft account with the lightweight hidden browser:
74
+ On macOS, Linux and WSL2, work/school setup prefers a dedicated browser; personal
75
+ setup prefers the lightweight browser. Missing display support, missing executables,
76
+ invalid browser overrides and unavailable matching downloads are checked before
77
+ selection. Personal can use a full browser or Teams Desktop when lightweight mode
78
+ is unavailable. Work/school can use Teams Desktop or Microsoft Graph when needed.
79
+ When no lightweight runtime is installed, these checks query public Chrome for
80
+ Testing version metadata at `googlechromelabs.github.io`; no browser download or
81
+ Teams sign-in happens before consent.
82
+ On a Linux terminal without a display, Graph uses device-code sign-in on another device.
83
+ You explicitly approve reopening a dedicated browser
84
+ when you start the inbox. The saved sign-in is reused, and expired work/school
85
+ sign-in offers to reopen the sign-in window. Some organisations require keeping
86
+ the browser visible; minimise it instead of closing it. WSL2 needs WSLg for sign-in.
87
+ On native Windows, browser options are unavailable; use Teams Desktop or run inside
88
+ WSL2 for browser mode.
89
+
90
+ Guided setup saves connection settings only after a successful chat read, including
91
+ Graph profiles. If sending was requested, desktop/browser setup also probes the
92
+ send interface without sending a message. If that fails, you can explicitly continue
93
+ read-only; setup never silently downgrades your choice. A successful probe establishes
94
+ that the interface is available, while delivery and organisation policies are checked
95
+ when you actually send. Teams build compatibility and sign-in still need live validation.
96
+
97
+ Running setup again asks whether to connect another account or update an existing
98
+ connection. Updates preserve Graph application/tenant settings and previously granted
99
+ channel-history access. Failed Graph verification preserves the previous credential;
100
+ if saving settings fails, the credential change is rolled back. Browser setup can resume
101
+ an unfinished sign-in on the same port, or start a separate account without touching it.
102
+ Recovery errors include the exact command to close that browser.
103
+ You can forget an unfinished setup after confirmation; its browser data and saved
104
+ sign-in remain on disk, and the old browser's close command is shown. Reusing that
105
+ forgotten browser data requires explicit setup with its original `--desktop-port`.
106
+ Setup offers unfinished connections under other names when you connect another account.
107
+
108
+ Cold work-browser startup opens the inbox once chats are readable and checks sign-in
109
+ renewal in the background. A sign-out pauses sending and offers sign-in in the inbox.
110
+ Other startup-check failures keep chats readable and pause sending until you reopen
111
+ the inbox to check again. Drafts stay in memory through the sign-in detour.
112
+ Guided Graph setup disables conflicting token or permission environment overrides;
113
+ explicit flags keep their automation behavior.
114
+
115
+ **Other connection options** keeps Microsoft Graph and the running Teams Desktop
116
+ available. Microsoft Graph includes a maintained Entra public-client registration,
117
+ so normal API setup needs no app registration or copied client ID.
118
+
119
+ Scripts and explicit connection flags keep their existing behaviour. For example:
72
120
 
73
121
  ```console
74
- teams init --profile personal --backend desktop --desktop-client browser-core
122
+ teams init --backend graph
123
+ # Or configure an automatically reopened work browser explicitly:
124
+ teams init --profile work --backend desktop --desktop-client browser \
125
+ --desktop-account work-school --desktop-port 9224 --auto-start
75
126
  ```
76
127
 
77
- This downloads its browsers automatically, opens visible sign-in once, and then
78
- runs hidden. See [lightweight browser setup](#low-memory-browser-client-experimental)
79
- for sending, reconnecting, and experimental compatibility limits.
128
+ Browser profiles default to read-only; add `--allow-send` to enable sending.
129
+ Existing profiles retain their connection behaviour unless you opt in with setup
130
+ or `--auto-start`. CLI reads, JSON output, demo mode and snapshots never start a
131
+ browser automatically. See [lightweight browser setup](#low-memory-browser-client-experimental)
132
+ for personal-account compatibility limits.
80
133
 
81
- Browser PKCE is the human-friendly default. The browser talks directly to Microsoft, and the CLI never receives or stores your password. Normal sign-in requests these delegated scopes:
134
+ For Microsoft Graph profiles, browser PKCE is the default when a local browser is available. The browser talks directly to Microsoft, and the CLI never receives or stores your password. Normal Graph sign-in requests these delegated scopes:
82
135
 
83
136
  ```text
84
137
  openid profile offline_access User.Read User.ReadBasic.All
@@ -157,6 +210,51 @@ The custom app must be a public client with `http://localhost` registered for br
157
210
 
158
211
  For short-lived automation, `TEAMS_ACCESS_TOKEN` overrides the stored credential. Refresh credentials are never written to the config file.
159
212
 
213
+ Under WSL, Graph credentials use Windows DPAPI encryption for the current Windows
214
+ user through `powershell.exe`; no D-Bus or Linux Secret Service is required. Windows
215
+ executable interop must be enabled. Encrypted files live under
216
+ `%LOCALAPPDATA%\teams-cli\credentials` and are shared by WSL distributions using
217
+ the same Windows account and profile name. Existing WSL Secret Service sign-ins
218
+ require `teams auth login` again after upgrading; their old entries are not migrated
219
+ or removed. Native Linux uses Secret Service by default.
220
+
221
+ ### Using pass for Graph credentials
222
+
223
+ On Linux, WSL and macOS, interactive Graph setup offers `pass` when it is installed
224
+ and the selected password store has a readable `.gpg-id`. The OS store is recommended
225
+ when available; if it is unavailable, setup recommends the configured pass store.
226
+ Existing profiles keep their saved credential store without prompting again.
227
+
228
+ To select it explicitly, initialize your GPG password store first, then run:
229
+
230
+ ```console
231
+ pass init GPG_KEY_ID
232
+ teams --profile work-pass init --credential-store pass --device-code
233
+ # To use a different existing store:
234
+ teams --profile other-work init --credential-store pass --pass-store-dir /path/to/password-store --device-code
235
+ ```
236
+
237
+ Before opening Microsoft sign-in for a new pass credential, the CLI checks encryption
238
+ and decryption using synthetic data in a private temporary store. The check leaves
239
+ no probe entries or Git commits in your password store. GPG may ask you to unlock
240
+ your key; configure `gpg-agent` and a suitable pinentry for your terminal or desktop.
241
+ Terminal pinentry may need `export GPG_TTY="$(tty)"`. Helper operations time out after
242
+ 60 seconds if unlocking or another operation stalls.
243
+
244
+ Tokens are passed to `pass` through stdin, and stored under
245
+ `teams-cli/<SHA-256 of profile name>`. The CLI saves `credential_store = "pass"` and
246
+ the absolute `pass_store_dir` in the profile. Changing `PASSWORD_STORE_DIR` later
247
+ will not redirect that profile's credentials. Sign-in, refresh, status and logout
248
+ use the same saved store; failures report the store or GPG problem without falling
249
+ back to another backend. Failed replacements restore the previous encrypted file.
250
+ As usual, pass manages its own local Git history if enabled; logout removes the
251
+ current entry, while older encrypted versions may remain in that history.
252
+
253
+ Use a new profile name to change credential stores or pass directories. After
254
+ verifying the new connection, sign out the old profile if you no longer need it.
255
+ `--no-login` validates the pass installation and recipient configuration without
256
+ unlocking a key or running the encryption/decryption check.
257
+
160
258
  ## Everyday commands
161
259
 
162
260
  ```console
@@ -414,7 +512,7 @@ helper route remains the default for native desktop profiles.
414
512
  Create a separate read-only profile and sign in in the window that opens:
415
513
 
416
514
  ```console
417
- teams init --profile browser --backend desktop --desktop-client browser --desktop-account work-school --yes
515
+ teams init --profile browser --backend desktop --desktop-client browser --desktop-account work-school --auto-start --yes
418
516
  # The window closes automatically after a successful chat read.
419
517
  # Teams then runs headless with the same saved sign-in:
420
518
  teams --profile browser
@@ -446,7 +544,22 @@ profile. Different ports use different browser profiles. Disconnect closes this
446
544
  browser and keeps its sign-in data. To switch between visible and headless operation,
447
545
  disconnect first. `desktop recover` closes a verified managed browser or clears a
448
546
  stale record when no listener remains. A verified browser that does not exit after
449
- closing its debugging port is stopped; unverifiable processes are left untouched.
547
+ closing its debugging port is stopped. Verified helpers are recorded before shutdown
548
+ and closed individually if they outlive it; unverifiable processes are left untouched.
549
+
550
+ Standalone CLI browser sessions persist until `desktop disconnect`. Applications can
551
+ instead use `desktop supervise`: keep its stdin pipe open, read its protocol-1 JSON
552
+ handshake, and pass the returned `client` token as `TEAMS_DESKTOP_BROWSER_CLIENT` to
553
+ CLI commands and sign-in terminals. Browsers those commands start close when their
554
+ last application user exits, including after a parent-process crash, with a 15-second
555
+ grace period so a reloaded application can reclaim its session. Existing
556
+ persistent sessions are left running, and in-flight CLI commands finish before
557
+ cleanup. The supervisor must run in its own process group, with its stdin pipe held
558
+ only by the application. Sign-in data is retained. `--keep-alive` opts newly started
559
+ sessions into persistent operation; `TEAMS_DESKTOP_BROWSER_KEEP_ALIVE=1` or `0` can
560
+ override that policy for subsequent launches without restarting the supervisor.
561
+ Explicit `desktop connect` outside supervision makes a shared session persistent.
562
+ Only macOS and Linux support this integration protocol.
450
563
 
451
564
  The CLI checks that every listener is loopback-only and belongs to the recorded
452
565
  browser process, running as you with the expected executable, debugging port and
@@ -46,23 +46,76 @@ Run `teams` in a terminal on first use, or start explicitly:
46
46
  teams init
47
47
  ```
48
48
 
49
- `teams-cli` includes a maintained multitenant Microsoft Entra public-client registration, so normal setup does not require creating an app or copying a client ID:
49
+ Choose **Work or school** or **Personal**, choose whether to enable sending, and
50
+ follow sign-in. Setup checks this machine first and gives unavailable connections
51
+ no selectable number, with an explanation of what they need. It chooses a separate
52
+ browser port and opens your inbox once chats are readable. After that, just run:
50
53
 
51
54
  ```console
52
- teams init
55
+ teams
53
56
  ```
54
57
 
55
- For a personal Microsoft account with the lightweight hidden browser:
58
+ On macOS, Linux and WSL2, work/school setup prefers a dedicated browser; personal
59
+ setup prefers the lightweight browser. Missing display support, missing executables,
60
+ invalid browser overrides and unavailable matching downloads are checked before
61
+ selection. Personal can use a full browser or Teams Desktop when lightweight mode
62
+ is unavailable. Work/school can use Teams Desktop or Microsoft Graph when needed.
63
+ When no lightweight runtime is installed, these checks query public Chrome for
64
+ Testing version metadata at `googlechromelabs.github.io`; no browser download or
65
+ Teams sign-in happens before consent.
66
+ On a Linux terminal without a display, Graph uses device-code sign-in on another device.
67
+ You explicitly approve reopening a dedicated browser
68
+ when you start the inbox. The saved sign-in is reused, and expired work/school
69
+ sign-in offers to reopen the sign-in window. Some organisations require keeping
70
+ the browser visible; minimise it instead of closing it. WSL2 needs WSLg for sign-in.
71
+ On native Windows, browser options are unavailable; use Teams Desktop or run inside
72
+ WSL2 for browser mode.
73
+
74
+ Guided setup saves connection settings only after a successful chat read, including
75
+ Graph profiles. If sending was requested, desktop/browser setup also probes the
76
+ send interface without sending a message. If that fails, you can explicitly continue
77
+ read-only; setup never silently downgrades your choice. A successful probe establishes
78
+ that the interface is available, while delivery and organisation policies are checked
79
+ when you actually send. Teams build compatibility and sign-in still need live validation.
80
+
81
+ Running setup again asks whether to connect another account or update an existing
82
+ connection. Updates preserve Graph application/tenant settings and previously granted
83
+ channel-history access. Failed Graph verification preserves the previous credential;
84
+ if saving settings fails, the credential change is rolled back. Browser setup can resume
85
+ an unfinished sign-in on the same port, or start a separate account without touching it.
86
+ Recovery errors include the exact command to close that browser.
87
+ You can forget an unfinished setup after confirmation; its browser data and saved
88
+ sign-in remain on disk, and the old browser's close command is shown. Reusing that
89
+ forgotten browser data requires explicit setup with its original `--desktop-port`.
90
+ Setup offers unfinished connections under other names when you connect another account.
91
+
92
+ Cold work-browser startup opens the inbox once chats are readable and checks sign-in
93
+ renewal in the background. A sign-out pauses sending and offers sign-in in the inbox.
94
+ Other startup-check failures keep chats readable and pause sending until you reopen
95
+ the inbox to check again. Drafts stay in memory through the sign-in detour.
96
+ Guided Graph setup disables conflicting token or permission environment overrides;
97
+ explicit flags keep their automation behavior.
98
+
99
+ **Other connection options** keeps Microsoft Graph and the running Teams Desktop
100
+ available. Microsoft Graph includes a maintained Entra public-client registration,
101
+ so normal API setup needs no app registration or copied client ID.
102
+
103
+ Scripts and explicit connection flags keep their existing behaviour. For example:
56
104
 
57
105
  ```console
58
- teams init --profile personal --backend desktop --desktop-client browser-core
106
+ teams init --backend graph
107
+ # Or configure an automatically reopened work browser explicitly:
108
+ teams init --profile work --backend desktop --desktop-client browser \
109
+ --desktop-account work-school --desktop-port 9224 --auto-start
59
110
  ```
60
111
 
61
- This downloads its browsers automatically, opens visible sign-in once, and then
62
- runs hidden. See [lightweight browser setup](#low-memory-browser-client-experimental)
63
- for sending, reconnecting, and experimental compatibility limits.
112
+ Browser profiles default to read-only; add `--allow-send` to enable sending.
113
+ Existing profiles retain their connection behaviour unless you opt in with setup
114
+ or `--auto-start`. CLI reads, JSON output, demo mode and snapshots never start a
115
+ browser automatically. See [lightweight browser setup](#low-memory-browser-client-experimental)
116
+ for personal-account compatibility limits.
64
117
 
65
- Browser PKCE is the human-friendly default. The browser talks directly to Microsoft, and the CLI never receives or stores your password. Normal sign-in requests these delegated scopes:
118
+ For Microsoft Graph profiles, browser PKCE is the default when a local browser is available. The browser talks directly to Microsoft, and the CLI never receives or stores your password. Normal Graph sign-in requests these delegated scopes:
66
119
 
67
120
  ```text
68
121
  openid profile offline_access User.Read User.ReadBasic.All
@@ -141,6 +194,51 @@ The custom app must be a public client with `http://localhost` registered for br
141
194
 
142
195
  For short-lived automation, `TEAMS_ACCESS_TOKEN` overrides the stored credential. Refresh credentials are never written to the config file.
143
196
 
197
+ Under WSL, Graph credentials use Windows DPAPI encryption for the current Windows
198
+ user through `powershell.exe`; no D-Bus or Linux Secret Service is required. Windows
199
+ executable interop must be enabled. Encrypted files live under
200
+ `%LOCALAPPDATA%\teams-cli\credentials` and are shared by WSL distributions using
201
+ the same Windows account and profile name. Existing WSL Secret Service sign-ins
202
+ require `teams auth login` again after upgrading; their old entries are not migrated
203
+ or removed. Native Linux uses Secret Service by default.
204
+
205
+ ### Using pass for Graph credentials
206
+
207
+ On Linux, WSL and macOS, interactive Graph setup offers `pass` when it is installed
208
+ and the selected password store has a readable `.gpg-id`. The OS store is recommended
209
+ when available; if it is unavailable, setup recommends the configured pass store.
210
+ Existing profiles keep their saved credential store without prompting again.
211
+
212
+ To select it explicitly, initialize your GPG password store first, then run:
213
+
214
+ ```console
215
+ pass init GPG_KEY_ID
216
+ teams --profile work-pass init --credential-store pass --device-code
217
+ # To use a different existing store:
218
+ teams --profile other-work init --credential-store pass --pass-store-dir /path/to/password-store --device-code
219
+ ```
220
+
221
+ Before opening Microsoft sign-in for a new pass credential, the CLI checks encryption
222
+ and decryption using synthetic data in a private temporary store. The check leaves
223
+ no probe entries or Git commits in your password store. GPG may ask you to unlock
224
+ your key; configure `gpg-agent` and a suitable pinentry for your terminal or desktop.
225
+ Terminal pinentry may need `export GPG_TTY="$(tty)"`. Helper operations time out after
226
+ 60 seconds if unlocking or another operation stalls.
227
+
228
+ Tokens are passed to `pass` through stdin, and stored under
229
+ `teams-cli/<SHA-256 of profile name>`. The CLI saves `credential_store = "pass"` and
230
+ the absolute `pass_store_dir` in the profile. Changing `PASSWORD_STORE_DIR` later
231
+ will not redirect that profile's credentials. Sign-in, refresh, status and logout
232
+ use the same saved store; failures report the store or GPG problem without falling
233
+ back to another backend. Failed replacements restore the previous encrypted file.
234
+ As usual, pass manages its own local Git history if enabled; logout removes the
235
+ current entry, while older encrypted versions may remain in that history.
236
+
237
+ Use a new profile name to change credential stores or pass directories. After
238
+ verifying the new connection, sign out the old profile if you no longer need it.
239
+ `--no-login` validates the pass installation and recipient configuration without
240
+ unlocking a key or running the encryption/decryption check.
241
+
144
242
  ## Everyday commands
145
243
 
146
244
  ```console
@@ -398,7 +496,7 @@ helper route remains the default for native desktop profiles.
398
496
  Create a separate read-only profile and sign in in the window that opens:
399
497
 
400
498
  ```console
401
- teams init --profile browser --backend desktop --desktop-client browser --desktop-account work-school --yes
499
+ teams init --profile browser --backend desktop --desktop-client browser --desktop-account work-school --auto-start --yes
402
500
  # The window closes automatically after a successful chat read.
403
501
  # Teams then runs headless with the same saved sign-in:
404
502
  teams --profile browser
@@ -430,7 +528,22 @@ profile. Different ports use different browser profiles. Disconnect closes this
430
528
  browser and keeps its sign-in data. To switch between visible and headless operation,
431
529
  disconnect first. `desktop recover` closes a verified managed browser or clears a
432
530
  stale record when no listener remains. A verified browser that does not exit after
433
- closing its debugging port is stopped; unverifiable processes are left untouched.
531
+ closing its debugging port is stopped. Verified helpers are recorded before shutdown
532
+ and closed individually if they outlive it; unverifiable processes are left untouched.
533
+
534
+ Standalone CLI browser sessions persist until `desktop disconnect`. Applications can
535
+ instead use `desktop supervise`: keep its stdin pipe open, read its protocol-1 JSON
536
+ handshake, and pass the returned `client` token as `TEAMS_DESKTOP_BROWSER_CLIENT` to
537
+ CLI commands and sign-in terminals. Browsers those commands start close when their
538
+ last application user exits, including after a parent-process crash, with a 15-second
539
+ grace period so a reloaded application can reclaim its session. Existing
540
+ persistent sessions are left running, and in-flight CLI commands finish before
541
+ cleanup. The supervisor must run in its own process group, with its stdin pipe held
542
+ only by the application. Sign-in data is retained. `--keep-alive` opts newly started
543
+ sessions into persistent operation; `TEAMS_DESKTOP_BROWSER_KEEP_ALIVE=1` or `0` can
544
+ override that policy for subsequent launches without restarting the supervisor.
545
+ Explicit `desktop connect` outside supervision makes a shared session persistent.
546
+ Only macOS and Linux support this integration protocol.
434
547
 
435
548
  The CLI checks that every listener is loopback-only and belongs to the recorded
436
549
  browser process, running as you with the expected executable, debugging port and