@topolo/sdk 0.2.11 → 0.3.0

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/dist/index.cjs CHANGED
@@ -143,7 +143,6 @@ var SERVICES = {
143
143
  nexus: "https://nexus-api.topolo.app",
144
144
  notify: "https://notify.topolo.app",
145
145
  one: "https://one.topolo.app",
146
- "one.ai": "https://ai.one.topolo.app",
147
146
  p2p: "https://p2p.topolo.app",
148
147
  pay: "https://pay.topolo.app",
149
148
  people: "https://people.topolo.app",
@@ -160,27 +159,27 @@ var SERVICES = {
160
159
  web: "https://web-api.topolo.app"
161
160
  };
162
161
  var PLATFORM_SERVICE_IDS = {
163
- books: "srv_topolo_books",
164
- bugfix: "srv_topolo_bugfix",
165
- compose: "srv_topolo_compose",
166
- consent: "srv_topolo_consent",
162
+ books: "srv_0g260hbN8oqv",
163
+ bugfix: "srv_kQ1t8qUSDgNs",
164
+ compose: "srv_aR3ETYmgygmd",
165
+ consent: "srv_8FIGR7Q7zP9r",
167
166
  crm: "srv_iCwM4jGXcwlj",
168
- customer_success: "srv_topolo_success",
169
- developers: "svc_topolo_developers",
170
- director: "srv_topolo_director",
171
- flow: "srv_topolo_flow",
172
- forms: "srv_topolo_forms",
173
- home: "srv_topolo_home",
174
- insights: "srv_topolo_insights",
175
- inventory: "srv_topolo_inventory",
176
- localize: "srv_topolo_localize",
177
- notify: "svc_topolo_notify",
178
- p2p: "srv_topolo_p2p",
179
- people: "srv_topolo_people",
180
- sign: "srv_topolo_sign",
167
+ customer_success: "srv_RWpOxkgZdZbH",
168
+ developers: "srv_NjDq9G9qyyjr",
169
+ director: "srv_wRCnLLbtvmVT",
170
+ flow: "srv_GBCuKkHhnRXv",
171
+ forms: "srv_UE7IcGe80J5o",
172
+ home: "srv_hE6HBldVzjth",
173
+ insights: "srv_DgbBMwWSIhmC",
174
+ inventory: "srv_hmvjbv3ZxDnh",
175
+ localize: "srv_Ze1g9OmXuZjF",
176
+ notify: "srv_9pRdkIjYyKX0",
177
+ p2p: "srv_4BzeLqH0wCve",
178
+ people: "srv_VDMBAonA5fKb",
179
+ sign: "srv_Bd8pRw5ZqRBT",
181
180
  status: "srv_topolo_status",
182
- survey: "srv_topolo_survey",
183
- voice: "srv_topolo_voice"
181
+ survey: "srv_RCOi7CJkwf7R",
182
+ voice: "srv_BZANHkshGAK5"
184
183
  };
185
184
 
186
185
  // src/applications.generated.ts
@@ -188,13 +187,13 @@ var APPLICATIONS = {
188
187
  "admin": {
189
188
  "id": "admin",
190
189
  "appDir": "TopoloAdmin",
191
- "name": "topoloadmin",
190
+ "name": "topolo-admin",
192
191
  "packageName": "topolo-admin",
193
192
  "productionUrl": "https://admin.topolo.app",
194
193
  "services": [],
195
194
  "deployTargets": [
196
195
  {
197
- "name": "topoloadmin",
196
+ "name": "topolo-admin",
198
197
  "kind": "pages",
199
198
  "apiUrl": null,
200
199
  "domains": [
@@ -217,7 +216,7 @@ var APPLICATIONS = {
217
216
  "deployTargets": [
218
217
  {
219
218
  "name": "topolo-agent",
220
- "kind": "pages",
219
+ "kind": "worker",
221
220
  "apiUrl": null,
222
221
  "domains": [
223
222
  "agent.topolo.app"
@@ -551,7 +550,7 @@ var APPLICATIONS = {
551
550
  },
552
551
  {
553
552
  "name": "topolo-crm-app",
554
- "kind": "pages",
553
+ "kind": "worker",
555
554
  "apiUrl": null,
556
555
  "domains": [
557
556
  "crm.topolo.app"
@@ -749,7 +748,7 @@ var APPLICATIONS = {
749
748
  "deployTargets": [
750
749
  {
751
750
  "name": "topolo-forecast",
752
- "kind": "pages",
751
+ "kind": "worker",
753
752
  "apiUrl": null,
754
753
  "domains": [
755
754
  "forecast.topolo.app"
@@ -877,7 +876,7 @@ var APPLICATIONS = {
877
876
  "deployTargets": [
878
877
  {
879
878
  "name": "topolo-learn",
880
- "kind": "pages",
879
+ "kind": "worker",
881
880
  "apiUrl": null,
882
881
  "domains": [
883
882
  "learn.topolo.app"
@@ -933,7 +932,7 @@ var APPLICATIONS = {
933
932
  "deployTargets": [
934
933
  {
935
934
  "name": "topolo-mail",
936
- "kind": "workers",
935
+ "kind": "worker",
937
936
  "apiUrl": "https://mail.topolo.app",
938
937
  "domains": [
939
938
  "mail.topolo.app"
@@ -978,7 +977,7 @@ var APPLICATIONS = {
978
977
  },
979
978
  {
980
979
  "name": "topolo-mdm-console",
981
- "kind": "pages",
980
+ "kind": "worker",
982
981
  "apiUrl": null,
983
982
  "domains": [
984
983
  "mdm.topolo.app"
@@ -1002,7 +1001,7 @@ var APPLICATIONS = {
1002
1001
  "deployTargets": [
1003
1002
  {
1004
1003
  "name": "topolo-messaging",
1005
- "kind": "workers",
1004
+ "kind": "worker",
1006
1005
  "apiUrl": "https://messages.topolo.app",
1007
1006
  "domains": [
1008
1007
  "messages.topolo.app"
@@ -1012,7 +1011,7 @@ var APPLICATIONS = {
1012
1011
  },
1013
1012
  {
1014
1013
  "name": "topolo-messaging-dispatch",
1015
- "kind": "workers",
1014
+ "kind": "worker",
1016
1015
  "apiUrl": null,
1017
1016
  "domains": [],
1018
1017
  "routes": [],
@@ -1032,7 +1031,7 @@ var APPLICATIONS = {
1032
1031
  "deployTargets": [
1033
1032
  {
1034
1033
  "name": "topolo-nexus-dashboard",
1035
- "kind": "pages",
1034
+ "kind": "worker",
1036
1035
  "apiUrl": null,
1037
1036
  "domains": [
1038
1037
  "nexus.topolo.app"
@@ -1092,20 +1091,9 @@ var APPLICATIONS = {
1092
1091
  "packageName": "topolo-oneclick-sso",
1093
1092
  "productionUrl": "https://one.topolo.app",
1094
1093
  "services": [
1095
- "one",
1096
- "one.ai"
1094
+ "one"
1097
1095
  ],
1098
1096
  "deployTargets": [
1099
- {
1100
- "name": "ai-chat-rag",
1101
- "kind": "worker",
1102
- "apiUrl": "https://ai.one.topolo.app",
1103
- "domains": [
1104
- "ai.one.topolo.app"
1105
- ],
1106
- "routes": [],
1107
- "serviceId": "one.ai"
1108
- },
1109
1097
  {
1110
1098
  "name": "topolo-one",
1111
1099
  "kind": "pages",
@@ -1259,7 +1247,7 @@ var APPLICATIONS = {
1259
1247
  },
1260
1248
  {
1261
1249
  "name": "quro-ui",
1262
- "kind": "pages",
1250
+ "kind": "worker",
1263
1251
  "apiUrl": null,
1264
1252
  "domains": [
1265
1253
  "quro.topolo.app"
@@ -1281,7 +1269,7 @@ var APPLICATIONS = {
1281
1269
  "deployTargets": [
1282
1270
  {
1283
1271
  "name": "topolo-roadmapper",
1284
- "kind": "pages",
1272
+ "kind": "worker",
1285
1273
  "apiUrl": null,
1286
1274
  "domains": [
1287
1275
  "roadmapper.topolo.app"
@@ -1337,7 +1325,7 @@ var APPLICATIONS = {
1337
1325
  "deployTargets": [
1338
1326
  {
1339
1327
  "name": "topolo-social-studio",
1340
- "kind": "pages",
1328
+ "kind": "worker",
1341
1329
  "apiUrl": null,
1342
1330
  "domains": [
1343
1331
  "studio.topolo.app"
@@ -1441,7 +1429,7 @@ var APPLICATIONS = {
1441
1429
  "deployTargets": [
1442
1430
  {
1443
1431
  "name": "topolo-support",
1444
- "kind": "workers",
1432
+ "kind": "worker",
1445
1433
  "apiUrl": "https://support.topolo.app",
1446
1434
  "domains": [
1447
1435
  "support.topolo.app"
@@ -1533,7 +1521,7 @@ var APPLICATIONS = {
1533
1521
  },
1534
1522
  {
1535
1523
  "name": "topolo-web-studio",
1536
- "kind": "pages",
1524
+ "kind": "worker",
1537
1525
  "apiUrl": null,
1538
1526
  "domains": [
1539
1527
  "web.topolo.app"
@@ -1937,7 +1925,9 @@ function resolveServiceUrl(service, overrides) {
1937
1925
 
1938
1926
  // src/client.ts
1939
1927
  var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
1940
- var TopoloClient = class {
1928
+ var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
1929
+ var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
1930
+ var TopoloClient = class _TopoloClient {
1941
1931
  credential;
1942
1932
  agent;
1943
1933
  serviceUrls;
@@ -1945,6 +1935,20 @@ var TopoloClient = class {
1945
1935
  timeoutMs;
1946
1936
  fetchImpl;
1947
1937
  debug;
1938
+ /**
1939
+ * Process-wide cache for slug → service-id lookups. Keyed by
1940
+ * `${authBaseUrl}|${slug}` so multiple `TopoloClient` instances pointing at
1941
+ * the same Auth share, but staging vs prod don't poison each other.
1942
+ * Cleared via `TopoloClient.clearServiceIdCache()` if a test needs it.
1943
+ */
1944
+ static serviceIdCache = /* @__PURE__ */ new Map();
1945
+ /**
1946
+ * Drop the slug→service-id cache. Test-only — production callers should
1947
+ * let the 5-minute TTL expire naturally.
1948
+ */
1949
+ static clearServiceIdCache() {
1950
+ _TopoloClient.serviceIdCache.clear();
1951
+ }
1948
1952
  constructor(options) {
1949
1953
  if (!options.credential) throw new TopoloAuthError("credential is required");
1950
1954
  if (!options.agent?.clientName) throw new TopoloAuthError("agent.clientName is required");
@@ -2059,6 +2063,66 @@ var TopoloClient = class {
2059
2063
  });
2060
2064
  return parsed;
2061
2065
  }
2066
+ /**
2067
+ * Resolve a service-slug → opaque service-id via TopoloAuth.
2068
+ *
2069
+ * Replaces the SDK-baked `PLATFORM_SERVICE_IDS` map (deprecated in 0.3.0,
2070
+ * removed in 0.4.0). Slug shape accepted: either the canonical Auth slug
2071
+ * (e.g. `topolo-notify`) or the SDK short id (`notify`) — Auth's resolver
2072
+ * understands both.
2073
+ *
2074
+ * Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
2075
+ * results (404) are cached for 60s so a typo doesn't hot-loop the
2076
+ * resolver. Returns null when the slug isn't registered — callers decide
2077
+ * whether to throw.
2078
+ *
2079
+ * No credential is sent: the endpoint is public (slugs aren't secret).
2080
+ * This keeps the resolver usable during early bootstrap before a caller
2081
+ * has acquired an access token.
2082
+ */
2083
+ async getServiceIdBySlug(slug) {
2084
+ if (typeof slug !== "string") return null;
2085
+ const normalized = slug.trim().toLowerCase();
2086
+ if (!normalized) return null;
2087
+ const authBase = resolveServiceUrl("auth", this.serviceUrls);
2088
+ const cacheKey = `${authBase}|${normalized}`;
2089
+ const now = Date.now();
2090
+ const cached = _TopoloClient.serviceIdCache.get(cacheKey);
2091
+ if (cached && cached.expiresAt > now) {
2092
+ return cached.value;
2093
+ }
2094
+ const url = new URL(
2095
+ `/api/services/by-slug/${encodeURIComponent(normalized)}`,
2096
+ authBase.endsWith("/") ? authBase : `${authBase}/`
2097
+ ).toString();
2098
+ let res;
2099
+ try {
2100
+ res = await this.fetchImpl(url, {
2101
+ method: "GET",
2102
+ headers: { Accept: "application/json" }
2103
+ });
2104
+ } catch {
2105
+ return null;
2106
+ }
2107
+ if (res.status === 404) {
2108
+ _TopoloClient.serviceIdCache.set(cacheKey, {
2109
+ value: null,
2110
+ expiresAt: now + NEGATIVE_CACHE_TTL_MS
2111
+ });
2112
+ return null;
2113
+ }
2114
+ if (!res.ok) {
2115
+ return null;
2116
+ }
2117
+ const body = await res.json().catch(() => null);
2118
+ const serviceId = body?.data?.service_id;
2119
+ const value = typeof serviceId === "string" && serviceId ? serviceId : null;
2120
+ _TopoloClient.serviceIdCache.set(cacheKey, {
2121
+ value,
2122
+ expiresAt: now + POSITIVE_CACHE_TTL_MS
2123
+ });
2124
+ return value;
2125
+ }
2062
2126
  /**
2063
2127
  * Introspect the current credential. Returns the caller's resolved identity,
2064
2128
  * organization, and permission set. Used by CLI `whoami` and by MCP to gate
package/dist/index.d.cts CHANGED
@@ -62,7 +62,6 @@ declare const SERVICES: {
62
62
  readonly nexus: "https://nexus-api.topolo.app";
63
63
  readonly notify: "https://notify.topolo.app";
64
64
  readonly one: "https://one.topolo.app";
65
- readonly "one.ai": "https://ai.one.topolo.app";
66
65
  readonly p2p: "https://p2p.topolo.app";
67
66
  readonly pay: "https://pay.topolo.app";
68
67
  readonly people: "https://people.topolo.app";
@@ -79,18 +78,26 @@ declare const SERVICES: {
79
78
  readonly web: "https://web-api.topolo.app";
80
79
  };
81
80
  type ServiceId = keyof typeof SERVICES;
81
+ /**
82
+ * @deprecated since 0.3.0 — opaque service ids are no longer baked into the
83
+ * SDK. Use `TopoloClient.getServiceIdBySlug(slug)` which hits
84
+ * `GET /api/services/by-slug/:slug` on TopoloAuth at runtime. This map is
85
+ * still populated as a build-time snapshot for backward compatibility and
86
+ * will be removed in 0.4.0. Stale entries are expected — do not rely on
87
+ * presence/absence for catalog membership.
88
+ */
82
89
  declare const PLATFORM_SERVICE_IDS: Partial<Record<ServiceId, string>>;
83
90
 
84
91
  declare const APPLICATIONS: {
85
92
  readonly admin: {
86
93
  readonly id: "admin";
87
94
  readonly appDir: "TopoloAdmin";
88
- readonly name: "topoloadmin";
95
+ readonly name: "topolo-admin";
89
96
  readonly packageName: "topolo-admin";
90
97
  readonly productionUrl: "https://admin.topolo.app";
91
98
  readonly services: readonly [];
92
99
  readonly deployTargets: readonly [{
93
- readonly name: "topoloadmin";
100
+ readonly name: "topolo-admin";
94
101
  readonly kind: "pages";
95
102
  readonly apiUrl: null;
96
103
  readonly domains: readonly ["admin.topolo.app"];
@@ -107,7 +114,7 @@ declare const APPLICATIONS: {
107
114
  readonly services: readonly ["agent"];
108
115
  readonly deployTargets: readonly [{
109
116
  readonly name: "topolo-agent";
110
- readonly kind: "pages";
117
+ readonly kind: "worker";
111
118
  readonly apiUrl: null;
112
119
  readonly domains: readonly ["agent.topolo.app"];
113
120
  readonly routes: readonly [];
@@ -343,7 +350,7 @@ declare const APPLICATIONS: {
343
350
  readonly serviceId: "crm";
344
351
  }, {
345
352
  readonly name: "topolo-crm-app";
346
- readonly kind: "pages";
353
+ readonly kind: "worker";
347
354
  readonly apiUrl: null;
348
355
  readonly domains: readonly ["crm.topolo.app"];
349
356
  readonly routes: readonly [];
@@ -485,7 +492,7 @@ declare const APPLICATIONS: {
485
492
  readonly services: readonly ["forecast"];
486
493
  readonly deployTargets: readonly [{
487
494
  readonly name: "topolo-forecast";
488
- readonly kind: "pages";
495
+ readonly kind: "worker";
489
496
  readonly apiUrl: null;
490
497
  readonly domains: readonly ["forecast.topolo.app"];
491
498
  readonly routes: readonly [];
@@ -572,7 +579,7 @@ declare const APPLICATIONS: {
572
579
  readonly services: readonly ["learn"];
573
580
  readonly deployTargets: readonly [{
574
581
  readonly name: "topolo-learn";
575
- readonly kind: "pages";
582
+ readonly kind: "worker";
576
583
  readonly apiUrl: null;
577
584
  readonly domains: readonly ["learn.topolo.app"];
578
585
  readonly routes: readonly [];
@@ -611,7 +618,7 @@ declare const APPLICATIONS: {
611
618
  readonly services: readonly ["mail"];
612
619
  readonly deployTargets: readonly [{
613
620
  readonly name: "topolo-mail";
614
- readonly kind: "workers";
621
+ readonly kind: "worker";
615
622
  readonly apiUrl: "https://mail.topolo.app";
616
623
  readonly domains: readonly ["mail.topolo.app"];
617
624
  readonly routes: readonly ["mail.topolo.app"];
@@ -643,7 +650,7 @@ declare const APPLICATIONS: {
643
650
  readonly serviceId: "mdm";
644
651
  }, {
645
652
  readonly name: "topolo-mdm-console";
646
- readonly kind: "pages";
653
+ readonly kind: "worker";
647
654
  readonly apiUrl: null;
648
655
  readonly domains: readonly ["mdm.topolo.app"];
649
656
  readonly routes: readonly ["mdm.topolo.app"];
@@ -659,14 +666,14 @@ declare const APPLICATIONS: {
659
666
  readonly services: readonly ["messaging"];
660
667
  readonly deployTargets: readonly [{
661
668
  readonly name: "topolo-messaging";
662
- readonly kind: "workers";
669
+ readonly kind: "worker";
663
670
  readonly apiUrl: "https://messages.topolo.app";
664
671
  readonly domains: readonly ["messages.topolo.app"];
665
672
  readonly routes: readonly [];
666
673
  readonly serviceId: "messaging";
667
674
  }, {
668
675
  readonly name: "topolo-messaging-dispatch";
669
- readonly kind: "workers";
676
+ readonly kind: "worker";
670
677
  readonly apiUrl: null;
671
678
  readonly domains: readonly [];
672
679
  readonly routes: readonly [];
@@ -682,7 +689,7 @@ declare const APPLICATIONS: {
682
689
  readonly services: readonly ["nexus"];
683
690
  readonly deployTargets: readonly [{
684
691
  readonly name: "topolo-nexus-dashboard";
685
- readonly kind: "pages";
692
+ readonly kind: "worker";
686
693
  readonly apiUrl: null;
687
694
  readonly domains: readonly ["nexus.topolo.app"];
688
695
  readonly routes: readonly [];
@@ -727,15 +734,8 @@ declare const APPLICATIONS: {
727
734
  readonly name: "topolo-oneclick-sso";
728
735
  readonly packageName: "topolo-oneclick-sso";
729
736
  readonly productionUrl: "https://one.topolo.app";
730
- readonly services: readonly ["one", "one.ai"];
737
+ readonly services: readonly ["one"];
731
738
  readonly deployTargets: readonly [{
732
- readonly name: "ai-chat-rag";
733
- readonly kind: "worker";
734
- readonly apiUrl: "https://ai.one.topolo.app";
735
- readonly domains: readonly ["ai.one.topolo.app"];
736
- readonly routes: readonly [];
737
- readonly serviceId: "one.ai";
738
- }, {
739
739
  readonly name: "topolo-one";
740
740
  readonly kind: "pages";
741
741
  readonly apiUrl: null;
@@ -838,7 +838,7 @@ declare const APPLICATIONS: {
838
838
  readonly serviceId: "quro.redirect";
839
839
  }, {
840
840
  readonly name: "quro-ui";
841
- readonly kind: "pages";
841
+ readonly kind: "worker";
842
842
  readonly apiUrl: null;
843
843
  readonly domains: readonly ["quro.topolo.app"];
844
844
  readonly routes: readonly [];
@@ -854,7 +854,7 @@ declare const APPLICATIONS: {
854
854
  readonly services: readonly ["roadmapper"];
855
855
  readonly deployTargets: readonly [{
856
856
  readonly name: "topolo-roadmapper";
857
- readonly kind: "pages";
857
+ readonly kind: "worker";
858
858
  readonly apiUrl: null;
859
859
  readonly domains: readonly ["roadmapper.topolo.app"];
860
860
  readonly routes: readonly [];
@@ -893,7 +893,7 @@ declare const APPLICATIONS: {
893
893
  readonly services: readonly ["social_studio"];
894
894
  readonly deployTargets: readonly [{
895
895
  readonly name: "topolo-social-studio";
896
- readonly kind: "pages";
896
+ readonly kind: "worker";
897
897
  readonly apiUrl: null;
898
898
  readonly domains: readonly ["studio.topolo.app"];
899
899
  readonly routes: readonly [];
@@ -969,7 +969,7 @@ declare const APPLICATIONS: {
969
969
  readonly services: readonly ["support"];
970
970
  readonly deployTargets: readonly [{
971
971
  readonly name: "topolo-support";
972
- readonly kind: "workers";
972
+ readonly kind: "worker";
973
973
  readonly apiUrl: "https://support.topolo.app";
974
974
  readonly domains: readonly ["support.topolo.app"];
975
975
  readonly routes: readonly ["support.topolo.app/*"];
@@ -1031,7 +1031,7 @@ declare const APPLICATIONS: {
1031
1031
  readonly serviceId: null;
1032
1032
  }, {
1033
1033
  readonly name: "topolo-web-studio";
1034
- readonly kind: "pages";
1034
+ readonly kind: "worker";
1035
1035
  readonly apiUrl: null;
1036
1036
  readonly domains: readonly ["web.topolo.app"];
1037
1037
  readonly routes: readonly [];
@@ -1262,6 +1262,18 @@ declare class TopoloClient {
1262
1262
  private readonly timeoutMs;
1263
1263
  private readonly fetchImpl;
1264
1264
  private readonly debug?;
1265
+ /**
1266
+ * Process-wide cache for slug → service-id lookups. Keyed by
1267
+ * `${authBaseUrl}|${slug}` so multiple `TopoloClient` instances pointing at
1268
+ * the same Auth share, but staging vs prod don't poison each other.
1269
+ * Cleared via `TopoloClient.clearServiceIdCache()` if a test needs it.
1270
+ */
1271
+ private static readonly serviceIdCache;
1272
+ /**
1273
+ * Drop the slug→service-id cache. Test-only — production callers should
1274
+ * let the 5-minute TTL expire naturally.
1275
+ */
1276
+ static clearServiceIdCache(): void;
1265
1277
  constructor(options: TopoloClientOptions);
1266
1278
  private emit;
1267
1279
  /**
@@ -1270,6 +1282,24 @@ declare class TopoloClient {
1270
1282
  * use and for the generic `topolo api` / MCP passthrough tool.
1271
1283
  */
1272
1284
  request<T = unknown>(opts: RequestOptions): Promise<T>;
1285
+ /**
1286
+ * Resolve a service-slug → opaque service-id via TopoloAuth.
1287
+ *
1288
+ * Replaces the SDK-baked `PLATFORM_SERVICE_IDS` map (deprecated in 0.3.0,
1289
+ * removed in 0.4.0). Slug shape accepted: either the canonical Auth slug
1290
+ * (e.g. `topolo-notify`) or the SDK short id (`notify`) — Auth's resolver
1291
+ * understands both.
1292
+ *
1293
+ * Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
1294
+ * results (404) are cached for 60s so a typo doesn't hot-loop the
1295
+ * resolver. Returns null when the slug isn't registered — callers decide
1296
+ * whether to throw.
1297
+ *
1298
+ * No credential is sent: the endpoint is public (slugs aren't secret).
1299
+ * This keeps the resolver usable during early bootstrap before a caller
1300
+ * has acquired an access token.
1301
+ */
1302
+ getServiceIdBySlug(slug: string): Promise<string | null>;
1273
1303
  /**
1274
1304
  * Introspect the current credential. Returns the caller's resolved identity,
1275
1305
  * organization, and permission set. Used by CLI `whoami` and by MCP to gate