@proveanything/smartlinks 2.0.18 → 2.0.19

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/openapi.yaml CHANGED
@@ -1081,6 +1081,39 @@ paths:
1081
1081
  application/json:
1082
1082
  schema:
1083
1083
  $ref: "#/components/schemas/AISearchPhotosRequest"
1084
+ /admin/collection/{collectionId}/ai/sessions:
1085
+ post:
1086
+ tags:
1087
+ - sessions
1088
+ summary: Persisted AI assistant sessions (admin scope) — durable conversation history for admin/host assistants.
1089
+ operationId: sessions_create
1090
+ security:
1091
+ - bearerAuth: []
1092
+ parameters:
1093
+ - name: collectionId
1094
+ in: path
1095
+ required: true
1096
+ schema:
1097
+ type: string
1098
+ responses:
1099
+ 200:
1100
+ description: Success
1101
+ content:
1102
+ application/json:
1103
+ schema:
1104
+ $ref: "#/components/schemas/AiSession"
1105
+ 400:
1106
+ description: Bad request
1107
+ 401:
1108
+ description: Unauthorized
1109
+ 404:
1110
+ description: Not found
1111
+ requestBody:
1112
+ required: true
1113
+ content:
1114
+ application/json:
1115
+ schema:
1116
+ $ref: "#/components/schemas/AiSessionCreate"
1084
1117
  /admin/collection/{collectionId}/ai/sessions/stats:
1085
1118
  get:
1086
1119
  tags:
@@ -1108,6 +1141,77 @@ paths:
1108
1141
  description: Unauthorized
1109
1142
  404:
1110
1143
  description: Not found
1144
+ /admin/collection/{collectionId}/ai/sessions/{id}:
1145
+ get:
1146
+ tags:
1147
+ - sessions
1148
+ summary: Get one session, including its full transcript.
1149
+ operationId: sessions_get
1150
+ security:
1151
+ - bearerAuth: []
1152
+ parameters:
1153
+ - name: collectionId
1154
+ in: path
1155
+ required: true
1156
+ schema:
1157
+ type: string
1158
+ - name: id
1159
+ in: path
1160
+ required: true
1161
+ schema:
1162
+ type: string
1163
+ responses:
1164
+ 200:
1165
+ description: Success
1166
+ content:
1167
+ application/json:
1168
+ schema:
1169
+ $ref: "#/components/schemas/AiSession"
1170
+ 400:
1171
+ description: Bad request
1172
+ 401:
1173
+ description: Unauthorized
1174
+ 404:
1175
+ description: Not found
1176
+ /admin/collection/{collectionId}/ai/sessions/{id}/append:
1177
+ post:
1178
+ tags:
1179
+ - sessions
1180
+ summary: Append Responses items (input/output/tool) to a session — the manual-persistence path.
1181
+ operationId: sessions_append
1182
+ security:
1183
+ - bearerAuth: []
1184
+ parameters:
1185
+ - name: collectionId
1186
+ in: path
1187
+ required: true
1188
+ schema:
1189
+ type: string
1190
+ - name: id
1191
+ in: path
1192
+ required: true
1193
+ schema:
1194
+ type: string
1195
+ responses:
1196
+ 200:
1197
+ description: Success
1198
+ content:
1199
+ application/json:
1200
+ schema:
1201
+ $ref: "#/components/schemas/AiSession"
1202
+ 400:
1203
+ description: Bad request
1204
+ 401:
1205
+ description: Unauthorized
1206
+ 404:
1207
+ description: Not found
1208
+ requestBody:
1209
+ required: true
1210
+ content:
1211
+ application/json:
1212
+ schema:
1213
+ type: object
1214
+ additionalProperties: true
1111
1215
  /admin/collection/{collectionId}/ai/skills:
1112
1216
  get:
1113
1217
  tags:
@@ -1196,6 +1300,33 @@ paths:
1196
1300
  description: Unauthorized
1197
1301
  404:
1198
1302
  description: Not found
1303
+ /admin/collection/{collectionId}/ai/usage:
1304
+ get:
1305
+ tags:
1306
+ - sessions
1307
+ summary: AI usage / cost report for a collection, grouped by any of model/serviceTier/appId/feature/mode over an optional date window.
1308
+ operationId: sessions_usage
1309
+ security:
1310
+ - bearerAuth: []
1311
+ parameters:
1312
+ - name: collectionId
1313
+ in: path
1314
+ required: true
1315
+ schema:
1316
+ type: string
1317
+ responses:
1318
+ 200:
1319
+ description: Success
1320
+ content:
1321
+ application/json:
1322
+ schema:
1323
+ $ref: "#/components/schemas/AiUsageReport"
1324
+ 400:
1325
+ description: Bad request
1326
+ 401:
1327
+ description: Unauthorized
1328
+ 404:
1329
+ description: Not found
1199
1330
  /admin/collection/{collectionId}/ai/v1/chat/completions:
1200
1331
  post:
1201
1332
  tags:
@@ -10294,9 +10425,9 @@ paths:
10294
10425
  /public/collection/{collectionId}/ai/rate-limit/{userId}:
10295
10426
  get:
10296
10427
  tags:
10297
- - publicClient
10428
+ - sessions
10298
10429
  summary: Check rate limit status
10299
- operationId: publicClient_getRateLimit
10430
+ operationId: sessions_getRateLimit
10300
10431
  security: []
10301
10432
  parameters:
10302
10433
  - name: collectionId
@@ -10353,12 +10484,113 @@ paths:
10353
10484
  description: Unauthorized
10354
10485
  404:
10355
10486
  description: Not found
10487
+ /public/collection/{collectionId}/ai/sessions:
10488
+ post:
10489
+ tags:
10490
+ - sessions
10491
+ summary: sessions.create
10492
+ operationId: sessions_create
10493
+ security: []
10494
+ parameters:
10495
+ - name: collectionId
10496
+ in: path
10497
+ required: true
10498
+ schema:
10499
+ type: string
10500
+ responses:
10501
+ 200:
10502
+ description: Success
10503
+ content:
10504
+ application/json:
10505
+ schema:
10506
+ $ref: "#/components/schemas/AiSession"
10507
+ 400:
10508
+ description: Bad request
10509
+ 401:
10510
+ description: Unauthorized
10511
+ 404:
10512
+ description: Not found
10513
+ requestBody:
10514
+ required: true
10515
+ content:
10516
+ application/json:
10517
+ schema:
10518
+ $ref: "#/components/schemas/AiSessionCreate"
10519
+ /public/collection/{collectionId}/ai/sessions/{id}:
10520
+ get:
10521
+ tags:
10522
+ - sessions
10523
+ summary: sessions.get
10524
+ operationId: sessions_get
10525
+ security: []
10526
+ parameters:
10527
+ - name: collectionId
10528
+ in: path
10529
+ required: true
10530
+ schema:
10531
+ type: string
10532
+ - name: id
10533
+ in: path
10534
+ required: true
10535
+ schema:
10536
+ type: string
10537
+ responses:
10538
+ 200:
10539
+ description: Success
10540
+ content:
10541
+ application/json:
10542
+ schema:
10543
+ $ref: "#/components/schemas/AiSession"
10544
+ 400:
10545
+ description: Bad request
10546
+ 401:
10547
+ description: Unauthorized
10548
+ 404:
10549
+ description: Not found
10550
+ /public/collection/{collectionId}/ai/sessions/{id}/append:
10551
+ post:
10552
+ tags:
10553
+ - sessions
10554
+ summary: sessions.append
10555
+ operationId: sessions_append
10556
+ security: []
10557
+ parameters:
10558
+ - name: collectionId
10559
+ in: path
10560
+ required: true
10561
+ schema:
10562
+ type: string
10563
+ - name: id
10564
+ in: path
10565
+ required: true
10566
+ schema:
10567
+ type: string
10568
+ responses:
10569
+ 200:
10570
+ description: Success
10571
+ content:
10572
+ application/json:
10573
+ schema:
10574
+ $ref: "#/components/schemas/AiSession"
10575
+ 400:
10576
+ description: Bad request
10577
+ 401:
10578
+ description: Unauthorized
10579
+ 404:
10580
+ description: Not found
10581
+ requestBody:
10582
+ required: true
10583
+ content:
10584
+ application/json:
10585
+ schema:
10586
+ type: object
10587
+ additionalProperties: true
10356
10588
  /public/collection/{collectionId}/ai/token:
10357
10589
  post:
10358
10590
  tags:
10359
- - publicClient
10591
+ - sessions
10360
10592
  summary: Generate ephemeral token for Gemini Live
10361
- operationId: publicClient_getToken
10593
+ operationId: sessions_getToken
10362
10594
  security: []
10363
10595
  parameters:
10364
10596
  - name: collectionId
@@ -15244,6 +15476,10 @@ components:
15244
15476
  - standard
15245
15477
  - flex
15246
15478
  - priority
15479
+ feature:
15480
+ type: string
15481
+ session_id:
15482
+ type: string
15247
15483
  server_tools:
15248
15484
  type: array
15249
15485
  items:
@@ -15799,6 +16035,102 @@ components:
15799
16035
  - activeSessions
15800
16036
  - totalMessages
15801
16037
  - rateLimitedUsers
16038
+ AiSession:
16039
+ type: object
16040
+ properties:
16041
+ id:
16042
+ type: string
16043
+ collectionId:
16044
+ type: string
16045
+ appId:
16046
+ type: string
16047
+ scope:
16048
+ $ref: "#/components/schemas/AiSessionScope"
16049
+ title:
16050
+ type: string
16051
+ status:
16052
+ type: string
16053
+ ownerId:
16054
+ type: string
16055
+ authorId:
16056
+ type: string
16057
+ productId:
16058
+ type: string
16059
+ proofId:
16060
+ type: string
16061
+ feature:
16062
+ type: string
16063
+ items:
16064
+ type: array
16065
+ items:
16066
+ $ref: "#/components/schemas/ResponseInputItem"
16067
+ summary:
16068
+ type: object
16069
+ additionalProperties: true
16070
+ usage:
16071
+ type: object
16072
+ additionalProperties: true
16073
+ itemCount:
16074
+ type: number
16075
+ lastTurnAt:
16076
+ type: string
16077
+ createdAt:
16078
+ type: string
16079
+ updatedAt:
16080
+ type: string
16081
+ expiresAt:
16082
+ type: string
16083
+ required:
16084
+ - id
16085
+ - collectionId
16086
+ - scope
16087
+ - status
16088
+ - items
16089
+ - itemCount
16090
+ - createdAt
16091
+ - updatedAt
16092
+ AiSessionCreate:
16093
+ type: object
16094
+ properties:
16095
+ appId:
16096
+ type: string
16097
+ title:
16098
+ type: string
16099
+ productId:
16100
+ type: string
16101
+ proofId:
16102
+ type: string
16103
+ feature:
16104
+ type: string
16105
+ ttlMs:
16106
+ type: number
16107
+ items:
16108
+ type: array
16109
+ items:
16110
+ $ref: "#/components/schemas/ResponseInputItem"
16111
+ AiUsageReport:
16112
+ type: object
16113
+ properties:
16114
+ groupBy:
16115
+ type: array
16116
+ items:
16117
+ type: string
16118
+ from:
16119
+ type: string
16120
+ to:
16121
+ type: string
16122
+ totals:
16123
+ type: object
16124
+ additionalProperties: true
16125
+ groups:
16126
+ type: array
16127
+ items:
16128
+ type: object
16129
+ additionalProperties: true
16130
+ required:
16131
+ - groupBy
16132
+ - totals
16133
+ - groups
15802
16134
  VoiceSessionRequest:
15803
16135
  type: object
15804
16136
  properties:
@@ -16656,6 +16988,12 @@ components:
16656
16988
  additionalProperties: true
16657
16989
  required:
16658
16990
  - type
16991
+ AiSessionScope:
16992
+ type: string
16993
+ enum:
16994
+ - admin
16995
+ - owner
16996
+ - public
16659
16997
  AiToolCapability:
16660
16998
  type: string
16661
16999
  enum:
@@ -116,6 +116,12 @@ export function createFunctionTestContext(opts) {
116
116
  throw new CapabilityError(`secrets:${ref}`);
117
117
  return Object.prototype.hasOwnProperty.call(secretsMap, ref) ? secretsMap[ref] : null;
118
118
  },
119
+ // App-scoped read — in tests it resolves from the same provided secrets map.
120
+ async app(ref) {
121
+ if (!parsed.secrets.has(ref))
122
+ throw new CapabilityError(`secrets:${ref}`);
123
+ return Object.prototype.hasOwnProperty.call(secretsMap, ref) ? secretsMap[ref] : null;
124
+ },
119
125
  },
120
126
  caller: {
121
127
  userId: (_a = caller.userId) !== null && _a !== void 0 ? _a : null,
@@ -109,6 +109,18 @@ export interface ResponsesRequest {
109
109
  };
110
110
  /** `'flex'` is ~50% cheaper at Batch-API rates but slower; reserve for non-interactive/background work. */
111
111
  service_tier?: 'auto' | 'standard' | 'flex' | 'priority';
112
+ /**
113
+ * Attribution tag for AI usage/cost reporting (see `ai.usage`). Not sent to the model —
114
+ * the server strips it. e.g. `'readiness-check'`, `'design-critique'`.
115
+ */
116
+ feature?: string;
117
+ /**
118
+ * Persist this turn to a server-managed session (create one with `ai.sessions.create`). The
119
+ * server threads the session's prior transcript into the input and appends the new turn — so
120
+ * you get conversation memory without managing history yourself, and it works even with
121
+ * `server_tools` (unlike `previous_response_id`).
122
+ */
123
+ session_id?: string;
112
124
  /**
113
125
  * Run through the server-side agent loop: the platform executes built-in tools
114
126
  * (see BUILTIN_AI_TOOLS / AiToolName) and feeds results back automatically, so the
@@ -350,6 +362,65 @@ export interface SessionStatistics {
350
362
  totalMessages: number;
351
363
  rateLimitedUsers: number;
352
364
  }
365
+ /** Who may read/append a persisted AI session. */
366
+ export type AiSessionScope = 'admin' | 'owner' | 'public';
367
+ /** A persisted AI assistant conversation (durable, scoped). */
368
+ export interface AiSession {
369
+ id: string;
370
+ collectionId: string;
371
+ appId?: string | null;
372
+ scope: AiSessionScope;
373
+ title?: string | null;
374
+ status: string;
375
+ ownerId?: string | null;
376
+ authorId?: string | null;
377
+ productId?: string | null;
378
+ proofId?: string | null;
379
+ feature?: string | null;
380
+ /** Append-only Responses items (input/output + tool calls/results). */
381
+ items: ResponseInputItem[];
382
+ /** Compacted digest of older turns (server-managed). */
383
+ summary?: Record<string, any>;
384
+ /** Running token/turn accounting for this session. */
385
+ usage?: Record<string, any>;
386
+ itemCount: number;
387
+ lastTurnAt?: string | null;
388
+ createdAt: string;
389
+ updatedAt: string;
390
+ expiresAt?: string | null;
391
+ }
392
+ /** Fields for creating a session (all optional). */
393
+ export interface AiSessionCreate {
394
+ appId?: string;
395
+ title?: string;
396
+ productId?: string;
397
+ proofId?: string;
398
+ feature?: string;
399
+ /** Time-to-live in ms; omit to keep until explicitly cleared. */
400
+ ttlMs?: number;
401
+ /** Seed items (e.g. a system/instruction turn). */
402
+ items?: ResponseInputItem[];
403
+ }
404
+ /** Per-collection AI usage/cost report. `costUnits` are OPAQUE internal units, never provider currency. */
405
+ export interface AiUsageReport {
406
+ groupBy: string[];
407
+ from?: string | null;
408
+ to?: string | null;
409
+ totals: {
410
+ promptTokens: number;
411
+ outputTokens: number;
412
+ totalTokens: number;
413
+ requests: number;
414
+ costUnits: number;
415
+ };
416
+ groups: Array<Record<string, any> & {
417
+ promptTokens: number;
418
+ outputTokens: number;
419
+ totalTokens: number;
420
+ requests: number;
421
+ costUnits: number;
422
+ }>;
423
+ }
353
424
  /** Voice session request */
354
425
  export interface VoiceSessionRequest {
355
426
  productId: string;
@@ -298,9 +298,15 @@ export interface ServerFunctionContext {
298
298
  * Declared `capabilities` cap what these calls may do.
299
299
  */
300
300
  sl: any;
301
- /** Capability-gated secret access. `get(ref)` resolves only refs granted via `secrets:<ref>`. */
301
+ /**
302
+ * Capability-gated secret access (both require the `secrets:<ref>` capability).
303
+ * `get(ref)` resolves the collection's OWN secret first (a client's credential), then falls back
304
+ * to the app-level secret (the developer's shared singleton, installed once per instance).
305
+ * `app(ref)` reads the app-level secret only, skipping the collection store.
306
+ */
302
307
  secrets: {
303
308
  get(ref: string): Promise<string | null>;
309
+ app(ref: string): Promise<string | null>;
304
310
  };
305
311
  /** Who invoked this function. */
306
312
  caller: ServerFunctionCaller;
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.0.18 | Generated: 2026-09-24T11:49:54.037Z
3
+ Version: 2.0.19 | Generated: 2026-09-24T19:51:28.993Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -580,6 +580,8 @@ interface ResponsesRequest {
580
580
  max_concurrent_subagents?: number
581
581
  }
582
582
  service_tier?: 'auto' | 'standard' | 'flex' | 'priority'
583
+ feature?: string
584
+ session_id?: string
583
585
  server_tools?: boolean | AiToolName[]
584
586
  allowCapabilities?: AiToolCapability[]
585
587
  only?: AiToolName[]
@@ -857,6 +859,55 @@ interface SessionStatistics {
857
859
  }
858
860
  ```
859
861
 
862
+ **AiSession** (interface)
863
+ ```typescript
864
+ interface AiSession {
865
+ id: string
866
+ collectionId: string
867
+ appId?: string | null
868
+ scope: AiSessionScope
869
+ title?: string | null
870
+ status: string
871
+ ownerId?: string | null
872
+ authorId?: string | null
873
+ productId?: string | null
874
+ proofId?: string | null
875
+ feature?: string | null
876
+ items: ResponseInputItem[]
877
+ summary?: Record<string, any>
878
+ usage?: Record<string, any>
879
+ itemCount: number
880
+ lastTurnAt?: string | null
881
+ createdAt: string
882
+ updatedAt: string
883
+ expiresAt?: string | null
884
+ }
885
+ ```
886
+
887
+ **AiSessionCreate** (interface)
888
+ ```typescript
889
+ interface AiSessionCreate {
890
+ appId?: string
891
+ title?: string
892
+ productId?: string
893
+ proofId?: string
894
+ feature?: string
895
+ ttlMs?: number
896
+ items?: ResponseInputItem[]
897
+ }
898
+ ```
899
+
900
+ **AiUsageReport** (interface)
901
+ ```typescript
902
+ interface AiUsageReport {
903
+ groupBy: string[]
904
+ from?: string | null
905
+ to?: string | null
906
+ totals: { promptTokens: number; outputTokens: number; totalTokens: number; requests: number; costUnits: number }
907
+ groups: Array<Record<string, any> & { promptTokens: number; outputTokens: number; totalTokens: number; requests: number; costUnits: number }>
908
+ }
909
+ ```
910
+
860
911
  **VoiceSessionRequest** (interface)
861
912
  ```typescript
862
913
  interface VoiceSessionRequest {
@@ -1440,6 +1491,8 @@ interface AgentResponseCompletedEvent {
1440
1491
  }
1441
1492
  ```
1442
1493
 
1494
+ **AiSessionScope** = `'admin' | 'owner' | 'public'`
1495
+
1443
1496
  **AiToolCapability** = ``
1444
1497
 
1445
1498
  **AiToolName** = ``
@@ -2102,7 +2155,10 @@ interface ServerFunctionContext {
2102
2155
  collectionId: string;
2103
2156
  appId: string;
2104
2157
  sl: any;
2105
- secrets: { get(ref: string): Promise<string | null> };
2158
+ secrets: {
2159
+ get(ref: string): Promise<string | null>;
2160
+ app(ref: string): Promise<string | null>;
2161
+ };
2106
2162
  caller: ServerFunctionCaller;
2107
2163
  fetch: typeof fetch;
2108
2164
  log: (message: string, data?: Record<string, any>) => void;
@@ -11091,6 +11147,27 @@ Check rate limit status
11091
11147
  request: EphemeralTokenRequest) → `Promise<EphemeralTokenResponse>`
11092
11148
  Generate ephemeral token for Gemini Live
11093
11149
 
11150
+ ### publicClient.sessions
11151
+
11152
+ **create**(collectionId: string,
11153
+ body: AiSessionCreate & { scope?: 'owner' | 'public' } = {}) → `Promise<AiSession>`
11154
+
11155
+ **list**(collectionId: string,
11156
+ params?: { appId?: string; limit?: number }) → `Promise<`
11157
+ List the signed-in consumer's own ('owner') sessions — requires an authKit bearer.
11158
+
11159
+ **get**(collectionId: string, id: string) → `Promise<AiSession>`
11160
+ List the signed-in consumer's own ('owner') sessions — requires an authKit bearer.
11161
+
11162
+ **append**(collectionId: string,
11163
+ id: string,
11164
+ items: ResponseInputItem[],
11165
+ opts?: { usage?: Record<string, any> }) → `Promise<AiSession>`
11166
+ List the signed-in consumer's own ('owner') sessions — requires an authKit bearer.
11167
+
11168
+ **clear**(collectionId: string, id: string) → `Promise<`
11169
+ List the signed-in consumer's own ('owner') sessions — requires an authKit bearer.
11170
+
11094
11171
  ### qr
11095
11172
 
11096
11173
  **lookupShortCode**(shortId: string, code: string) → `Promise<QrShortCodeLookupResponse>`
@@ -11176,6 +11253,24 @@ Allocate (or return the existing) sequence number for a subject. Idempotent —
11176
11253
  **stats**(collectionId: string) → `Promise<SessionStatistics>`
11177
11254
  Get session statistics
11178
11255
 
11256
+ **create**(collectionId: string, body: AiSessionCreate = {}) → `Promise<AiSession>`
11257
+ Persisted AI assistant sessions (admin scope) — durable conversation history for admin/host assistants. Create one, then either append your turns explicitly, OR pass its `id` as `session_id` to `ai.chat.responses.create` and the server threads prior turns into the input and persists the new turn automatically (works with `server_tools`).
11258
+
11259
+ **list**(collectionId: string, params?: { appId?: string; limit?: number }) → `Promise<`
11260
+ List sessions, most-recently-active first (optionally filtered by app).
11261
+
11262
+ **get**(collectionId: string, id: string) → `Promise<AiSession>`
11263
+ Get one session, including its full transcript.
11264
+
11265
+ **append**(collectionId: string,
11266
+ id: string,
11267
+ items: ResponseInputItem[],
11268
+ opts?: { usage?: Record<string, any> }) → `Promise<AiSession>`
11269
+ Append Responses items (input/output/tool) to a session — the manual-persistence path.
11270
+
11271
+ **clear**(collectionId: string, id: string) → `Promise<`
11272
+ Archive (soft-delete) a session.
11273
+
11179
11274
  ### skills
11180
11275
 
11181
11276
  **list**(collectionId: string) → `Promise<SkillsListResponse>`
@@ -62,12 +62,19 @@ export default defineConfig({
62
62
 
63
63
  ## Host-provided globals (build against versions ≤ these)
64
64
 
65
+ > **The SmartLinks packages on the host are always the latest published.** `@proveanything/smartlinks`
66
+ > (and `-utils-ui`, `-auth-ui`) are considered *released* only once Hub and Portal are running them —
67
+ > that's the first place a version lands, by design. So **build against the latest published SmartLinks
68
+ > SDK**; never pin below it. The exact number below is just "current at time of writing" — the rule is
69
+ > *latest*. The third-party framework versions (React, Vite, Router, …) change rarely and are the real
70
+ > compile-time ceiling.
71
+
65
72
  | Import | Window global | Host provides (R5) |
66
73
  |---|---|---|
67
74
  | `react` | `React` | 19.3 (accepts 18.3 builds) |
68
75
  | `react-dom` | `ReactDOM` | 19.3 (accepts 18.3 builds) |
69
76
  | `react/jsx-runtime` | `jsxRuntime` | 19.3 |
70
- | `@proveanything/smartlinks` | `SL` | 2.0.5 |
77
+ | `@proveanything/smartlinks` | `SL` | latest published 2.x (build against latest) |
71
78
  | `react-router-dom` | `ReactRouterDOM` | 7.18 (accepts 6.x builds) |
72
79
  | `@tanstack/react-query` | `ReactQuery` | 5.103 |
73
80
  | `lucide-react` | `LucideReact` | 1.47 |
@@ -130,10 +137,12 @@ app ships the Tailwind 4 CSS-first layout as the default; see its README.)
130
137
  ## The R5 host stack (reference)
131
138
 
132
139
  React **19.3** · Vite **8.3** · react-router-dom **7.18** · Tailwind **4.3** (CSS-first) ·
133
- TypeScript **6.0** · ESLint **10.11** · `@proveanything/smartlinks` **2.0.5** ·
134
- `@proveanything/smartlinks-utils-ui` **1.16.4** · liquidjs **10.29** · marked **12+** ·
140
+ TypeScript **6.0** · ESLint **10.11** · liquidjs **10.29** · marked **12+** ·
135
141
  dompurify **3+** · clsx **2+** · tailwind-merge **3+**.
136
142
 
143
+ The SmartLinks packages (`@proveanything/smartlinks`, `-utils-ui`, `-auth-ui`) are **always the latest
144
+ published 2.x** — see the note above; build against latest, don't pin a specific number here (it rots).
145
+
137
146
  > **TypeScript 7** (the native/Go compiler) is **deliberately deferred** — tooling hasn't settled.
138
147
  > Target **TS 6** for R5; it compiles existing code with no source changes.
139
148