@lanes-sh/link 0.6.11 → 0.7.1

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 (201) hide show
  1. package/README.md +62 -45
  2. package/instructions/skills/lanes-link/SKILL.md +25 -0
  3. package/package.json +3 -2
  4. package/src/audit/conformance.ts +1 -1
  5. package/src/cli/argv.ts +14 -1
  6. package/src/cli/commands/connect/acquire.ts +100 -0
  7. package/src/cli/commands/connect/custom/index.ts +1 -1
  8. package/src/cli/commands/connect/declare.ts +19 -0
  9. package/src/cli/commands/connect/index.ts +54 -56
  10. package/src/cli/commands/connect/requirements.ts +23 -1
  11. package/src/cli/commands/connect/setup.ts +1 -1
  12. package/src/cli/commands/connect/variables.ts +220 -0
  13. package/src/cli/commands/knowledge/index.ts +22 -4
  14. package/src/cli/commands/knowledge/migrate.ts +61 -43
  15. package/src/cli/commands/operate/tools.ts +1 -1
  16. package/src/cli/commands/owner/entities.ts +244 -0
  17. package/src/cli/commands/owner/shared.ts +14 -0
  18. package/src/cli/commands/owner/vault.ts +2 -2
  19. package/src/cli/commands/owner.ts +13 -3
  20. package/src/cli/commands/setup.ts +12 -0
  21. package/src/cli/config-edit.ts +16 -6
  22. package/src/cli/config-repair.ts +22 -3
  23. package/src/cli/dispatch-owner.ts +30 -1
  24. package/src/cli/main.ts +2 -1
  25. package/src/cli/runtime/open.ts +14 -7
  26. package/src/cli/runtime/registry.ts +6 -1
  27. package/src/cli/selection.ts +11 -0
  28. package/src/cli/usage.ts +13 -2
  29. package/src/connectivity/auth/strategy/index.ts +1 -1
  30. package/src/connectivity/capability.ts +1 -1
  31. package/src/connectivity/context.ts +1 -1
  32. package/src/connectivity/index.ts +1 -1
  33. package/src/connectivity/mail/attachments.ts +42 -73
  34. package/src/connectivity/mail/content-type.ts +71 -0
  35. package/src/connectivity/mail/index.ts +1 -1
  36. package/src/connectivity/manifest/provider.ts +50 -0
  37. package/src/connectivity/manifest/variables.ts +173 -0
  38. package/src/connectivity/transports/factory.ts +74 -1
  39. package/src/connectivity/transports/http/index.ts +8 -2
  40. package/src/connectivity/transports/http/keys.ts +83 -0
  41. package/src/connectivity/transports/imap/attachment.ts +53 -10
  42. package/src/connectivity/transports/imap/capabilities.ts +28 -0
  43. package/src/connectivity/transports/imap/download.ts +111 -0
  44. package/src/connectivity/transports/imap/index.ts +13 -0
  45. package/src/connectivity/transports/imap/operations.ts +1 -0
  46. package/src/deployments/adapters/s3.ts +1 -1
  47. package/src/deployments/gcp/provision.ts +1 -1
  48. package/src/deployments/knowledge.ts +44 -18
  49. package/src/deployments/prepare.ts +1 -1
  50. package/src/deployments/serving.ts +1 -1
  51. package/src/dispatch/dispatch.ts +17 -10
  52. package/src/dispatch/staging.ts +76 -1
  53. package/src/profile/knowledge.ts +19 -11
  54. package/src/profile/schema.ts +2 -2
  55. package/src/providers/README.md +189 -0
  56. package/src/providers/airtable/index.ts +10 -0
  57. package/src/providers/algolia/index.ts +10 -0
  58. package/src/providers/amplitude/index.ts +10 -0
  59. package/src/providers/apify/index.ts +10 -0
  60. package/src/providers/asana/index.ts +10 -0
  61. package/src/providers/assets/provider.ts +11 -4
  62. package/src/providers/atlassian/index.ts +19 -0
  63. package/src/providers/attio/index.ts +10 -0
  64. package/src/providers/betterstack/index.ts +10 -0
  65. package/src/providers/box/index.ts +64 -0
  66. package/src/providers/brightdata/index.ts +10 -0
  67. package/src/providers/buildkite/index.ts +10 -0
  68. package/src/providers/bunq/index.ts +2 -2
  69. package/src/providers/calendly/index.ts +10 -0
  70. package/src/providers/canva/index.ts +10 -0
  71. package/src/providers/circleci/index.ts +10 -0
  72. package/src/providers/clickup/index.ts +10 -0
  73. package/src/providers/close/index.ts +10 -0
  74. package/src/providers/cloudflare_bindings/index.ts +14 -0
  75. package/src/providers/cloudflare_observability/index.ts +10 -0
  76. package/src/providers/contentful/index.ts +10 -0
  77. package/src/providers/custom/load.ts +1 -1
  78. package/src/providers/datadog/index.ts +10 -0
  79. package/src/providers/discord/index.ts +1 -1
  80. package/src/providers/discord/specs/discord.v10.json +0 -88
  81. package/src/providers/discord/specs/vendor.ts +1 -1
  82. package/src/providers/dropbox/index.ts +10 -0
  83. package/src/providers/entities/catalogue.ts +366 -0
  84. package/src/providers/entities/find.ts +279 -0
  85. package/src/providers/entities/provider.ts +338 -0
  86. package/src/providers/entities/render.ts +142 -0
  87. package/src/providers/entities/store.ts +276 -0
  88. package/src/providers/entities/writes.ts +279 -0
  89. package/src/providers/example/provider.ts +1 -1
  90. package/src/providers/expensify/index.ts +10 -0
  91. package/src/providers/fastmail/calendar/index.ts +21 -0
  92. package/src/providers/fastmail/contacts/index.ts +17 -0
  93. package/src/providers/fastmail/index.ts +4 -0
  94. package/src/providers/fastmail/mail/index.ts +38 -0
  95. package/src/providers/fastmail/shared/setup.ts +52 -0
  96. package/src/providers/figma/index.ts +10 -0
  97. package/src/providers/fireflies/index.ts +10 -0
  98. package/src/providers/flagsmith/index.ts +10 -0
  99. package/src/providers/gamma/index.ts +10 -0
  100. package/src/providers/github/index.ts +2 -2
  101. package/src/providers/google/gmail/attachment.ts +16 -1
  102. package/src/providers/google/gmail-imap/index.ts +7 -2
  103. package/src/providers/google/shared/oauth.ts +1 -1
  104. package/src/providers/google/shared/service-account.ts +1 -1
  105. package/src/providers/google/shared/setup.ts +1 -1
  106. package/src/providers/google/specs/calendar.v3.json +0 -32
  107. package/src/providers/google/specs/docs.v1.json +0 -76
  108. package/src/providers/google/specs/drive.v3.json +0 -32
  109. package/src/providers/google/specs/gmail.v1.json +0 -76
  110. package/src/providers/google/specs/people.v1.json +0 -77
  111. package/src/providers/google/specs/sheets.v4.json +0 -76
  112. package/src/providers/google/specs/tasks.v1.json +0 -76
  113. package/src/providers/grafana/index.ts +10 -0
  114. package/src/providers/heroku/index.ts +10 -0
  115. package/src/providers/hubspot/index.ts +75 -0
  116. package/src/providers/hygraph/index.ts +10 -0
  117. package/src/providers/icloud/mail/index.ts +5 -0
  118. package/src/providers/icloud/shared/setup.ts +1 -1
  119. package/src/providers/index.ts +255 -0
  120. package/src/providers/insightly/index.ts +10 -0
  121. package/src/providers/jam/index.ts +10 -0
  122. package/src/providers/klaviyo/index.ts +10 -0
  123. package/src/providers/mailbox/index.ts +87 -0
  124. package/src/providers/memory/provider.ts +3 -8
  125. package/src/providers/mercury/index.ts +10 -0
  126. package/src/providers/microsoft/calendar/index.ts +49 -0
  127. package/src/providers/microsoft/contacts/index.ts +50 -0
  128. package/src/providers/microsoft/drive/index.ts +62 -0
  129. package/src/providers/microsoft/index.ts +12 -0
  130. package/src/providers/microsoft/mail/index.ts +76 -0
  131. package/src/providers/microsoft/shared/oauth.ts +58 -0
  132. package/src/providers/microsoft/shared/scopes.ts +56 -0
  133. package/src/providers/microsoft/shared/setup.ts +45 -0
  134. package/src/providers/microsoft/specs/microsoft-todo.v1.json +755 -0
  135. package/src/providers/microsoft/specs/onedrive.v1.json +993 -0
  136. package/src/providers/microsoft/specs/outlook-calendar.v1.json +1743 -0
  137. package/src/providers/microsoft/specs/outlook-contacts.v1.json +430 -0
  138. package/src/providers/microsoft/specs/outlook-mail.v1.json +901 -0
  139. package/src/providers/microsoft/specs/vendor.ts +232 -0
  140. package/src/providers/microsoft/todo/index.ts +54 -0
  141. package/src/providers/miro/index.ts +10 -0
  142. package/src/providers/mixpanel/index.ts +10 -0
  143. package/src/providers/monday/index.ts +10 -0
  144. package/src/providers/mux/index.ts +10 -0
  145. package/src/providers/navan/index.ts +10 -0
  146. package/src/providers/neon/index.ts +10 -0
  147. package/src/providers/netlify/index.ts +10 -0
  148. package/src/providers/nextcloud/calendar/index.ts +28 -0
  149. package/src/providers/nextcloud/contacts/index.ts +18 -0
  150. package/src/providers/nextcloud/index.ts +3 -0
  151. package/src/providers/nextcloud/shared/setup.ts +59 -0
  152. package/src/providers/owner.ts +15 -3
  153. package/src/providers/paddle/index.ts +10 -0
  154. package/src/providers/paypal/index.ts +10 -0
  155. package/src/providers/posthog/index.ts +10 -0
  156. package/src/providers/prisma/index.ts +10 -0
  157. package/src/providers/ramp/index.ts +10 -0
  158. package/src/providers/recurly/index.ts +10 -0
  159. package/src/providers/reddit/index.ts +1 -1
  160. package/src/providers/remote/index.ts +10 -0
  161. package/src/providers/render/index.ts +35 -0
  162. package/src/providers/replicate/index.ts +10 -0
  163. package/src/providers/resend/index.ts +10 -0
  164. package/src/providers/riverside/index.ts +10 -0
  165. package/src/providers/rootly/index.ts +10 -0
  166. package/src/providers/rudderstack/index.ts +10 -0
  167. package/src/providers/salesloft/index.ts +10 -0
  168. package/src/providers/sanity/index.ts +10 -0
  169. package/src/providers/scopes.ts +2 -0
  170. package/src/providers/sentry/index.ts +10 -0
  171. package/src/providers/setup/plan.ts +11 -0
  172. package/src/providers/setup/provider.ts +12 -0
  173. package/src/providers/shared/openapi.ts +70 -0
  174. package/src/providers/shared/slug.ts +28 -0
  175. package/src/providers/shared/vendor-operations.ts +43 -1
  176. package/src/providers/shared/vendor-spec.ts +98 -17
  177. package/src/providers/shortcut/index.ts +10 -0
  178. package/src/providers/slack/index.ts +2 -2
  179. package/src/providers/square/index.ts +10 -0
  180. package/src/providers/storyblok/index.ts +10 -0
  181. package/src/providers/stripe/index.ts +10 -0
  182. package/src/providers/supabase/index.ts +10 -0
  183. package/src/providers/tasks/store.ts +2 -7
  184. package/src/providers/tavily/index.ts +10 -0
  185. package/src/providers/todoist/index.ts +10 -0
  186. package/src/providers/untested.ts +105 -0
  187. package/src/providers/vault/provider.ts +1 -1
  188. package/src/providers/vercel/index.ts +10 -0
  189. package/src/providers/vimeo/index.ts +10 -0
  190. package/src/providers/webflow/index.ts +10 -0
  191. package/src/providers/whimsical/index.ts +10 -0
  192. package/src/providers/wix/index.ts +10 -0
  193. package/src/providers/workable/index.ts +10 -0
  194. package/src/providers/yahoo_mail/index.ts +73 -0
  195. package/src/providers/zapier/index.ts +10 -0
  196. package/src/providers/zoho_mail/index.ts +79 -0
  197. package/src/secrets/document.ts +1 -1
  198. package/src/server/attachments.ts +129 -5
  199. package/src/server/index.ts +3 -3
  200. package/src/server/mcp/instructions.ts +88 -18
  201. package/src/server/stdio.ts +1 -1
@@ -0,0 +1,76 @@
1
+ import { defineProvider } from '#connectivity';
2
+ import {
3
+ CALENDAR_SCOPES,
4
+ CONTACTS_SCOPES,
5
+ FILES_SCOPES,
6
+ GRAPH_BASE_URL,
7
+ MAIL_SCOPES,
8
+ MICROSOFT_APP,
9
+ MICROSOFT_AUTHORIZE_URL,
10
+ MICROSOFT_IDENTITY,
11
+ MICROSOFT_TOKEN_URL,
12
+ TODO_SCOPES,
13
+ specPath,
14
+ } from '../shared/oauth.ts';
15
+ import { microsoftSetup } from '../shared/setup.ts';
16
+
17
+ /**
18
+ * Outlook mail, through Microsoft Graph.
19
+ *
20
+ * The REST half of the Microsoft family, and the reason there is no IMAP one
21
+ * beside it: Microsoft retired basic authentication for Outlook.com IMAP, so an
22
+ * app password is not a route here the way it is for iCloud, Fastmail, or a
23
+ * personal Gmail. Graph with a browser sign-in is what works.
24
+ *
25
+ * `send_message` is a vendored operation rather than authored code, unlike
26
+ * Gmail's — Graph composes the message from JSON, so nothing here has to
27
+ * assemble RFC 2822. What it does not do is attachments: Graph carries those as
28
+ * base64 inside the message, which is the thing ADR-017 exists to avoid, so the
29
+ * field is deliberately absent from the vendored body rather than offered and
30
+ * expensive.
31
+ */
32
+ export const outlookMail = defineProvider({
33
+ id: 'outlook_mail',
34
+ name: 'Outlook Mail',
35
+ description:
36
+ 'Read, search, file, and send mail in an Outlook or Microsoft 365 mailbox, via Microsoft Graph.',
37
+ connector: {
38
+ kind: 'http',
39
+ // Graph carries its version in the path of the server URL, like Drive and
40
+ // unlike Sheets. `cli/tools.test.ts` checks this equals the spec's own
41
+ // `servers[0].url`.
42
+ base_url: GRAPH_BASE_URL,
43
+ openapi: specPath('outlook-mail.v1.json'),
44
+ },
45
+ auth: {
46
+ kind: 'oauth',
47
+ registration: 'manual',
48
+ app: MICROSOFT_APP,
49
+ // Declared rather than discovered. An `http` connector has no metadata
50
+ // document to read — a REST API does not announce where its authorization
51
+ // server lives — so the two endpoints are part of the manifest.
52
+ authorize_url: MICROSOFT_AUTHORIZE_URL,
53
+ token_url: MICROSOFT_TOKEN_URL,
54
+ scopes: MAIL_SCOPES,
55
+ revoke_url: 'https://account.live.com/consent/Manage',
56
+ },
57
+ identity: MICROSOFT_IDENTITY,
58
+ setup: microsoftSetup('Outlook Mail', MAIL_SCOPES),
59
+ // Keyed on the capability name as it is *served* — dots, not underscores.
60
+ // Graph's operationIds are `me.ListMessages` and nothing strips the `me.`,
61
+ // because `shortenName` removes the provider id and the provider is not
62
+ // called "me". A key that misses does not error: it withholds every argument
63
+ // and reads exactly like working redaction.
64
+ redact: {
65
+ // Never `search` or `filter`: a query is content, and "who did I email
66
+ // about the diagnosis" is the whole message.
67
+ 'me.ListMessages': ['top', 'orderby', 'select'],
68
+ 'me.GetMessages': ['message-id', 'select'],
69
+ 'me.UpdateMessages': ['message-id', 'isRead', 'categories', 'flag', 'importance'],
70
+ 'me.ListMailFolders': ['top', 'orderby', 'select'],
71
+ 'me.messages.ListAttachments': ['message-id', 'top', 'orderby', 'select'],
72
+ 'me.messages.GetAttachments': ['message-id', 'attachment-id', 'select'],
73
+ // Nothing. The recipients, the subject, and the body are the message.
74
+ 'me.sendMail': ['saveToSentItems'],
75
+ },
76
+ });
@@ -0,0 +1,58 @@
1
+ /** The `oauth_apps` entry every Microsoft provider authorises against. */
2
+ export const MICROSOFT_APP = 'microsoft';
3
+
4
+ /**
5
+ * One app registration, five providers.
6
+ *
7
+ * Microsoft Graph is a single API behind mail, calendars, contacts, files and
8
+ * to-do, so unlike Google — where each product has its own client and its own
9
+ * consent screen — there is one Entra registration here and the providers differ
10
+ * only in what they ask it for. The token still lands per provider, exactly as
11
+ * Gmail's and Drive's do: `app` moves where the *client* comes from, never where
12
+ * the tokens go, so connecting Outlook mail does not silently grant OneDrive.
13
+ */
14
+
15
+ /** `common` rather than a tenant id: personal accounts and work accounts both. */
16
+ export const MICROSOFT_AUTHORIZE_URL =
17
+ 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
18
+ export const MICROSOFT_TOKEN_URL = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
19
+
20
+ /**
21
+ * Asked for by every provider, and neither reaches a service.
22
+ *
23
+ * `offline_access` is not optional and is the one to get wrong: Microsoft issues
24
+ * no refresh token without it, so the connection authorises cleanly, works for
25
+ * about an hour, and then stops. That is the same failure Google's
26
+ * `access_type=offline` exists to prevent, and it is worth naming because the
27
+ * successful-looking response is what makes it hard to debug an hour later.
28
+ *
29
+ * `User.Read` is what the identity probe reads — the account's own name and
30
+ * address, so a connection can be labelled with whose it is. It reaches no
31
+ * mailbox, no calendar, and no file.
32
+ */
33
+ export const MICROSOFT_BASE_SCOPES = ['offline_access', 'User.Read'] as const;
34
+
35
+ export const MAIL_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Mail.ReadWrite', 'Mail.Send'];
36
+ export const CALENDAR_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Calendars.ReadWrite'];
37
+ export const CONTACTS_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Contacts.Read'];
38
+ export const FILES_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Files.ReadWrite'];
39
+ export const TODO_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Tasks.ReadWrite'];
40
+
41
+ /**
42
+ * Whose account this is, for the label a connection is listed under.
43
+ *
44
+ * `userPrincipalName` rather than `mail`: a personal Microsoft account often has
45
+ * no `mail` at all, and a null there would send `connect` to its "which account
46
+ * is this?" fallback on exactly the accounts this is most useful for.
47
+ */
48
+ export const MICROSOFT_IDENTITY = {
49
+ kind: 'http' as const,
50
+ url: 'https://graph.microsoft.com/v1.0/me',
51
+ field: 'userPrincipalName',
52
+ };
53
+
54
+ /** Graph is one host and one version, for all five. */
55
+ export const GRAPH_BASE_URL = 'https://graph.microsoft.com/v1.0';
56
+
57
+ export const specPath = (file: string): string =>
58
+ new URL(`../specs/${file}`, import.meta.url).pathname;
@@ -0,0 +1,56 @@
1
+ import type { ScopeMeaning } from '../../scopes.ts';
2
+
3
+ /**
4
+ * What the Microsoft Graph scopes we ship actually permit, in plain words.
5
+ *
6
+ * Vendor knowledge, so it lives with the vendor — the same reasoning as
7
+ * `../../google/shared/scopes.ts`, and the same confinement: nothing routes on
8
+ * this, and a scope missing from the table is printed unannotated rather than
9
+ * mis-described.
10
+ */
11
+ export const MICROSOFT_SCOPE_MEANINGS: Record<string, ScopeMeaning> = {
12
+ offline_access: {
13
+ meaning:
14
+ 'keep the connection working without sending you to a browser again — Microsoft issues no refresh token without it',
15
+ },
16
+ 'User.Read': {
17
+ meaning: 'your name and address, so this connection can be labelled with whose it is. No mail, calendar, or files',
18
+ },
19
+ // Graph's mail scopes are coarser than Gmail's. There is no equivalent of
20
+ // `gmail.metadata` or a per-message grant, so reading one message means the
21
+ // grant reaches every message — which is exactly why `gmail.modify` is on this
22
+ // list too.
23
+ 'Mail.ReadWrite': {
24
+ meaning: 'read, file, and modify any message in the mailbox; no permanent delete',
25
+ broad: true,
26
+ },
27
+ 'Mail.Read': { meaning: 'read any message in the mailbox' },
28
+ // Broad for where it lands rather than what it reaches. A sent message leaves
29
+ // the account, arrives as the person, and cannot be recalled — the same
30
+ // argument that puts Reddit's three on the broad list.
31
+ 'Mail.Send': {
32
+ meaning: 'send mail as you — it leaves the account under your name and cannot be recalled',
33
+ broad: true,
34
+ },
35
+ 'Calendars.ReadWrite': {
36
+ meaning: 'read and write every event in every calendar on the account, including invitations sent to others',
37
+ broad: true,
38
+ },
39
+ 'Calendars.Read': { meaning: 'read every event in every calendar on the account' },
40
+ 'Contacts.Read': { meaning: 'read the address book. Read-only — nothing here writes a contact' },
41
+ // Broad, and the only one here that is broad for want of a narrower option.
42
+ // Google Drive is reached with `drive.file`, which covers files this app made
43
+ // or the person picked and nothing else; Graph publishes no equivalent, so the
44
+ // smallest grant that can create a folder is one that reaches every file in
45
+ // the drive.
46
+ 'Files.ReadWrite': {
47
+ meaning: 'read and write every file in your OneDrive — Microsoft publishes no per-file equivalent of Google\'s drive.file',
48
+ broad: true,
49
+ },
50
+ 'Files.Read': { meaning: 'read every file in your OneDrive' },
51
+ 'Tasks.ReadWrite': {
52
+ meaning: 'read and write every list and task in Microsoft To Do',
53
+ broad: true,
54
+ },
55
+ 'Tasks.Read': { meaning: 'read every list and task in Microsoft To Do' },
56
+ };
@@ -0,0 +1,45 @@
1
+ import { MICROSOFT_APP } from './oauth.ts';
2
+
3
+ /**
4
+ * The console walkthrough, shared by all five providers.
5
+ *
6
+ * Parameterised by product name and by the permissions that product asks for,
7
+ * because the registration is one app and the consent is per provider — someone
8
+ * connecting only To Do should not be told to tick mail permissions.
9
+ *
10
+ * A registration of the operator's own, with no broker behind it. Microsoft does
11
+ * not offer dynamic client registration, so a client has to exist before the
12
+ * browser opens; until Lanes operates one, that client is theirs. `--own-client`
13
+ * is not a flag here, it is the only route — which is the `reddit` shape, and
14
+ * the reason `setup.prompts` carries `scope: shared` entries rather than a
15
+ * pasted token.
16
+ */
17
+ export const microsoftSetup = (product: string, permissions: readonly string[]) => ({
18
+ summary:
19
+ `${product} authorises in a browser against an app registration of your own in Microsoft Entra. ` +
20
+ `Registering one is free and takes a few minutes; it is a public client, so there is no secret ` +
21
+ `to keep. The same registration covers Outlook mail, calendar, contacts, OneDrive and To Do — ` +
22
+ `you do this once, not once per provider.`,
23
+ docs: 'https://lanes.sh/docs/link/connect',
24
+ docs_url: 'https://entra.microsoft.com',
25
+ steps: [
26
+ 'Open https://entra.microsoft.com and go to Applications → App registrations → New registration.',
27
+ 'Name it "Lanes Link". Under "Supported account types", pick the option that includes personal Microsoft accounts if this is an @outlook.com or @hotmail.com address — the default is work accounts only, and choosing it is what makes a personal account fail at sign-in rather than at registration.',
28
+ 'Under "Redirect URI", choose the platform "Mobile and desktop applications" and enter exactly: http://localhost — no port. Microsoft accepts any port on a loopback redirect for this platform, which is what lets connect listen on whichever one is free.',
29
+ 'Register, then copy the "Application (client) ID" from the overview page. That is the value asked for below.',
30
+ 'Leave "Certificates & secrets" alone. This is a public client: a secret shipped to a program someone runs is not a secret, so none is created and none is asked for.',
31
+ `Permissions are requested at sign-in rather than configured here, so there is nothing to add under "API permissions" first. ${product} asks for: ${permissions.join(', ')}.`,
32
+ ],
33
+ troubleshooting:
34
+ 'AADSTS50011 means the redirect URI does not match: the registration needs the platform "Mobile and desktop applications" with http://localhost, not the "Web" platform, which pins the whole URL including the port. ' +
35
+ 'AADSTS50020 means the account type is wrong — a personal Microsoft account signing in to a registration made for work accounts only. Change it under Authentication → Supported account types and re-run: lanes link connect <provider> --replace.',
36
+ prompts: [
37
+ {
38
+ key: 'client_id',
39
+ label: 'Application (client) ID',
40
+ secret: false,
41
+ scope: 'shared' as const,
42
+ credential_ref: `${MICROSOFT_APP}/client_id`,
43
+ },
44
+ ],
45
+ });