@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.d.ts 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
package/dist/index.js CHANGED
@@ -88,7 +88,6 @@ var SERVICES = {
88
88
  nexus: "https://nexus-api.topolo.app",
89
89
  notify: "https://notify.topolo.app",
90
90
  one: "https://one.topolo.app",
91
- "one.ai": "https://ai.one.topolo.app",
92
91
  p2p: "https://p2p.topolo.app",
93
92
  pay: "https://pay.topolo.app",
94
93
  people: "https://people.topolo.app",
@@ -105,27 +104,27 @@ var SERVICES = {
105
104
  web: "https://web-api.topolo.app"
106
105
  };
107
106
  var PLATFORM_SERVICE_IDS = {
108
- books: "srv_topolo_books",
109
- bugfix: "srv_topolo_bugfix",
110
- compose: "srv_topolo_compose",
111
- consent: "srv_topolo_consent",
107
+ books: "srv_0g260hbN8oqv",
108
+ bugfix: "srv_kQ1t8qUSDgNs",
109
+ compose: "srv_aR3ETYmgygmd",
110
+ consent: "srv_8FIGR7Q7zP9r",
112
111
  crm: "srv_iCwM4jGXcwlj",
113
- customer_success: "srv_topolo_success",
114
- developers: "svc_topolo_developers",
115
- director: "srv_topolo_director",
116
- flow: "srv_topolo_flow",
117
- forms: "srv_topolo_forms",
118
- home: "srv_topolo_home",
119
- insights: "srv_topolo_insights",
120
- inventory: "srv_topolo_inventory",
121
- localize: "srv_topolo_localize",
122
- notify: "svc_topolo_notify",
123
- p2p: "srv_topolo_p2p",
124
- people: "srv_topolo_people",
125
- sign: "srv_topolo_sign",
112
+ customer_success: "srv_RWpOxkgZdZbH",
113
+ developers: "srv_NjDq9G9qyyjr",
114
+ director: "srv_wRCnLLbtvmVT",
115
+ flow: "srv_GBCuKkHhnRXv",
116
+ forms: "srv_UE7IcGe80J5o",
117
+ home: "srv_hE6HBldVzjth",
118
+ insights: "srv_DgbBMwWSIhmC",
119
+ inventory: "srv_hmvjbv3ZxDnh",
120
+ localize: "srv_Ze1g9OmXuZjF",
121
+ notify: "srv_9pRdkIjYyKX0",
122
+ p2p: "srv_4BzeLqH0wCve",
123
+ people: "srv_VDMBAonA5fKb",
124
+ sign: "srv_Bd8pRw5ZqRBT",
126
125
  status: "srv_topolo_status",
127
- survey: "srv_topolo_survey",
128
- voice: "srv_topolo_voice"
126
+ survey: "srv_RCOi7CJkwf7R",
127
+ voice: "srv_BZANHkshGAK5"
129
128
  };
130
129
 
131
130
  // src/applications.generated.ts
@@ -133,13 +132,13 @@ var APPLICATIONS = {
133
132
  "admin": {
134
133
  "id": "admin",
135
134
  "appDir": "TopoloAdmin",
136
- "name": "topoloadmin",
135
+ "name": "topolo-admin",
137
136
  "packageName": "topolo-admin",
138
137
  "productionUrl": "https://admin.topolo.app",
139
138
  "services": [],
140
139
  "deployTargets": [
141
140
  {
142
- "name": "topoloadmin",
141
+ "name": "topolo-admin",
143
142
  "kind": "pages",
144
143
  "apiUrl": null,
145
144
  "domains": [
@@ -162,7 +161,7 @@ var APPLICATIONS = {
162
161
  "deployTargets": [
163
162
  {
164
163
  "name": "topolo-agent",
165
- "kind": "pages",
164
+ "kind": "worker",
166
165
  "apiUrl": null,
167
166
  "domains": [
168
167
  "agent.topolo.app"
@@ -496,7 +495,7 @@ var APPLICATIONS = {
496
495
  },
497
496
  {
498
497
  "name": "topolo-crm-app",
499
- "kind": "pages",
498
+ "kind": "worker",
500
499
  "apiUrl": null,
501
500
  "domains": [
502
501
  "crm.topolo.app"
@@ -694,7 +693,7 @@ var APPLICATIONS = {
694
693
  "deployTargets": [
695
694
  {
696
695
  "name": "topolo-forecast",
697
- "kind": "pages",
696
+ "kind": "worker",
698
697
  "apiUrl": null,
699
698
  "domains": [
700
699
  "forecast.topolo.app"
@@ -822,7 +821,7 @@ var APPLICATIONS = {
822
821
  "deployTargets": [
823
822
  {
824
823
  "name": "topolo-learn",
825
- "kind": "pages",
824
+ "kind": "worker",
826
825
  "apiUrl": null,
827
826
  "domains": [
828
827
  "learn.topolo.app"
@@ -878,7 +877,7 @@ var APPLICATIONS = {
878
877
  "deployTargets": [
879
878
  {
880
879
  "name": "topolo-mail",
881
- "kind": "workers",
880
+ "kind": "worker",
882
881
  "apiUrl": "https://mail.topolo.app",
883
882
  "domains": [
884
883
  "mail.topolo.app"
@@ -923,7 +922,7 @@ var APPLICATIONS = {
923
922
  },
924
923
  {
925
924
  "name": "topolo-mdm-console",
926
- "kind": "pages",
925
+ "kind": "worker",
927
926
  "apiUrl": null,
928
927
  "domains": [
929
928
  "mdm.topolo.app"
@@ -947,7 +946,7 @@ var APPLICATIONS = {
947
946
  "deployTargets": [
948
947
  {
949
948
  "name": "topolo-messaging",
950
- "kind": "workers",
949
+ "kind": "worker",
951
950
  "apiUrl": "https://messages.topolo.app",
952
951
  "domains": [
953
952
  "messages.topolo.app"
@@ -957,7 +956,7 @@ var APPLICATIONS = {
957
956
  },
958
957
  {
959
958
  "name": "topolo-messaging-dispatch",
960
- "kind": "workers",
959
+ "kind": "worker",
961
960
  "apiUrl": null,
962
961
  "domains": [],
963
962
  "routes": [],
@@ -977,7 +976,7 @@ var APPLICATIONS = {
977
976
  "deployTargets": [
978
977
  {
979
978
  "name": "topolo-nexus-dashboard",
980
- "kind": "pages",
979
+ "kind": "worker",
981
980
  "apiUrl": null,
982
981
  "domains": [
983
982
  "nexus.topolo.app"
@@ -1037,20 +1036,9 @@ var APPLICATIONS = {
1037
1036
  "packageName": "topolo-oneclick-sso",
1038
1037
  "productionUrl": "https://one.topolo.app",
1039
1038
  "services": [
1040
- "one",
1041
- "one.ai"
1039
+ "one"
1042
1040
  ],
1043
1041
  "deployTargets": [
1044
- {
1045
- "name": "ai-chat-rag",
1046
- "kind": "worker",
1047
- "apiUrl": "https://ai.one.topolo.app",
1048
- "domains": [
1049
- "ai.one.topolo.app"
1050
- ],
1051
- "routes": [],
1052
- "serviceId": "one.ai"
1053
- },
1054
1042
  {
1055
1043
  "name": "topolo-one",
1056
1044
  "kind": "pages",
@@ -1204,7 +1192,7 @@ var APPLICATIONS = {
1204
1192
  },
1205
1193
  {
1206
1194
  "name": "quro-ui",
1207
- "kind": "pages",
1195
+ "kind": "worker",
1208
1196
  "apiUrl": null,
1209
1197
  "domains": [
1210
1198
  "quro.topolo.app"
@@ -1226,7 +1214,7 @@ var APPLICATIONS = {
1226
1214
  "deployTargets": [
1227
1215
  {
1228
1216
  "name": "topolo-roadmapper",
1229
- "kind": "pages",
1217
+ "kind": "worker",
1230
1218
  "apiUrl": null,
1231
1219
  "domains": [
1232
1220
  "roadmapper.topolo.app"
@@ -1282,7 +1270,7 @@ var APPLICATIONS = {
1282
1270
  "deployTargets": [
1283
1271
  {
1284
1272
  "name": "topolo-social-studio",
1285
- "kind": "pages",
1273
+ "kind": "worker",
1286
1274
  "apiUrl": null,
1287
1275
  "domains": [
1288
1276
  "studio.topolo.app"
@@ -1386,7 +1374,7 @@ var APPLICATIONS = {
1386
1374
  "deployTargets": [
1387
1375
  {
1388
1376
  "name": "topolo-support",
1389
- "kind": "workers",
1377
+ "kind": "worker",
1390
1378
  "apiUrl": "https://support.topolo.app",
1391
1379
  "domains": [
1392
1380
  "support.topolo.app"
@@ -1478,7 +1466,7 @@ var APPLICATIONS = {
1478
1466
  },
1479
1467
  {
1480
1468
  "name": "topolo-web-studio",
1481
- "kind": "pages",
1469
+ "kind": "worker",
1482
1470
  "apiUrl": null,
1483
1471
  "domains": [
1484
1472
  "web.topolo.app"
@@ -1882,7 +1870,9 @@ function resolveServiceUrl(service, overrides) {
1882
1870
 
1883
1871
  // src/client.ts
1884
1872
  var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
1885
- var TopoloClient = class {
1873
+ var POSITIVE_CACHE_TTL_MS = 5 * 60 * 1e3;
1874
+ var NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
1875
+ var TopoloClient = class _TopoloClient {
1886
1876
  credential;
1887
1877
  agent;
1888
1878
  serviceUrls;
@@ -1890,6 +1880,20 @@ var TopoloClient = class {
1890
1880
  timeoutMs;
1891
1881
  fetchImpl;
1892
1882
  debug;
1883
+ /**
1884
+ * Process-wide cache for slug → service-id lookups. Keyed by
1885
+ * `${authBaseUrl}|${slug}` so multiple `TopoloClient` instances pointing at
1886
+ * the same Auth share, but staging vs prod don't poison each other.
1887
+ * Cleared via `TopoloClient.clearServiceIdCache()` if a test needs it.
1888
+ */
1889
+ static serviceIdCache = /* @__PURE__ */ new Map();
1890
+ /**
1891
+ * Drop the slug→service-id cache. Test-only — production callers should
1892
+ * let the 5-minute TTL expire naturally.
1893
+ */
1894
+ static clearServiceIdCache() {
1895
+ _TopoloClient.serviceIdCache.clear();
1896
+ }
1893
1897
  constructor(options) {
1894
1898
  if (!options.credential) throw new TopoloAuthError("credential is required");
1895
1899
  if (!options.agent?.clientName) throw new TopoloAuthError("agent.clientName is required");
@@ -2004,6 +2008,66 @@ var TopoloClient = class {
2004
2008
  });
2005
2009
  return parsed;
2006
2010
  }
2011
+ /**
2012
+ * Resolve a service-slug → opaque service-id via TopoloAuth.
2013
+ *
2014
+ * Replaces the SDK-baked `PLATFORM_SERVICE_IDS` map (deprecated in 0.3.0,
2015
+ * removed in 0.4.0). Slug shape accepted: either the canonical Auth slug
2016
+ * (e.g. `topolo-notify`) or the SDK short id (`notify`) — Auth's resolver
2017
+ * understands both.
2018
+ *
2019
+ * Cache: 5 minutes per process per `(slug, auth_base_url)`. Negative
2020
+ * results (404) are cached for 60s so a typo doesn't hot-loop the
2021
+ * resolver. Returns null when the slug isn't registered — callers decide
2022
+ * whether to throw.
2023
+ *
2024
+ * No credential is sent: the endpoint is public (slugs aren't secret).
2025
+ * This keeps the resolver usable during early bootstrap before a caller
2026
+ * has acquired an access token.
2027
+ */
2028
+ async getServiceIdBySlug(slug) {
2029
+ if (typeof slug !== "string") return null;
2030
+ const normalized = slug.trim().toLowerCase();
2031
+ if (!normalized) return null;
2032
+ const authBase = resolveServiceUrl("auth", this.serviceUrls);
2033
+ const cacheKey = `${authBase}|${normalized}`;
2034
+ const now = Date.now();
2035
+ const cached = _TopoloClient.serviceIdCache.get(cacheKey);
2036
+ if (cached && cached.expiresAt > now) {
2037
+ return cached.value;
2038
+ }
2039
+ const url = new URL(
2040
+ `/api/services/by-slug/${encodeURIComponent(normalized)}`,
2041
+ authBase.endsWith("/") ? authBase : `${authBase}/`
2042
+ ).toString();
2043
+ let res;
2044
+ try {
2045
+ res = await this.fetchImpl(url, {
2046
+ method: "GET",
2047
+ headers: { Accept: "application/json" }
2048
+ });
2049
+ } catch {
2050
+ return null;
2051
+ }
2052
+ if (res.status === 404) {
2053
+ _TopoloClient.serviceIdCache.set(cacheKey, {
2054
+ value: null,
2055
+ expiresAt: now + NEGATIVE_CACHE_TTL_MS
2056
+ });
2057
+ return null;
2058
+ }
2059
+ if (!res.ok) {
2060
+ return null;
2061
+ }
2062
+ const body = await res.json().catch(() => null);
2063
+ const serviceId = body?.data?.service_id;
2064
+ const value = typeof serviceId === "string" && serviceId ? serviceId : null;
2065
+ _TopoloClient.serviceIdCache.set(cacheKey, {
2066
+ value,
2067
+ expiresAt: now + POSITIVE_CACHE_TTL_MS
2068
+ });
2069
+ return value;
2070
+ }
2007
2071
  /**
2008
2072
  * Introspect the current credential. Returns the caller's resolved identity,
2009
2073
  * organization, and permission set. Used by CLI `whoami` and by MCP to gate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.2.11",
3
+ "version": "0.3.0",
4
4
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",