vana-cli 0.15.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.
Files changed (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +320 -0
  3. package/dist/cli/auth.d.ts +119 -0
  4. package/dist/cli/auth.d.ts.map +1 -0
  5. package/dist/cli/auth.js +528 -0
  6. package/dist/cli/auth.js.map +1 -0
  7. package/dist/cli/bin.d.ts +3 -0
  8. package/dist/cli/bin.d.ts.map +1 -0
  9. package/dist/cli/bin.js +15 -0
  10. package/dist/cli/bin.js.map +1 -0
  11. package/dist/cli/index.d.ts +92 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +4703 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/main.d.ts +2 -0
  16. package/dist/cli/main.d.ts.map +1 -0
  17. package/dist/cli/main.js +10 -0
  18. package/dist/cli/main.js.map +1 -0
  19. package/dist/cli/mcp-server.d.ts +15 -0
  20. package/dist/cli/mcp-server.d.ts.map +1 -0
  21. package/dist/cli/mcp-server.js +199 -0
  22. package/dist/cli/mcp-server.js.map +1 -0
  23. package/dist/cli/queries.d.ts +128 -0
  24. package/dist/cli/queries.d.ts.map +1 -0
  25. package/dist/cli/queries.js +422 -0
  26. package/dist/cli/queries.js.map +1 -0
  27. package/dist/cli/render/capabilities.d.ts +9 -0
  28. package/dist/cli/render/capabilities.d.ts.map +1 -0
  29. package/dist/cli/render/capabilities.js +24 -0
  30. package/dist/cli/render/capabilities.js.map +1 -0
  31. package/dist/cli/render/connect-renderer.d.ts +23 -0
  32. package/dist/cli/render/connect-renderer.d.ts.map +1 -0
  33. package/dist/cli/render/connect-renderer.js +259 -0
  34. package/dist/cli/render/connect-renderer.js.map +1 -0
  35. package/dist/cli/render/flow-theme.d.ts +17 -0
  36. package/dist/cli/render/flow-theme.d.ts.map +1 -0
  37. package/dist/cli/render/flow-theme.js +26 -0
  38. package/dist/cli/render/flow-theme.js.map +1 -0
  39. package/dist/cli/render/format.d.ts +27 -0
  40. package/dist/cli/render/format.d.ts.map +1 -0
  41. package/dist/cli/render/format.js +111 -0
  42. package/dist/cli/render/format.js.map +1 -0
  43. package/dist/cli/render/index.d.ts +8 -0
  44. package/dist/cli/render/index.d.ts.map +1 -0
  45. package/dist/cli/render/index.js +8 -0
  46. package/dist/cli/render/index.js.map +1 -0
  47. package/dist/cli/render/progress.d.ts +11 -0
  48. package/dist/cli/render/progress.d.ts.map +1 -0
  49. package/dist/cli/render/progress.js +56 -0
  50. package/dist/cli/render/progress.js.map +1 -0
  51. package/dist/cli/render/symbols.d.ts +11 -0
  52. package/dist/cli/render/symbols.d.ts.map +1 -0
  53. package/dist/cli/render/symbols.js +21 -0
  54. package/dist/cli/render/symbols.js.map +1 -0
  55. package/dist/cli/render/theme.d.ts +16 -0
  56. package/dist/cli/render/theme.d.ts.map +1 -0
  57. package/dist/cli/render/theme.js +57 -0
  58. package/dist/cli/render/theme.js.map +1 -0
  59. package/dist/cli/search-select.d.ts +17 -0
  60. package/dist/cli/search-select.d.ts.map +1 -0
  61. package/dist/cli/search-select.js +29 -0
  62. package/dist/cli/search-select.js.map +1 -0
  63. package/dist/cli/telemetry-contract.d.ts +146 -0
  64. package/dist/cli/telemetry-contract.d.ts.map +1 -0
  65. package/dist/cli/telemetry-contract.js +56 -0
  66. package/dist/cli/telemetry-contract.js.map +1 -0
  67. package/dist/cli/telemetry.d.ts +60 -0
  68. package/dist/cli/telemetry.d.ts.map +1 -0
  69. package/dist/cli/telemetry.js +621 -0
  70. package/dist/cli/telemetry.js.map +1 -0
  71. package/dist/cli/update-check.d.ts +21 -0
  72. package/dist/cli/update-check.d.ts.map +1 -0
  73. package/dist/cli/update-check.js +86 -0
  74. package/dist/cli/update-check.js.map +1 -0
  75. package/dist/connectors/index.d.ts +2 -0
  76. package/dist/connectors/index.d.ts.map +1 -0
  77. package/dist/connectors/index.js +2 -0
  78. package/dist/connectors/index.js.map +1 -0
  79. package/dist/connectors/registry.d.ts +55 -0
  80. package/dist/connectors/registry.d.ts.map +1 -0
  81. package/dist/connectors/registry.js +301 -0
  82. package/dist/connectors/registry.js.map +1 -0
  83. package/dist/core/cli-types.d.ts +722 -0
  84. package/dist/core/cli-types.d.ts.map +1 -0
  85. package/dist/core/cli-types.js +328 -0
  86. package/dist/core/cli-types.js.map +1 -0
  87. package/dist/core/constants.d.ts +33 -0
  88. package/dist/core/constants.d.ts.map +1 -0
  89. package/dist/core/constants.js +25 -0
  90. package/dist/core/constants.js.map +1 -0
  91. package/dist/core/errors.d.ts +47 -0
  92. package/dist/core/errors.d.ts.map +1 -0
  93. package/dist/core/errors.js +50 -0
  94. package/dist/core/errors.js.map +1 -0
  95. package/dist/core/grants.d.ts +19 -0
  96. package/dist/core/grants.d.ts.map +1 -0
  97. package/dist/core/grants.js +31 -0
  98. package/dist/core/grants.js.map +1 -0
  99. package/dist/core/index.d.ts +9 -0
  100. package/dist/core/index.d.ts.map +1 -0
  101. package/dist/core/index.js +7 -0
  102. package/dist/core/index.js.map +1 -0
  103. package/dist/core/paths.d.ts +30 -0
  104. package/dist/core/paths.d.ts.map +1 -0
  105. package/dist/core/paths.js +95 -0
  106. package/dist/core/paths.js.map +1 -0
  107. package/dist/core/state-store.d.ts +44 -0
  108. package/dist/core/state-store.d.ts.map +1 -0
  109. package/dist/core/state-store.js +101 -0
  110. package/dist/core/state-store.js.map +1 -0
  111. package/dist/core/types.d.ts +148 -0
  112. package/dist/core/types.d.ts.map +1 -0
  113. package/dist/core/types.js +2 -0
  114. package/dist/core/types.js.map +1 -0
  115. package/dist/index.d.ts +2 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +2 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/personal-server/client.d.ts +34 -0
  120. package/dist/personal-server/client.d.ts.map +1 -0
  121. package/dist/personal-server/client.js +108 -0
  122. package/dist/personal-server/client.js.map +1 -0
  123. package/dist/personal-server/index.d.ts +28 -0
  124. package/dist/personal-server/index.d.ts.map +1 -0
  125. package/dist/personal-server/index.js +157 -0
  126. package/dist/personal-server/index.js.map +1 -0
  127. package/dist/personal-server/scope-resolver.d.ts +22 -0
  128. package/dist/personal-server/scope-resolver.d.ts.map +1 -0
  129. package/dist/personal-server/scope-resolver.js +80 -0
  130. package/dist/personal-server/scope-resolver.js.map +1 -0
  131. package/dist/react/ConnectButton.d.ts +27 -0
  132. package/dist/react/ConnectButton.d.ts.map +1 -0
  133. package/dist/react/ConnectButton.js +39 -0
  134. package/dist/react/ConnectButton.js.map +1 -0
  135. package/dist/react/index.d.ts +4 -0
  136. package/dist/react/index.d.ts.map +1 -0
  137. package/dist/react/index.js +4 -0
  138. package/dist/react/index.js.map +1 -0
  139. package/dist/react/useVanaConnect.d.ts +50 -0
  140. package/dist/react/useVanaConnect.d.ts.map +1 -0
  141. package/dist/react/useVanaConnect.js +114 -0
  142. package/dist/react/useVanaConnect.js.map +1 -0
  143. package/dist/react/useVanaData.d.ts +69 -0
  144. package/dist/react/useVanaData.d.ts.map +1 -0
  145. package/dist/react/useVanaData.js +144 -0
  146. package/dist/react/useVanaData.js.map +1 -0
  147. package/dist/runtime/core/contracts.d.ts +84 -0
  148. package/dist/runtime/core/contracts.d.ts.map +1 -0
  149. package/dist/runtime/core/contracts.js +2 -0
  150. package/dist/runtime/core/contracts.js.map +1 -0
  151. package/dist/runtime/core/index.d.ts +2 -0
  152. package/dist/runtime/core/index.d.ts.map +1 -0
  153. package/dist/runtime/core/index.js +2 -0
  154. package/dist/runtime/core/index.js.map +1 -0
  155. package/dist/runtime/index.d.ts +4 -0
  156. package/dist/runtime/index.d.ts.map +1 -0
  157. package/dist/runtime/index.js +3 -0
  158. package/dist/runtime/index.js.map +1 -0
  159. package/dist/runtime/managed-playwright.d.ts +42 -0
  160. package/dist/runtime/managed-playwright.d.ts.map +1 -0
  161. package/dist/runtime/managed-playwright.js +178 -0
  162. package/dist/runtime/managed-playwright.js.map +1 -0
  163. package/dist/runtime/playwright/browser.d.ts +12 -0
  164. package/dist/runtime/playwright/browser.d.ts.map +1 -0
  165. package/dist/runtime/playwright/browser.js +229 -0
  166. package/dist/runtime/playwright/browser.js.map +1 -0
  167. package/dist/runtime/playwright/in-process-run.d.ts +6 -0
  168. package/dist/runtime/playwright/in-process-run.d.ts.map +1 -0
  169. package/dist/runtime/playwright/in-process-run.js +625 -0
  170. package/dist/runtime/playwright/in-process-run.js.map +1 -0
  171. package/dist/runtime/playwright/index.d.ts +3 -0
  172. package/dist/runtime/playwright/index.d.ts.map +1 -0
  173. package/dist/runtime/playwright/index.js +3 -0
  174. package/dist/runtime/playwright/index.js.map +1 -0
  175. package/dist/runtime/repo-paths.d.ts +2 -0
  176. package/dist/runtime/repo-paths.d.ts.map +1 -0
  177. package/dist/runtime/repo-paths.js +36 -0
  178. package/dist/runtime/repo-paths.js.map +1 -0
  179. package/dist/server/config.d.ts +38 -0
  180. package/dist/server/config.d.ts.map +1 -0
  181. package/dist/server/config.js +45 -0
  182. package/dist/server/config.js.map +1 -0
  183. package/dist/server/connect.d.ts +43 -0
  184. package/dist/server/connect.d.ts.map +1 -0
  185. package/dist/server/connect.js +115 -0
  186. package/dist/server/connect.js.map +1 -0
  187. package/dist/server/data-client.d.ts +31 -0
  188. package/dist/server/data-client.d.ts.map +1 -0
  189. package/dist/server/data-client.js +95 -0
  190. package/dist/server/data-client.js.map +1 -0
  191. package/dist/server/index.d.ts +8 -0
  192. package/dist/server/index.d.ts.map +1 -0
  193. package/dist/server/index.js +8 -0
  194. package/dist/server/index.js.map +1 -0
  195. package/dist/server/manifest-signer.d.ts +25 -0
  196. package/dist/server/manifest-signer.d.ts.map +1 -0
  197. package/dist/server/manifest-signer.js +51 -0
  198. package/dist/server/manifest-signer.js.map +1 -0
  199. package/dist/server/request-signer.d.ts +31 -0
  200. package/dist/server/request-signer.d.ts.map +1 -0
  201. package/dist/server/request-signer.js +72 -0
  202. package/dist/server/request-signer.js.map +1 -0
  203. package/dist/server/session-relay.d.ts +39 -0
  204. package/dist/server/session-relay.d.ts.map +1 -0
  205. package/dist/server/session-relay.js +74 -0
  206. package/dist/server/session-relay.js.map +1 -0
  207. package/dist/server/webhook.d.ts +11 -0
  208. package/dist/server/webhook.d.ts.map +1 -0
  209. package/dist/server/webhook.js +18 -0
  210. package/dist/server/webhook.js.map +1 -0
  211. package/dist/skills/index.d.ts +4 -0
  212. package/dist/skills/index.d.ts.map +1 -0
  213. package/dist/skills/index.js +3 -0
  214. package/dist/skills/index.js.map +1 -0
  215. package/dist/skills/paths.d.ts +33 -0
  216. package/dist/skills/paths.d.ts.map +1 -0
  217. package/dist/skills/paths.js +81 -0
  218. package/dist/skills/paths.js.map +1 -0
  219. package/dist/skills/registry.d.ts +48 -0
  220. package/dist/skills/registry.d.ts.map +1 -0
  221. package/dist/skills/registry.js +173 -0
  222. package/dist/skills/registry.js.map +1 -0
  223. package/package.json +147 -0
@@ -0,0 +1,157 @@
1
+ import fs from "node:fs/promises";
2
+ import { readCliConfig } from "../core/state-store.js";
3
+ import { resolveScopes } from "./scope-resolver.js";
4
+ import { createPersonalServerClient } from "./client.js";
5
+ import { readCachedConnectorMetadata } from "../connectors/registry.js";
6
+ import { getConnectorCacheDir } from "../core/paths.js";
7
+ import { loadCredentials } from "../cli/auth.js";
8
+ export { createPersonalServerClient } from "./client.js";
9
+ const DEFAULT_PORTS = [8080, 8081, 8082, 8083, 8084, 8085];
10
+ async function detectTargetAt(url, source) {
11
+ const health = await fetchHealth(url);
12
+ if (!health) {
13
+ return null;
14
+ }
15
+ return {
16
+ state: "available",
17
+ url,
18
+ source,
19
+ health,
20
+ };
21
+ }
22
+ export async function detectPersonalServerTarget() {
23
+ // 1. Persisted config (highest priority)
24
+ const config = await readCliConfig();
25
+ if (config.personalServerUrl) {
26
+ const target = await detectTargetAt(config.personalServerUrl, "config");
27
+ if (target) {
28
+ return target;
29
+ }
30
+ }
31
+ // 2. Auth credentials (from `vana login`)
32
+ const authCreds = loadCredentials();
33
+ if (authCreds?.personal_server?.url) {
34
+ const target = await detectTargetAt(authCreds.personal_server.url, "auth");
35
+ if (target) {
36
+ return target;
37
+ }
38
+ }
39
+ // 3. Environment variable
40
+ const explicitUrl = process.env.VANA_PERSONAL_SERVER_URL;
41
+ if (explicitUrl) {
42
+ const target = await detectTargetAt(explicitUrl, "env");
43
+ if (target) {
44
+ return target;
45
+ }
46
+ }
47
+ // 3. Localhost port scan
48
+ for (const port of DEFAULT_PORTS) {
49
+ const url = `http://localhost:${port}`;
50
+ const health = await fetchHealth(url);
51
+ if (health) {
52
+ return { state: "available", url, source: "scan", health };
53
+ }
54
+ }
55
+ return { state: "unavailable", url: null, source: null, health: null };
56
+ }
57
+ export async function ingestResult(source, resultPath, target, options) {
58
+ if (target.state !== "available" || !target.url) {
59
+ return [
60
+ {
61
+ type: "ingest-skipped",
62
+ source,
63
+ reason: "personal_server_unavailable",
64
+ },
65
+ ];
66
+ }
67
+ const raw = await fs.readFile(resultPath, "utf8");
68
+ const result = JSON.parse(raw);
69
+ const metadata = await readCachedConnectorMetadata(source, getConnectorCacheDir());
70
+ const selectedScopes = options?.scopes ? new Set(options.scopes) : null;
71
+ const scopeMappings = resolveScopes(source, result, metadata).filter((mapping) => !selectedScopes || selectedScopes.has(mapping.scope));
72
+ if (scopeMappings.length === 0) {
73
+ return [
74
+ {
75
+ type: "ingest-skipped",
76
+ source,
77
+ reason: "no_scopes_resolved",
78
+ },
79
+ ];
80
+ }
81
+ const client = createPersonalServerClient({
82
+ url: target.url,
83
+ auth: resolvePersonalServerAuthConfig(target.url),
84
+ });
85
+ const events = [
86
+ { type: "ingest-started", source, target: target.url },
87
+ ];
88
+ const scopeResults = [];
89
+ for (const mapping of scopeMappings) {
90
+ const scopeResult = await client.ingestScope(mapping.scope, mapping.data);
91
+ scopeResults.push(scopeResult);
92
+ }
93
+ const allStored = scopeResults.every((r) => r.status === "stored");
94
+ const allFailed = scopeResults.every((r) => r.status === "failed");
95
+ if (allStored) {
96
+ events.push({
97
+ type: "ingest-complete",
98
+ source,
99
+ target: target.url,
100
+ scopeResults,
101
+ });
102
+ }
103
+ else if (allFailed) {
104
+ events.push({
105
+ type: "ingest-failed",
106
+ source,
107
+ target: target.url,
108
+ message: scopeResults.map((r) => `${r.scope}: ${r.error}`).join("; "),
109
+ scopeResults,
110
+ });
111
+ }
112
+ else {
113
+ events.push({
114
+ type: "ingest-partial",
115
+ source,
116
+ target: target.url,
117
+ scopeResults,
118
+ });
119
+ }
120
+ return events;
121
+ }
122
+ export function resolvePersonalServerAuthConfig(serverUrl) {
123
+ const psToken = process.env.VANA_PS_TOKEN;
124
+ if (psToken) {
125
+ return { type: "bearerToken", token: psToken };
126
+ }
127
+ const creds = loadCredentials();
128
+ if (creds?.personal_server?.session_token &&
129
+ urlsMatch(creds.personal_server.url, serverUrl)) {
130
+ return { type: "bearerToken", token: creds.personal_server.session_token };
131
+ }
132
+ return undefined;
133
+ }
134
+ function urlsMatch(left, right) {
135
+ return left.replace(/\/+$/, "") === right.replace(/\/+$/, "");
136
+ }
137
+ async function fetchHealth(baseUrl) {
138
+ try {
139
+ const response = await fetch(`${baseUrl}/health`, {
140
+ method: "GET",
141
+ signal: AbortSignal.timeout(2_000),
142
+ });
143
+ if (!response.ok)
144
+ return null;
145
+ const body = (await response.json());
146
+ return {
147
+ status: typeof body.status === "string" ? body.status : "unknown",
148
+ version: typeof body.version === "string" ? body.version : "unknown",
149
+ uptime: typeof body.uptime === "number" ? body.uptime : 0,
150
+ owner: typeof body.owner === "string" ? body.owner : null,
151
+ };
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ }
157
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/personal-server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGlC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAOzD,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAyB3D,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,MAAsC;IAEtC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,GAAG;QACH,MAAM;QACN,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,yCAAyC;IACzC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;IACrC,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QACxE,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;IACpC,IAAI,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3E,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACzD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,UAAkB,EAClB,MAA4B,EAC5B,OAA6B;IAE7B,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChD,OAAO;YACL;gBACE,IAAI,EAAE,gBAAgB;gBACtB,MAAM;gBACN,MAAM,EAAE,6BAA6B;aACtC;SACF,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAChD,MAAM,EACN,oBAAoB,EAAE,CACvB,CAAC;IACF,MAAM,cAAc,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,MAAM,CAClE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAClE,CAAC;IAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL;gBACE,IAAI,EAAE,gBAAgB;gBACtB,MAAM;gBACN,MAAM,EAAE,oBAAoB;aAC7B;SACF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,0BAA0B,CAAC;QACxC,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE,+BAA+B,CAAC,MAAM,CAAC,GAAG,CAAC;KAClD,CAAC,CAAC;IACH,MAAM,MAAM,GAAe;QACzB,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE;KACvD,CAAC;IACF,MAAM,YAAY,GAAG,EAAE,CAAC;IAExB,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1E,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IAEnE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,iBAAiB;YACvB,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,YAAY;SACb,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,eAAe;YACrB,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACrE,YAAY;SACb,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,gBAAgB;YACtB,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,SAAiB;IAEjB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC1C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IACE,KAAK,EAAE,eAAe,EAAE,aAAa;QACrC,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,EAC/C,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;IAC7E,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,KAAa;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,EAAE;YAChD,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;QAChE,OAAO;YACL,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YACjE,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACpE,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACzD,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;SAC1D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ConnectorMetadata } from "../connectors/registry.js";
2
+ export interface ScopeMapping {
3
+ scope: string;
4
+ data: unknown;
5
+ }
6
+ /**
7
+ * Resolve connector output keys to personal server scopes.
8
+ *
9
+ * Strategy (matches DataConnect production):
10
+ * 1. If any output keys contain ".", use them directly as scopes
11
+ * 2. Otherwise, use connector metadata to map: metadata scope "github.profile"
12
+ * → look for key "profile" in result
13
+ * 3. If no metadata, fall back to "{source}.{key}" for every non-metadata key
14
+ * (exclude: exportSummary, timestamp, version, platform)
15
+ *
16
+ * @param source - The connector source name (e.g. "github")
17
+ * @param result - The connector output as key-value pairs
18
+ * @param metadata - Optional connector metadata with scope definitions
19
+ * @returns An array of scope mappings
20
+ */
21
+ export declare function resolveScopes(source: string, result: Record<string, unknown>, metadata: ConnectorMetadata | null): ScopeMapping[];
22
+ //# sourceMappingURL=scope-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-resolver.d.ts","sourceRoot":"","sources":["../../src/personal-server/scope-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAoCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GACjC,YAAY,EAAE,CAsChB"}
@@ -0,0 +1,80 @@
1
+ /** Keys that are connector metadata, not user data. */
2
+ const EXCLUDED_KEYS = new Set([
3
+ "exportSummary",
4
+ "timestamp",
5
+ "version",
6
+ "platform",
7
+ ]);
8
+ /**
9
+ * Ensure scope data is a JSON object for the Personal Server API.
10
+ * Arrays are wrapped as `{ items: [...] }`. Primitives are wrapped
11
+ * as `{ value: ... }`. Objects pass through unchanged.
12
+ */
13
+ function ensureObject(data) {
14
+ if (Array.isArray(data)) {
15
+ return { items: data };
16
+ }
17
+ if (data !== null && typeof data === "object") {
18
+ return data;
19
+ }
20
+ return { value: data };
21
+ }
22
+ function normalizeScopeSegment(segment) {
23
+ return segment
24
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
25
+ .replace(/[\s-]+/g, "_")
26
+ .toLowerCase();
27
+ }
28
+ function normalizeScope(scope) {
29
+ return scope.split(".").filter(Boolean).map(normalizeScopeSegment).join(".");
30
+ }
31
+ /**
32
+ * Resolve connector output keys to personal server scopes.
33
+ *
34
+ * Strategy (matches DataConnect production):
35
+ * 1. If any output keys contain ".", use them directly as scopes
36
+ * 2. Otherwise, use connector metadata to map: metadata scope "github.profile"
37
+ * → look for key "profile" in result
38
+ * 3. If no metadata, fall back to "{source}.{key}" for every non-metadata key
39
+ * (exclude: exportSummary, timestamp, version, platform)
40
+ *
41
+ * @param source - The connector source name (e.g. "github")
42
+ * @param result - The connector output as key-value pairs
43
+ * @param metadata - Optional connector metadata with scope definitions
44
+ * @returns An array of scope mappings
45
+ */
46
+ export function resolveScopes(source, result, metadata) {
47
+ const keys = Object.keys(result);
48
+ // Strategy 1: If any keys are already dotted scopes, use them directly.
49
+ const dottedKeys = keys.filter((key) => key.includes(".") && !EXCLUDED_KEYS.has(key));
50
+ if (dottedKeys.length > 0) {
51
+ return dottedKeys.map((key) => ({
52
+ scope: normalizeScope(key),
53
+ data: ensureObject(result[key]),
54
+ }));
55
+ }
56
+ // Strategy 2: Use metadata scopes to map flat keys.
57
+ if (metadata?.scopes && metadata.scopes.length > 0) {
58
+ const mappings = [];
59
+ for (const { scope } of metadata.scopes) {
60
+ // Extract the key portion after the dot, e.g. "github.profile" → "profile"
61
+ const dotIndex = scope.indexOf(".");
62
+ const key = dotIndex >= 0 ? scope.slice(dotIndex + 1) : scope;
63
+ if (key in result) {
64
+ mappings.push({
65
+ scope: normalizeScope(scope),
66
+ data: ensureObject(result[key]),
67
+ });
68
+ }
69
+ }
70
+ return mappings;
71
+ }
72
+ // Strategy 3: Fall back to "{source}.{key}" for every non-metadata key.
73
+ return keys
74
+ .filter((key) => !EXCLUDED_KEYS.has(key))
75
+ .map((key) => ({
76
+ scope: normalizeScope(`${source}.${key}`),
77
+ data: ensureObject(result[key]),
78
+ }));
79
+ }
80
+ //# sourceMappingURL=scope-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-resolver.js","sourceRoot":"","sources":["../../src/personal-server/scope-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { GrantPayload } from "../core/types.js";
2
+ /** Props for the {@link ConnectButton} component. */
3
+ export interface ConnectButtonProps {
4
+ /** Session ID from the server-side `connect()` call. */
5
+ sessionId: string;
6
+ /** URL to account.vana.org/connect. */
7
+ connectUrl?: string;
8
+ /** Called when the user approves the grant. */
9
+ onComplete?: (grant: GrantPayload) => void;
10
+ /** Called on polling errors. */
11
+ onError?: (error: string) => void;
12
+ /** Called when the user denies the request. */
13
+ onDenied?: (reason: string) => void;
14
+ /** CSS class name for the wrapper element. */
15
+ className?: string;
16
+ /** Label for the connect anchor (default: `"Connect with Vana"`). */
17
+ label?: string;
18
+ }
19
+ /**
20
+ * Pre-built React component that displays connection status and a deep link.
21
+ *
22
+ * For full control over the UI, use {@link useVanaConnect} or {@link useVanaData} directly.
23
+ *
24
+ * @param props - Component props.
25
+ */
26
+ export declare function ConnectButton(props: ConnectButtonProps): import("react/jsx-runtime").JSX.Element;
27
+ //# sourceMappingURL=ConnectButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectButton.d.ts","sourceRoot":"","sources":["../../src/react/ConnectButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC3C,gCAAgC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAiDtD"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from "react";
3
+ import { useVanaConnect } from "./useVanaConnect.js";
4
+ /**
5
+ * Pre-built React component that displays connection status and a deep link.
6
+ *
7
+ * For full control over the UI, use {@link useVanaConnect} or {@link useVanaData} directly.
8
+ *
9
+ * @param props - Component props.
10
+ */
11
+ export function ConnectButton(props) {
12
+ const { sessionId, connectUrl: connectUrlProp, onComplete, onError, onDenied, className, label, } = props;
13
+ const { connect, status, grant, error, connectUrl } = useVanaConnect();
14
+ useEffect(() => {
15
+ connect({ sessionId, connectUrl: connectUrlProp });
16
+ }, [sessionId, connectUrlProp, connect]);
17
+ useEffect(() => {
18
+ if (status === "approved" && grant && onComplete) {
19
+ onComplete(grant);
20
+ }
21
+ if (status === "error" && error && onError) {
22
+ onError(error);
23
+ }
24
+ if (status === "denied" && onDenied) {
25
+ onDenied(error ?? "User denied the request");
26
+ }
27
+ }, [status, grant, error, onComplete, onError, onDenied]);
28
+ const statusText = {
29
+ idle: "Initializing...",
30
+ connecting: "Connecting...",
31
+ waiting: "Waiting for approval...",
32
+ approved: "Connected!",
33
+ denied: "Request denied",
34
+ expired: "Session expired",
35
+ error: "Connection error",
36
+ };
37
+ return (_jsxs("div", { className: className, children: [_jsx("p", { children: statusText[status] ?? status }), connectUrl && status === "waiting" && (_jsx("a", { href: connectUrl, target: "_blank", rel: "noopener noreferrer", children: label ?? "Connect with Vana" }))] }));
38
+ }
39
+ //# sourceMappingURL=ConnectButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectButton.js","sourceRoot":"","sources":["../../src/react/ConnectButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAoBrD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EACJ,SAAS,EACT,UAAU,EAAE,cAAc,EAC1B,UAAU,EACV,OAAO,EACP,QAAQ,EACR,SAAS,EACT,KAAK,GACN,GAAG,KAAK,CAAC;IAEV,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,cAAc,EAAE,CAAC;IAEvE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;IACrD,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IAEzC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,UAAU,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;YACjD,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,IAAI,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QACD,IAAI,MAAM,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACpC,QAAQ,CAAC,KAAK,IAAI,yBAAyB,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1D,MAAM,UAAU,GAA2B;QACzC,IAAI,EAAE,iBAAiB;QACvB,UAAU,EAAE,eAAe;QAC3B,OAAO,EAAE,yBAAyB;QAClC,QAAQ,EAAE,YAAY;QACtB,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE,iBAAiB;QAC1B,KAAK,EAAE,kBAAkB;KAC1B,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,SAAS,aACvB,sBAAI,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,GAAK,EACpC,UAAU,IAAI,MAAM,KAAK,SAAS,IAAI,CACrC,YAAG,IAAI,EAAE,UAAU,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,YAC3D,KAAK,IAAI,mBAAmB,GAC3B,CACL,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { useVanaConnect, type UseVanaConnectConfig, type UseVanaConnectResult, } from "./useVanaConnect.js";
2
+ export { ConnectButton, type ConnectButtonProps } from "./ConnectButton.js";
3
+ export { useVanaData, type UseVanaDataConfig, type UseVanaDataResult, } from "./useVanaData.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { useVanaConnect, } from "./useVanaConnect.js";
2
+ export { ConnectButton } from "./ConnectButton.js";
3
+ export { useVanaData, } from "./useVanaData.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,WAAW,GAGZ,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { ConnectionStatus, GrantPayload } from "../core/types.js";
2
+ /** Configuration for the {@link useVanaConnect} hook. */
3
+ export interface UseVanaConnectConfig {
4
+ /** Polling interval in milliseconds (default: 2000). */
5
+ pollingInterval?: number;
6
+ /** SDK environment (`"dev"` or `"prod"`). Defaults to `"prod"`. */
7
+ environment?: "dev" | "prod";
8
+ }
9
+ /** Return value of the {@link useVanaConnect} hook. */
10
+ export interface UseVanaConnectResult {
11
+ /** Starts polling the Session Relay for the given session. */
12
+ connect: (params: {
13
+ sessionId: string;
14
+ connectUrl?: string;
15
+ }) => void;
16
+ /** Current connection status. */
17
+ status: ConnectionStatus;
18
+ /** Grant payload after user approval, or `null`. */
19
+ grant: GrantPayload | null;
20
+ /** Error message, or `null`. */
21
+ error: string | null;
22
+ /** URL to account.vana.org where the user signs in and launches Data Connect, or `null`. */
23
+ connectUrl: string | null;
24
+ /** Resets all state back to idle and stops polling. */
25
+ reset: () => void;
26
+ }
27
+ /**
28
+ * React hook that polls the Session Relay and manages connection state.
29
+ *
30
+ * Call `connect()` with a session ID (from your server's `/api/connect` route)
31
+ * to begin polling. The hook will update `status` through the lifecycle:
32
+ * `idle` -> `connecting` -> `waiting` -> `approved` | `denied` | `expired` | `error`.
33
+ *
34
+ * @param config - Optional configuration for polling interval and environment.
35
+ * @returns A {@link UseVanaConnectResult} with state and actions.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const { connect, status, grant, connectUrl } = useVanaConnect();
40
+ *
41
+ * useEffect(() => {
42
+ * connect({ sessionId: "sess-123" });
43
+ * }, []);
44
+ *
45
+ * if (status === "waiting") return <a href={connectUrl!}>Open Vana</a>;
46
+ * if (status === "approved") return <p>Connected! Grant: {grant!.grantId}</p>;
47
+ * ```
48
+ */
49
+ export declare function useVanaConnect(config?: UseVanaConnectConfig): UseVanaConnectResult;
50
+ //# sourceMappingURL=useVanaConnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVanaConnect.d.ts","sourceRoot":"","sources":["../../src/react/useVanaConnect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EAEb,MAAM,kBAAkB,CAAC;AAE1B,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC9B;AAED,uDAAuD;AACvD,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,OAAO,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,iCAAiC;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oDAAoD;IACpD,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,gCAAgC;IAChC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uDAAuD;IACvD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,oBAAoB,GAC5B,oBAAoB,CA0GtB"}
@@ -0,0 +1,114 @@
1
+ import { useState, useCallback, useRef, useEffect } from "react";
2
+ import { getEnvConfig } from "../core/constants.js";
3
+ /**
4
+ * React hook that polls the Session Relay and manages connection state.
5
+ *
6
+ * Call `connect()` with a session ID (from your server's `/api/connect` route)
7
+ * to begin polling. The hook will update `status` through the lifecycle:
8
+ * `idle` -> `connecting` -> `waiting` -> `approved` | `denied` | `expired` | `error`.
9
+ *
10
+ * @param config - Optional configuration for polling interval and environment.
11
+ * @returns A {@link UseVanaConnectResult} with state and actions.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const { connect, status, grant, connectUrl } = useVanaConnect();
16
+ *
17
+ * useEffect(() => {
18
+ * connect({ sessionId: "sess-123" });
19
+ * }, []);
20
+ *
21
+ * if (status === "waiting") return <a href={connectUrl!}>Open Vana</a>;
22
+ * if (status === "approved") return <p>Connected! Grant: {grant!.grantId}</p>;
23
+ * ```
24
+ */
25
+ export function useVanaConnect(config) {
26
+ const envConfig = getEnvConfig(config?.environment);
27
+ const baseUrl = envConfig.sessionRelayUrl;
28
+ const accountUrl = envConfig.accountUrl;
29
+ const interval = config?.pollingInterval ?? 2000;
30
+ const [status, setStatus] = useState("idle");
31
+ const [grant, setGrant] = useState(null);
32
+ const [error, setError] = useState(null);
33
+ const [connectUrl, setConnectUrl] = useState(null);
34
+ const timerRef = useRef(null);
35
+ const stopPolling = useCallback(() => {
36
+ if (timerRef.current !== null) {
37
+ clearInterval(timerRef.current);
38
+ timerRef.current = null;
39
+ }
40
+ }, []);
41
+ const reset = useCallback(() => {
42
+ stopPolling();
43
+ setStatus("idle");
44
+ setGrant(null);
45
+ setError(null);
46
+ setConnectUrl(null);
47
+ }, [stopPolling]);
48
+ const connect = useCallback((params) => {
49
+ stopPolling();
50
+ setStatus("connecting");
51
+ setGrant(null);
52
+ setError(null);
53
+ setConnectUrl(params.connectUrl ??
54
+ `${accountUrl}/connect?sessionId=${params.sessionId}`);
55
+ const pollUrl = `${baseUrl}/v1/session/${params.sessionId}/poll`;
56
+ const poll = async () => {
57
+ try {
58
+ const res = await fetch(pollUrl);
59
+ if (!res.ok) {
60
+ // Try to extract structured error from response body
61
+ const body = await res.json().catch(() => null);
62
+ const errorCode = body && typeof body === "object"
63
+ ? body.error
64
+ ?.errorCode
65
+ : undefined;
66
+ if (res.status === 410 || errorCode === "SESSION_EXPIRED") {
67
+ setStatus("expired");
68
+ setError("Session expired");
69
+ }
70
+ else {
71
+ setStatus("error");
72
+ setError(`Poll failed: ${res.status}`);
73
+ }
74
+ stopPolling();
75
+ return;
76
+ }
77
+ const result = (await res.json());
78
+ switch (result.status) {
79
+ case "pending":
80
+ case "claimed":
81
+ setStatus("waiting");
82
+ break;
83
+ case "approved":
84
+ setStatus("approved");
85
+ setGrant(result.grant ?? null);
86
+ stopPolling();
87
+ break;
88
+ case "denied":
89
+ setStatus("denied");
90
+ setError(result.reason ?? "User denied the request");
91
+ stopPolling();
92
+ break;
93
+ case "expired":
94
+ setStatus("expired");
95
+ setError("Session expired");
96
+ stopPolling();
97
+ break;
98
+ }
99
+ }
100
+ catch (err) {
101
+ setStatus("error");
102
+ setError(err instanceof Error ? err.message : "Unknown polling error");
103
+ stopPolling();
104
+ }
105
+ };
106
+ // First poll immediately, then at interval
107
+ void poll();
108
+ timerRef.current = setInterval(() => void poll(), interval);
109
+ }, [baseUrl, accountUrl, interval, stopPolling]);
110
+ // Cleanup on unmount
111
+ useEffect(() => stopPolling, [stopPolling]);
112
+ return { connect, status, grant, error, connectUrl, reset };
113
+ }
114
+ //# sourceMappingURL=useVanaConnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVanaConnect.js","sourceRoot":"","sources":["../../src/react/useVanaConnect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { ConnectionStatus, GrantPayload } from "../core/types.js";
2
+ /**
3
+ * Configuration for the {@link useVanaData} hook.
4
+ */
5
+ export interface UseVanaDataConfig {
6
+ /** URL of the connect API route (default: `"/api/connect"`). */
7
+ connectUrl?: string;
8
+ /** URL of the data API route (default: `"/api/data"`). */
9
+ dataUrl?: string;
10
+ /** Polling interval in ms passed to {@link useVanaConnect} (default: 2000). */
11
+ pollingInterval?: number;
12
+ /** SDK environment passed through to {@link useVanaConnect}. */
13
+ environment?: "dev" | "prod";
14
+ /** When true, automatically fetches data after grant approval (default: `true`). */
15
+ autoFetch?: boolean;
16
+ }
17
+ /**
18
+ * Return value of the {@link useVanaData} hook.
19
+ */
20
+ export interface UseVanaDataResult {
21
+ /** Current connection status. */
22
+ status: ConnectionStatus;
23
+ /** Grant payload after user approval, or `null`. */
24
+ grant: GrantPayload | null;
25
+ /** Fetched data after calling the data route, or `null`. */
26
+ data: unknown;
27
+ /** Error message, or `null`. */
28
+ error: string | null;
29
+ /** URL to account.vana.org where the user signs in and launches Data Connect, or `null`. */
30
+ connectUrl: string | null;
31
+ /** Opens the connect URL in a new tab. Use this instead of rendering the URL directly to avoid navigating away from your app. */
32
+ openConnect: () => void;
33
+ /** Starts the connect flow by calling the connect API route. */
34
+ initConnect: () => Promise<void>;
35
+ /** Manually fetches data using the current grant. */
36
+ fetchData: () => Promise<void>;
37
+ /** Resets all state back to idle. */
38
+ reset: () => void;
39
+ /** `true` while any async operation is in progress. */
40
+ isLoading: boolean;
41
+ /** `true` when status is `"approved"`. */
42
+ isConnected: boolean;
43
+ }
44
+ /**
45
+ * Full-flow hook that orchestrates the entire Vana Connect lifecycle:
46
+ * session init, polling, and data fetching.
47
+ *
48
+ * Composes {@link useVanaConnect} internally and adds automatic
49
+ * calls to your app's `/api/connect` and `/api/data` routes.
50
+ *
51
+ * @param config - Optional configuration.
52
+ * @returns A {@link UseVanaDataResult} with state and actions.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { useVanaData } from "vana-cli/react";
57
+ *
58
+ * function MyComponent() {
59
+ * const { status, data, deepLinkUrl, initConnect, isLoading } = useVanaData();
60
+ *
61
+ * if (status === "idle") return <button onClick={initConnect}>Connect</button>;
62
+ * if (status === "waiting") return <a href={deepLinkUrl!}>Open Vana</a>;
63
+ * if (data) return <pre>{JSON.stringify(data, null, 2)}</pre>;
64
+ * return <p>{isLoading ? "Loading..." : status}</p>;
65
+ * }
66
+ * ```
67
+ */
68
+ export declare function useVanaData(config?: UseVanaDataConfig): UseVanaDataResult;
69
+ //# sourceMappingURL=useVanaData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVanaData.d.ts","sourceRoot":"","sources":["../../src/react/useVanaData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAevE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,oDAAoD;IACpD,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;IACd,gCAAgC;IAChC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iIAAiI;IACjI,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,gEAAgE;IAChE,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,qDAAqD;IACrD,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,qCAAqC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,CA8HzE"}