feat(microsoft): scaffold zero-config client_id + better setup error - #41
Merged
Conversation
… client id
Two changes to make createMicrosoftPlugin() work zero-config once the
ThinkFleet-owned Azure AD app is registered:
1. New constant `THINKFLEET_DEFAULT_CLIENT_ID` in auth.ts — currently
empty string (intentional placeholder), but the resolution order is
already wired up:
explicit config.clientId
→ AGENTMARK_MS_CLIENT_ID env var
→ THINKFLEET_DEFAULT_CLIENT_ID baked default
Filling in the constant later is a one-line PR.
2. Massively improved error message when client_id is missing. The old
one was "Register an Azure AD app". The new one walks the user
through the actual portal flow + the exact permission set they
need to grant.
```
Microsoft Graph client ID is not set.
One-time setup:
1. Open https://entra.microsoft.com → App registrations → New registration
2. Account types: "Accounts in any organizational directory and
personal Microsoft accounts"
3. Authentication → Advanced settings → "Allow public client flows" → Yes
4. API permissions → Add → Microsoft Graph → Delegated:
Mail.Send, Mail.ReadWrite, Files.ReadWrite, offline_access, User.Read
5. Grant admin consent
Then either:
- Set AGENTMARK_MS_CLIENT_ID=<your-app-id> in your environment, OR
- Pass `clientId: "<your-app-id>"` to createMicrosoftPlugin()
```
The first time an agent hits this error, the human gets a working
recipe instead of having to dig through docs.
Constraint flagged in the code: NEVER hardcode a tenant-specific
client id. The default must be multi-tenant or zero-config falls
apart for users on other tenants.
Tests unchanged — the existing /client ID is not set/i regex assertion
still passes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Two changes to make `createMicrosoftPlugin()` work zero-config once the ThinkFleet-owned Azure AD app is registered, and dramatically better UX in the meantime.
1. `THINKFLEET_DEFAULT_CLIENT_ID` placeholder
New constant in `auth.ts`, currently `''` — intentional placeholder. The resolution chain is already wired:
```
explicit config.clientId
→ AGENTMARK_MS_CLIENT_ID env var
→ THINKFLEET_DEFAULT_CLIENT_ID baked default
```
Filling in the constant later is a one-line PR (literally one string replacement). The hard work of getting the resolution order right is done now.
Why the placeholder isn't filled in yet: I can't register an Azure AD app under ThinkFleet's tenant — that requires Microsoft account credentials and admin access I don't have. The PR that fills in the real id will be ~3 lines: replace the empty string, bump the doc, ship.
2. Actionable error message
Old:
New:
```
Microsoft Graph client ID is not set.
One-time setup:
personal Microsoft accounts"
Mail.Send, Mail.ReadWrite, Files.ReadWrite, offline_access, User.Read
Then either:
```
When this error fires (and it will, on every fresh install until #2 ships or the operator brings their own app), the human gets a working recipe instead of having to dig through docs.
Test plan
🤖 Generated with Claude Code