@michaelschnyder/teams-cli 0.1.0 → 0.2.0-canary.7.1.g64541e1a

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.
package/README.md CHANGED
@@ -1,248 +1,136 @@
1
1
  # teams-cli
2
2
 
3
- A safety-conscious command-line client for persistent Microsoft Teams sessions. It supports multiple tenants and users, named profiles, structured output, agent skills, and optional subject-path policies that can prevent messages from being sent to unintended chats or channels.
3
+ A command-line client that gives people and compatible coding agents access to Microsoft Teams through a persistent local browser session.
4
4
 
5
5
  > [!WARNING]
6
6
  > This project relies on undocumented Microsoft Teams behavior and a Microsoft first-party client identity. It is unsupported, may be blocked by tenant policy, and may stop working without notice. Obtain organizational approval before using it, and never run live write tests against a production tenant.
7
7
 
8
- ## Requirements
9
-
10
- - Node.js 22.20 or newer. Node.js 24 LTS is recommended.
11
- - Microsoft Edge or Google Chrome.
12
- - A Microsoft 365 account with Teams access.
13
-
14
- ### Install Node.js on Windows
15
-
16
- Open PowerShell and install the current Node.js LTS release with Windows Package Manager:
17
-
18
- ```powershell
19
- winget install --id OpenJS.NodeJS.LTS --exact --source winget
20
- ```
21
-
22
- Open a new terminal, then verify both tools:
23
-
24
- ```powershell
25
- node --version
26
- npm --version
27
- ```
28
-
29
- If `winget` is unavailable, install Microsoft App Installer or use the signed installer from the [Node.js download page](https://nodejs.org/en/download).
30
-
31
- ### Install Node.js on macOS
32
-
33
- With [Homebrew](https://brew.sh/):
34
-
35
- ```bash
36
- brew install node@24
37
- echo 'export PATH="$(brew --prefix node@24)/bin:$PATH"' >> ~/.zshrc
38
- source ~/.zshrc
39
- node --version
40
- npm --version
41
- ```
42
-
43
- Alternatively, use the signed macOS package from the [Node.js download page](https://nodejs.org/en/download).
44
-
45
- ### Install Node.js on Linux
46
-
47
- Distribution repositories may contain a Node.js version older than this CLI requires. A version manager keeps the runtime separate from system packages. The following follows the [Node.js download guidance](https://nodejs.org/en/download) using `nvm`; inspect downloaded installation scripts before running them:
48
-
49
- ```bash
50
- curl -o nvm-install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.7/install.sh
51
- less nvm-install.sh
52
- bash nvm-install.sh
53
- . "$HOME/.nvm/nvm.sh"
54
- nvm install 24
55
- node --version
56
- npm --version
57
- ```
58
-
59
- Node.js also publishes signed standalone Linux archives on its download page.
8
+ ## Quick start
60
9
 
61
- ## Install teams-cli
10
+ You need Node.js 22.20 or newer, Microsoft Edge or Google Chrome, and a Microsoft 365 account with Teams access. Node.js 24 LTS is recommended. See the [installation guide](docs/use/installation.md) for operating-system-specific setup and troubleshooting.
62
11
 
63
- Install the command globally:
12
+ ### 1. Install the CLI
64
13
 
65
14
  ```bash
66
15
  npm install --global @michaelschnyder/teams-cli
67
16
  teams-cli --version
68
- teams-cli --help
69
17
  ```
70
18
 
71
- To try it without a permanent installation:
19
+ ### 2. Choose how you will use it
72
20
 
73
- ```bash
74
- npx @michaelschnyder/teams-cli --help
75
- ```
76
-
77
- If a global install reports a permissions error, use a Node version manager instead of running npm with `sudo`. If installation succeeds but `teams-cli` is not found, run `npm prefix --global` and ensure that npm's global executable directory is on `PATH`.
78
-
79
- ## Quick start
80
-
81
- Interactive login opens a dedicated Edge profile by default:
21
+ For an agent-first setup, install the packaged skill before signing in:
82
22
 
83
23
  ```bash
84
- teams-cli --profile work --tenant YOUR_TENANT_ID auth login
85
- teams-cli --profile work auth whoami
24
+ teams-cli skills install
86
25
  ```
87
26
 
88
- The successful login records the verified tenant, user, and browser in the named profile. Subsequent commands reuse identity-isolated tokens and refresh them from the saved browser state when necessary.
27
+ For filesystem-based agents such as Codex, Claude Code, Cursor, GitHub Copilot, OpenCode, Windsurf, Gemini CLI, Pi, and generic `.agents/skills` environments, the command installs the skill directly. You can then ask the agent, for example, `Send a test message to myself via Teams`; it can guide or perform login when needed.
89
28
 
90
- Discover Teams data:
29
+ When Claude Desktop is detected, the command also creates a versioned Cowork ZIP in Downloads. Cowork requires you to upload that ZIP in **Customize > Skills > Create skill > Upload a skill** and enable it. This account-level step cannot be completed or verified by the CLI. See [Claude Cowork and other agent setup](docs/use/agent-skills.md).
91
30
 
92
- ```bash
93
- teams-cli --profile work person search "Alice" --json
94
- teams-cli --profile work chat list --json
95
- teams-cli --profile work channel list --json
96
- teams-cli --profile work message list --chat CHAT_ID --json
97
- ```
31
+ For direct console use, skip the skill and continue to login.
98
32
 
99
- Send a plain-text message after checking the selected identity and target:
33
+ ### 3. Sign in
100
34
 
101
35
  ```bash
102
- teams-cli --profile work auth whoami
103
- teams-cli --profile work policy check send --chat CHAT_ID
104
- teams-cli --profile work message send --chat CHAT_ID --body "Hello"
105
- ```
106
-
107
- Use `--channel CHANNEL_ID` instead of `--chat CHAT_ID` for channel messages. A message body can also be piped on stdin.
108
-
109
- ## Command overview
110
-
111
- ```text
112
- teams-cli [--profile NAME] [--tenant ID] [--user ID] [--browser edge|chrome]
113
-
114
- version show the installed version or upgrade it
115
- skills list, locate, install, and refresh packaged agent skills
116
- auth login, refresh, whoami, tokens, logout
117
- profile list, show, save, remove
118
- policy init, list, show, check, activate
119
- person search, get, image
120
- chat list, get
121
- channel list, get
122
- message list, get, send
36
+ teams-cli login
123
37
  ```
124
38
 
125
- Run `teams-cli <command> --help` for complete arguments and options.
126
-
127
- ### Structured output
39
+ `teams-cli login` is the convenient alias for `teams-cli auth login`. It opens a dedicated Microsoft Edge profile by default, or a dedicated Google Chrome profile when selected. It does not reuse your normal browser profile or its signed-in session. The CLI discovers the Teams tenant and user, then saves them in the implicit `default` profile. Most users never need to provide a tenant ID or create a named profile.
128
40
 
129
- Person, chat, channel, and message commands that return data support `--json`. JSON payloads stay on stdout. Progress, warnings, update notices, and sanitized debug output stay on stderr, so scripts can safely pipe stdout.
41
+ On a first interactive login, the CLI offers to install the skill first when it detects an agent environment and no identity or managed skill. Declining continues login. Automated and non-interactive login never shows this prompt.
130
42
 
131
- ## Profiles and local state
43
+ ### 4. Add a workspace policy
132
44
 
133
- Profiles provide defaults; global flags override them for one command. When no profile is selected, the profile named `default` is used.
45
+ Policies are optional but recommended for agent-assisted work. From the workspace the agent will operate in, run:
134
46
 
135
47
  ```bash
136
- teams-cli profile list
137
- teams-cli profile show work
138
- teams-cli --tenant TENANT_ID --user USER_ID --browser chrome profile save work
139
- teams-cli profile remove work
48
+ teams-cli policy edit --open
140
49
  ```
141
50
 
142
- Configuration, authentication, browser state, policies, update state, and managed skill-installation records live under `~/.teams-cli/`. Secret-bearing files and directories are created with owner-only permissions on supported operating systems.
51
+ Choose which people, group chats, and channels may be read or posted to, then save and activate the policy. Policies are cooperative CLI-level safeguards: they help prevent accidental access and posts through `teams-cli`, but they are not an operating-system sandbox or a server-side Teams permission.
143
52
 
144
- See [profiles and precedence](docs/use/profiles.md) and [authentication and token handling](docs/use/authentication.md).
53
+ See [workspace policies](docs/use/policies.md) for the editor, audit mode, activation, manual editing and deactivation, overlapping policies, and the security boundary.
145
54
 
146
- ## Policies
55
+ ### 5. Use Teams
147
56
 
148
- Policies are optional. Inactive policies audit and warn without enforcing; active policies enforce the intersection of all matching subject-path rules. A malformed policy store puts authenticated operations into fail-safe mode. Active policies cannot be deactivated through this CLI.
57
+ Ask a compatible agent naturally after installing the skill, for example:
149
58
 
150
- ```bash
151
- teams-cli --profile work policy init project-agent
152
- teams-cli policy show project-agent
153
- teams-cli policy check send --chat CHAT_ID
154
- teams-cli policy activate project-agent
155
- ```
156
-
157
- Review and edit the generated allowlists before activation. See [workspace policies](docs/use/policies.md) and the [security model](https://github.com/michaelschnyder/teams-cli/blob/main/docs/build/security-model.md).
158
-
159
- ### Token export
160
-
161
- The existing authentication commands can print raw bearer tokens or decoded JWT claims:
162
-
163
- ```bash
164
- teams-cli --profile work auth tokens
165
- teams-cli --profile work auth token access
166
- teams-cli --profile work auth tokens --decode
59
+ ```text
60
+ Find my chat with Alice and summarize the latest five messages.
61
+ Draft a reply to the Project Phoenix channel, but show it to me before sending.
167
62
  ```
168
63
 
169
- Applicable active policies can deny raw token export. Treat exported tokens like passwords: another HTTP client can use them outside the CLI's cooperative policy checks. Never paste them into prompts, logs, issues, or source files.
170
-
171
- ## Agent skills
172
-
173
- The npm package includes skills that teach compatible coding agents how to use this CLI safely. Auto-detection supports Codex, Claude Code, Cursor, GitHub Copilot, OpenCode, Windsurf, Gemini CLI, Pi, and generic `.agents/skills` environments.
64
+ Or use the CLI directly:
174
65
 
175
66
  ```bash
176
- teams-cli skills list
177
- teams-cli skills path
178
- teams-cli skills install
67
+ teams-cli auth whoami
68
+ teams-cli person search "Alice" --json
69
+ teams-cli chat search "Alice" --json
70
+ teams-cli channel list --json
71
+ teams-cli message list --chat CHAT_ID --json
72
+ teams-cli message send --person alice@example.com --body "Hello"
179
73
  ```
180
74
 
181
- When several environments are detected, the skills are installed into all of them. Specify a target when detection is unavailable:
75
+ For an existing group chat or channel, use `--chat CHAT_ID` or `--channel CHANNEL_ID`. You can optionally preview a known target with `teams-cli policy check send`; the send command always enforces the applicable policy again immediately before posting. Sending is externally visible and the CLI has no delete or undo command.
182
76
 
183
- ```bash
184
- teams-cli skills install codex
185
- teams-cli skills install github-copilot --project
186
- teams-cli skills install agents --name teams-cli
187
- teams-cli skills install all
188
- teams-cli skills install --dir /custom/skills
77
+ ```mermaid
78
+ flowchart LR
79
+ install[Install teams-cli] --> route{How will you use it?}
80
+ route -->|Agent| skill[Install the agent skill]
81
+ route -->|Console| login[Sign in once]
82
+ skill --> login
83
+ login --> policy[Recommended: add a workspace policy]
84
+ policy --> use[Ask an agent or run commands]
189
85
  ```
190
86
 
191
- Initial installation does not replace an existing `SKILL.md`; use `--force` when replacement is intentional. Successful destinations are recorded. Installed copies are managed by the CLI and are refreshed by `teams-cli skills reinstall` and after a successful CLI upgrade, replacing local edits in those copies.
87
+ ## Important concepts
192
88
 
193
- ## Updates and upgrades
89
+ ### Default session
194
90
 
195
- At startup, the CLI may launch a detached npm registry check. It runs at most once per hour, does not delay the command, and stores only timestamps and version numbers. If a newer version is found, a notice is printed to stderr on the next invocation.
91
+ `teams-cli login` discovers and records the verified tenant, user, and browser in the `default` profile. The longer `teams-cli auth login` form remains available. Named profiles and explicit `--tenant` or `--user` flags are optional tools for people who deliberately maintain more than one identity. Profiles select configuration; they are not permission boundaries. See [authentication](docs/use/authentication.md) and [optional profiles](docs/use/profiles.md).
196
92
 
197
- Disable checks with either environment variable:
93
+ ### Agent skill
198
94
 
199
- ```bash
200
- export NO_UPDATE_NOTIFIER=1
201
- # or
202
- export TEAMS_CLI_DISABLE_UPDATE_CHECK=1
203
- ```
95
+ The skill gives an agent the operational knowledge that command help alone cannot provide: discover current IDs before using them, verify the active identity, keep JSON payloads separate from diagnostics, optionally preview policy decisions, and stop on denials. Installed copies can be refreshed when the CLI is upgraded.
204
96
 
205
- Checks are automatically disabled in CI. Upgrade the global npm installation and refresh recorded skills with:
97
+ ### Cooperative policies
206
98
 
207
- ```bash
208
- teams-cli version --upgrade
209
- ```
99
+ Policies are YAML files matched against the canonical working-directory path. Inactive policies audit and warn; active policies constrain identities, message reads, posts, and raw-token export. All matching active policies must allow an operation, so overlapping policies can only preserve or narrow access.
210
100
 
211
- This command updates the global npm package. It does not modify a project-local or one-off `npx` installation.
101
+ These safeguards apply to operations made through this CLI. A sufficiently privileged local process can change policy files, and a bearer token used by another HTTP client is outside the CLI's checks. Read-only file permissions add protection against accidental edits but do not make a policy immutable.
212
102
 
213
- ## Troubleshooting
103
+ ### Structured output
214
104
 
215
- - `teams-cli: command not found`: check `npm prefix --global` and your `PATH`.
216
- - Browser launch fails: install Edge or Chrome and select it with `--browser edge|chrome`.
217
- - Login succeeds but Teams access fails: confirm that the account has a Teams-enabled Microsoft 365 license.
218
- - Stored identity is rejected: run `auth login` again for the selected tenant, user, and profile.
219
- - An agent environment is not detected: pass its name explicitly to `skills install`.
220
- - Use `--debug` for sanitized request method, endpoint, status, duration, and retry diagnostics. Headers, tokens, cookies, query values, and bodies are not logged.
105
+ Person, chat, channel, and message commands support `--json`. JSON payloads stay on stdout, while progress, warnings, update notices, and sanitized diagnostics stay on stderr. Scripts and agents can therefore consume stdout without mixing it with status text.
221
106
 
222
- ## Uninstall
107
+ ## Command reference
223
108
 
224
- Remove the global command:
109
+ | Command | Purpose | Examples and details |
110
+ | --- | --- | --- |
111
+ | `login` | Sign in using the default session; alias for `auth login` | [Authentication](docs/use/authentication.md) |
112
+ | `version` | Inspect build provenance, check for updates, or select the notification channel | [Installation and upgrades](docs/use/installation.md) |
113
+ | `skills` | List, locate, install, and refresh the packaged agent skill | [Agent skill installation](docs/use/agent-skills.md) |
114
+ | `doctor` | Diagnose the local runtime, browser, session, and managed skills without changing them | [Installation and upgrades](docs/use/installation.md#troubleshooting) |
115
+ | `auth` | Login, refresh, inspect, export tokens, or logout | [Authentication](docs/use/authentication.md) |
116
+ | `profile` | Manage optional named identity selectors | [Profiles](docs/use/profiles.md) |
117
+ | `policy` | Create, inspect, check, activate, and edit safeguards | [Policies](docs/use/policies.md) |
118
+ | `person` | Search people, inspect profiles, and retrieve images | [Command examples](docs/use/commands.md) |
119
+ | `chat` | Search, explicitly enumerate, and inspect chats | [Command examples](docs/use/commands.md) |
120
+ | `channel` | List and inspect teams and channels | [Command examples](docs/use/commands.md) |
121
+ | `message` | List, get, and send messages | [Command examples](docs/use/commands.md) |
225
122
 
226
- ```bash
227
- npm uninstall --global @michaelschnyder/teams-cli
228
- ```
123
+ Run `teams-cli --help` or `teams-cli <command> --help` for the complete options supported by the installed version.
229
124
 
230
- Uninstalling the npm package intentionally leaves authentication and configuration data in `~/.teams-cli/`. Run `auth logout` for each stored identity before uninstalling. Remove `~/.teams-cli/` manually only when you intend to delete every remaining profile, token, browser session, policy, update record, and managed-skill record.
125
+ ## Local state and security
231
126
 
232
- Installed agent skill copies live outside `~/.teams-cli/` and are not deleted automatically.
127
+ Configuration, authentication, dedicated browser state, policies, update state, and managed skill-installation records live under `~/.teams-cli/`. Secret-bearing files and directories use owner-only permissions on supported operating systems.
233
128
 
234
- ## Development
129
+ Raw bearer tokens can be exported by authentication commands when applicable policies allow it. Treat them like passwords: never paste them into prompts, logs, issues, or source files. See the [security model](docs/build/security-model.md) for the complete trust boundary.
235
130
 
236
- ```bash
237
- npm install
238
- npm run check
239
- npm test
240
- npm run build
241
- npm run package:check
242
- npm run package:smoke
243
- ```
131
+ ## Contributing
244
132
 
245
- See [CONTRIBUTING.md](https://github.com/michaelschnyder/teams-cli/blob/main/CONTRIBUTING.md), [architecture](https://github.com/michaelschnyder/teams-cli/blob/main/docs/build/architecture.md), [testing](https://github.com/michaelschnyder/teams-cli/blob/main/docs/build/testing.md), and the [release guide](docs/releasing.md).
133
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing, and contribution guidance.
246
134
 
247
135
  ## License
248
136
 
package/dist/auth.js CHANGED
@@ -12,6 +12,14 @@ const defaultDependencies = {
12
12
  exchangeToken: exchangeInitialToken,
13
13
  now: () => new Date(),
14
14
  };
15
+ export class InteractiveLoginRequiredError extends Error {
16
+ code;
17
+ constructor(code) {
18
+ super(`Microsoft needs an interactive sign-in (${code}).`);
19
+ this.code = code;
20
+ this.name = "InteractiveLoginRequiredError";
21
+ }
22
+ }
15
23
  const execFileAsync = promisify(execFile);
16
24
  export async function passwordFromCommand(command) {
17
25
  if (!isAbsolute(command))
@@ -113,7 +121,7 @@ function createStoredSession(tokens, exchanged, browser, expectedTenant, now) {
113
121
  }
114
122
  function interactiveRefreshError(error) {
115
123
  if (error instanceof OAuthRedirectError) {
116
- throw new Error(`Microsoft could not refresh the session without interaction (${error.code}). Run \`teams-cli auth login\`.`);
124
+ throw new InteractiveLoginRequiredError(error.code);
117
125
  }
118
126
  throw error;
119
127
  }
@@ -0,0 +1,34 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "0.2.0-canary.7.1.g64541e1a",
4
+ "channel": "canary",
5
+ "builtAt": "2026-09-04T10:54:53.370Z",
6
+ "source": {
7
+ "branch": "codex/fix-canary-provenance-race",
8
+ "commit": "64541e1a22a00f539a23ee66d67aa70d33f47f8c",
9
+ "commitUrl": "https://github.com/michaelschnyder/teams-cli/commit/64541e1a22a00f539a23ee66d67aa70d33f47f8c",
10
+ "pullRequest": 14,
11
+ "pullRequestUrl": "https://github.com/michaelschnyder/teams-cli/pull/14",
12
+ "author": "michaelschnyder"
13
+ },
14
+ "trigger": {
15
+ "kind": "merged-pull-request",
16
+ "actor": "michaelschnyder"
17
+ },
18
+ "runner": {
19
+ "name": "GitHub Actions 1000001086",
20
+ "os": "Linux",
21
+ "architecture": "X64"
22
+ },
23
+ "workflow": {
24
+ "runId": "33865033307",
25
+ "runNumber": "7",
26
+ "runAttempt": "1",
27
+ "url": "https://github.com/michaelschnyder/teams-cli/actions/runs/33865033307"
28
+ },
29
+ "releaseNotes": {
30
+ "title": "Fix canary provenance race after rapid merges",
31
+ "body": "## Summary\n\n- derive publication provenance from the commit actually checked out for the completed CI run\n- reject a canary when the checkout and workflow-run commit differ\n- defer commit-author lookup until the authoritative source commit is selected\n- cover the rapid-merge mismatch with a regression test\n\n## Verification\n\n- `node --check scripts/prepare-publication.mjs`\n- `node --import tsx --test test/release-metadata.test.ts`\n- `npm run check`\n- `CI=true npm test` (105 tests)\n- `npm run build`\n- `npm run package:check`\n- `npm run package:smoke`\n- GitHub CI on Ubuntu, macOS, and Windows; the Ubuntu dependency audit passed",
32
+ "url": "https://github.com/michaelschnyder/teams-cli/pull/14"
33
+ }
34
+ }