@opendatalabs/personal-server-ts-server 0.0.1-canary.0078f25

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 (101) hide show
  1. package/dist/api.d.ts +2 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +2 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/app.d.ts +35 -0
  6. package/dist/app.d.ts.map +1 -0
  7. package/dist/app.js +124 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/bootstrap.d.ts +35 -0
  10. package/dist/bootstrap.d.ts.map +1 -0
  11. package/dist/bootstrap.js +232 -0
  12. package/dist/bootstrap.js.map +1 -0
  13. package/dist/dev-token.d.ts +6 -0
  14. package/dist/dev-token.d.ts.map +1 -0
  15. package/dist/dev-token.js +9 -0
  16. package/dist/dev-token.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +60 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/middleware/access-log.d.ts +8 -0
  22. package/dist/middleware/access-log.d.ts.map +1 -0
  23. package/dist/middleware/access-log.js +38 -0
  24. package/dist/middleware/access-log.js.map +1 -0
  25. package/dist/middleware/body-limit.d.ts +10 -0
  26. package/dist/middleware/body-limit.d.ts.map +1 -0
  27. package/dist/middleware/body-limit.js +20 -0
  28. package/dist/middleware/body-limit.js.map +1 -0
  29. package/dist/middleware/builder-check.d.ts +8 -0
  30. package/dist/middleware/builder-check.d.ts.map +1 -0
  31. package/dist/middleware/builder-check.js +29 -0
  32. package/dist/middleware/builder-check.js.map +1 -0
  33. package/dist/middleware/grant-check.d.ts +12 -0
  34. package/dist/middleware/grant-check.d.ts.map +1 -0
  35. package/dist/middleware/grant-check.js +90 -0
  36. package/dist/middleware/grant-check.js.map +1 -0
  37. package/dist/middleware/owner-check.d.ts +9 -0
  38. package/dist/middleware/owner-check.d.ts.map +1 -0
  39. package/dist/middleware/owner-check.js +37 -0
  40. package/dist/middleware/owner-check.js.map +1 -0
  41. package/dist/middleware/web3-auth.d.ts +16 -0
  42. package/dist/middleware/web3-auth.d.ts.map +1 -0
  43. package/dist/middleware/web3-auth.js +58 -0
  44. package/dist/middleware/web3-auth.js.map +1 -0
  45. package/dist/routes/access-logs.d.ts +16 -0
  46. package/dist/routes/access-logs.d.ts.map +1 -0
  47. package/dist/routes/access-logs.js +30 -0
  48. package/dist/routes/access-logs.js.map +1 -0
  49. package/dist/routes/data.d.ts +20 -0
  50. package/dist/routes/data.d.ts.map +1 -0
  51. package/dist/routes/data.js +213 -0
  52. package/dist/routes/data.js.map +1 -0
  53. package/dist/routes/grants.d.ts +17 -0
  54. package/dist/routes/grants.d.ts.map +1 -0
  55. package/dist/routes/grants.js +208 -0
  56. package/dist/routes/grants.js.map +1 -0
  57. package/dist/routes/health.d.ts +16 -0
  58. package/dist/routes/health.d.ts.map +1 -0
  59. package/dist/routes/health.js +37 -0
  60. package/dist/routes/health.js.map +1 -0
  61. package/dist/routes/mcp.d.ts +7 -0
  62. package/dist/routes/mcp.d.ts.map +1 -0
  63. package/dist/routes/mcp.js +14 -0
  64. package/dist/routes/mcp.js.map +1 -0
  65. package/dist/routes/sync.d.ts +16 -0
  66. package/dist/routes/sync.d.ts.map +1 -0
  67. package/dist/routes/sync.js +52 -0
  68. package/dist/routes/sync.js.map +1 -0
  69. package/dist/routes/ui-config.d.ts +7 -0
  70. package/dist/routes/ui-config.d.ts.map +1 -0
  71. package/dist/routes/ui-config.js +89 -0
  72. package/dist/routes/ui-config.js.map +1 -0
  73. package/dist/routes/ui.d.ts +6 -0
  74. package/dist/routes/ui.d.ts.map +1 -0
  75. package/dist/routes/ui.js +36 -0
  76. package/dist/routes/ui.js.map +1 -0
  77. package/dist/tunnel/auth.d.ts +46 -0
  78. package/dist/tunnel/auth.d.ts.map +1 -0
  79. package/dist/tunnel/auth.js +46 -0
  80. package/dist/tunnel/auth.js.map +1 -0
  81. package/dist/tunnel/binary.d.ts +57 -0
  82. package/dist/tunnel/binary.d.ts.map +1 -0
  83. package/dist/tunnel/binary.js +180 -0
  84. package/dist/tunnel/binary.js.map +1 -0
  85. package/dist/tunnel/config.d.ts +27 -0
  86. package/dist/tunnel/config.d.ts.map +1 -0
  87. package/dist/tunnel/config.js +38 -0
  88. package/dist/tunnel/config.js.map +1 -0
  89. package/dist/tunnel/index.d.ts +13 -0
  90. package/dist/tunnel/index.d.ts.map +1 -0
  91. package/dist/tunnel/index.js +9 -0
  92. package/dist/tunnel/index.js.map +1 -0
  93. package/dist/tunnel/manager.d.ts +88 -0
  94. package/dist/tunnel/manager.d.ts.map +1 -0
  95. package/dist/tunnel/manager.js +279 -0
  96. package/dist/tunnel/manager.js.map +1 -0
  97. package/dist/tunnel/verify.d.ts +28 -0
  98. package/dist/tunnel/verify.d.ts.map +1 -0
  99. package/dist/tunnel/verify.js +40 -0
  100. package/dist/tunnel/verify.js.map +1 -0
  101. package/package.json +47 -0
@@ -0,0 +1,279 @@
1
+ /**
2
+ * TunnelManager handles the frpc process lifecycle.
3
+ *
4
+ * Responsibilities:
5
+ * - Generate signed claim and frpc.toml config
6
+ * - Spawn frpc process with a caller-provided binary path
7
+ * - Monitor process lifecycle
8
+ * - Periodically refresh the auth claim before it expires
9
+ * - Provide status for health endpoint
10
+ */
11
+ import { spawn } from "node:child_process";
12
+ import { writeFile, mkdir, chmod, access, constants } from "node:fs/promises";
13
+ import { join } from "node:path";
14
+ import { generateSignedClaim, CLAIM_TTL_SECONDS } from "./auth.js";
15
+ import { generateFrpcConfig } from "./config.js";
16
+ import { buildTunnelUrl } from "./verify.js";
17
+ /** Refresh at 80% of TTL to leave buffer before expiry. */
18
+ const REFRESH_INTERVAL_MS = CLAIM_TTL_SECONDS * 0.8 * 1000;
19
+ /** Retry interval when a refresh attempt fails. */
20
+ const REFRESH_RETRY_MS = 30_000;
21
+ export class TunnelManager {
22
+ storageRoot;
23
+ process = null;
24
+ status = "stopped";
25
+ publicUrl = null;
26
+ connectedSince = null;
27
+ lastError = null;
28
+ config = null;
29
+ binaryPath = null;
30
+ refreshTimer = null;
31
+ refreshing = false;
32
+ constructor(storageRoot) {
33
+ this.storageRoot = storageRoot;
34
+ }
35
+ /**
36
+ * Start the frpc process with the given configuration.
37
+ * Returns the public URL once the tunnel is established.
38
+ * Automatically schedules periodic claim refresh.
39
+ */
40
+ async start(config, binaryPath) {
41
+ if (this.process) {
42
+ throw new Error("Tunnel already running");
43
+ }
44
+ this.config = config;
45
+ this.binaryPath = binaryPath;
46
+ this.status = "starting";
47
+ this.lastError = null;
48
+ // Verify binary exists and is executable
49
+ try {
50
+ await access(binaryPath, constants.X_OK);
51
+ }
52
+ catch {
53
+ try {
54
+ await chmod(binaryPath, 0o755);
55
+ }
56
+ catch {
57
+ throw new Error(`frpc binary not found or not executable: ${binaryPath}`);
58
+ }
59
+ }
60
+ const subdomain = config.walletAddress.toLowerCase();
61
+ this.publicUrl = buildTunnelUrl(subdomain);
62
+ const configPath = await this.writeFreshConfig(subdomain);
63
+ await this.spawnProcess(configPath);
64
+ this.scheduleRefresh();
65
+ return this.publicUrl;
66
+ }
67
+ /**
68
+ * Stop the frpc process gracefully.
69
+ */
70
+ async stop() {
71
+ this.clearRefreshTimer();
72
+ if (!this.process) {
73
+ return;
74
+ }
75
+ return new Promise((resolve) => {
76
+ const proc = this.process;
77
+ const timeout = setTimeout(() => {
78
+ // Force kill if graceful shutdown takes too long
79
+ proc.kill("SIGKILL");
80
+ resolve();
81
+ }, 5000);
82
+ proc.on("exit", () => {
83
+ clearTimeout(timeout);
84
+ this.process = null;
85
+ this.status = "stopped";
86
+ this.publicUrl = null;
87
+ this.connectedSince = null;
88
+ resolve();
89
+ });
90
+ // Send SIGTERM for graceful shutdown
91
+ proc.kill("SIGTERM");
92
+ });
93
+ }
94
+ /**
95
+ * Check if the tunnel is currently running.
96
+ */
97
+ isRunning() {
98
+ return this.process !== null && this.status === "connected";
99
+ }
100
+ /**
101
+ * Update status based on external verification of the tunnel URL.
102
+ */
103
+ setVerified(reachable, error) {
104
+ if (reachable) {
105
+ this.status = "connected";
106
+ this.lastError = null;
107
+ }
108
+ else {
109
+ this.status = "error";
110
+ this.lastError = error ?? "Tunnel URL not reachable";
111
+ }
112
+ }
113
+ /**
114
+ * Get the current tunnel status.
115
+ */
116
+ getStatus() {
117
+ return {
118
+ enabled: true,
119
+ status: this.status,
120
+ publicUrl: this.publicUrl,
121
+ connectedSince: this.connectedSince?.toISOString() ?? null,
122
+ error: this.lastError ?? undefined,
123
+ };
124
+ }
125
+ /**
126
+ * Get the public URL if connected.
127
+ */
128
+ getPublicUrl() {
129
+ return this.publicUrl;
130
+ }
131
+ // ---------------------------------------------------------------------------
132
+ // Private helpers
133
+ // ---------------------------------------------------------------------------
134
+ /**
135
+ * Generate a fresh signed claim, write frpc.toml, and return the config path.
136
+ */
137
+ async writeFreshConfig(subdomain) {
138
+ const config = this.config;
139
+ const { claim, sig } = await generateSignedClaim({
140
+ ownerAddress: config.ownerAddress,
141
+ walletAddress: config.walletAddress,
142
+ runId: config.runId,
143
+ serverKeypair: config.serverKeypair,
144
+ });
145
+ const frpcConfig = generateFrpcConfig({
146
+ serverAddr: config.serverAddr,
147
+ serverPort: config.serverPort,
148
+ localPort: config.localPort,
149
+ subdomain,
150
+ walletAddress: config.walletAddress,
151
+ ownerAddress: config.ownerAddress,
152
+ runId: config.runId,
153
+ authClaim: claim,
154
+ authSig: sig,
155
+ });
156
+ const tunnelDir = join(this.storageRoot, "tunnel");
157
+ await mkdir(tunnelDir, { recursive: true });
158
+ const configPath = join(tunnelDir, "frpc.toml");
159
+ await writeFile(configPath, frpcConfig, "utf-8");
160
+ return configPath;
161
+ }
162
+ /**
163
+ * Spawn the frpc process and wait for it to report a successful connection
164
+ * (or resolve optimistically after a timeout).
165
+ */
166
+ async spawnProcess(configPath) {
167
+ return new Promise((resolve, reject) => {
168
+ const proc = spawn(this.binaryPath, ["-c", configPath], {
169
+ stdio: ["ignore", "pipe", "pipe"],
170
+ });
171
+ this.process = proc;
172
+ let startupOutput = "";
173
+ let resolved = false;
174
+ const onData = (data) => {
175
+ const text = data.toString();
176
+ startupOutput += text;
177
+ if (text.includes("start proxy success") ||
178
+ text.includes("login to server success")) {
179
+ if (!resolved) {
180
+ resolved = true;
181
+ this.status = "connected";
182
+ this.connectedSince = new Date();
183
+ resolve();
184
+ }
185
+ }
186
+ };
187
+ proc.stdout?.on("data", onData);
188
+ proc.stderr?.on("data", onData);
189
+ proc.on("error", (err) => {
190
+ this.status = "error";
191
+ this.lastError = err.message;
192
+ if (!resolved) {
193
+ resolved = true;
194
+ reject(new Error(`Failed to start frpc: ${err.message}`));
195
+ }
196
+ });
197
+ proc.on("exit", (code) => {
198
+ this.process = null;
199
+ // During a planned refresh cycle, don't update status
200
+ if (this.refreshing)
201
+ return;
202
+ if (code !== 0 && !resolved) {
203
+ this.status = "error";
204
+ this.lastError = `frpc exited with code ${code}: ${startupOutput}`;
205
+ resolved = true;
206
+ reject(new Error(this.lastError));
207
+ }
208
+ else if (this.status === "connected") {
209
+ this.status = "disconnected";
210
+ }
211
+ });
212
+ // Timeout for startup — resolve optimistically
213
+ setTimeout(() => {
214
+ if (!resolved) {
215
+ resolved = true;
216
+ this.status = "connected";
217
+ this.connectedSince = new Date();
218
+ resolve();
219
+ }
220
+ }, 10_000);
221
+ });
222
+ }
223
+ /**
224
+ * Kill the running frpc process and wait for it to exit.
225
+ */
226
+ async killProcess() {
227
+ if (!this.process)
228
+ return;
229
+ return new Promise((resolve) => {
230
+ const proc = this.process;
231
+ const timeout = setTimeout(() => {
232
+ proc.kill("SIGKILL");
233
+ this.process = null;
234
+ resolve();
235
+ }, 3000);
236
+ proc.once("exit", () => {
237
+ clearTimeout(timeout);
238
+ this.process = null;
239
+ resolve();
240
+ });
241
+ proc.kill("SIGTERM");
242
+ });
243
+ }
244
+ scheduleRefresh() {
245
+ this.clearRefreshTimer();
246
+ this.refreshTimer = setTimeout(() => void this.refreshClaim(), REFRESH_INTERVAL_MS);
247
+ }
248
+ clearRefreshTimer() {
249
+ if (this.refreshTimer) {
250
+ clearTimeout(this.refreshTimer);
251
+ this.refreshTimer = null;
252
+ }
253
+ }
254
+ /**
255
+ * Refresh the auth claim by rewriting frpc.toml and restarting the process.
256
+ * On failure, retries after a shorter interval.
257
+ */
258
+ async refreshClaim() {
259
+ if (!this.config || !this.binaryPath)
260
+ return;
261
+ const subdomain = this.config.walletAddress.toLowerCase();
262
+ try {
263
+ const configPath = await this.writeFreshConfig(subdomain);
264
+ // Stop old process (suppress status change during restart)
265
+ this.refreshing = true;
266
+ await this.killProcess();
267
+ this.refreshing = false;
268
+ this.status = "starting";
269
+ await this.spawnProcess(configPath);
270
+ this.scheduleRefresh();
271
+ }
272
+ catch {
273
+ this.refreshing = false;
274
+ // Retry sooner on failure
275
+ this.refreshTimer = setTimeout(() => void this.refreshClaim(), REFRESH_RETRY_MS);
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/tunnel/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tunnel URL helpers: build the canonical tunnel URL and verify reachability.
3
+ */
4
+ export interface VerifyTunnelOptions {
5
+ /** Maximum number of attempts (default: 5) */
6
+ maxAttempts?: number;
7
+ /** Delay between retries in ms (default: 2000) */
8
+ retryDelayMs?: number;
9
+ /** Timeout per request in ms (default: 5000) */
10
+ timeoutMs?: number;
11
+ /** Custom fetch implementation (for testing) */
12
+ fetchFn?: typeof fetch;
13
+ }
14
+ export interface VerifyTunnelResult {
15
+ reachable: boolean;
16
+ attempts: number;
17
+ error?: string;
18
+ }
19
+ /**
20
+ * Build the canonical tunnel URL for a wallet address.
21
+ */
22
+ export declare function buildTunnelUrl(walletAddress: string): string;
23
+ /**
24
+ * Verify that a tunnel URL is reachable by hitting its /health endpoint.
25
+ * Retries on failure with configurable attempts, delay, and timeout.
26
+ */
27
+ export declare function verifyTunnelUrl(publicUrl: string, options?: VerifyTunnelOptions): Promise<VerifyTunnelResult>;
28
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/tunnel/verify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CA4B7B"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Tunnel URL helpers: build the canonical tunnel URL and verify reachability.
3
+ */
4
+ /**
5
+ * Build the canonical tunnel URL for a wallet address.
6
+ */
7
+ export function buildTunnelUrl(walletAddress) {
8
+ return `https://${walletAddress.toLowerCase()}.server.vana.org`;
9
+ }
10
+ /**
11
+ * Verify that a tunnel URL is reachable by hitting its /health endpoint.
12
+ * Retries on failure with configurable attempts, delay, and timeout.
13
+ */
14
+ export async function verifyTunnelUrl(publicUrl, options) {
15
+ const maxAttempts = options?.maxAttempts ?? 5;
16
+ const retryDelayMs = options?.retryDelayMs ?? 2000;
17
+ const timeoutMs = options?.timeoutMs ?? 5000;
18
+ const fetchFn = options?.fetchFn ?? fetch;
19
+ const healthUrl = `${publicUrl}/health`;
20
+ let lastError;
21
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
22
+ try {
23
+ const response = await fetchFn(healthUrl, {
24
+ signal: AbortSignal.timeout(timeoutMs),
25
+ });
26
+ if (response.ok) {
27
+ return { reachable: true, attempts: attempt };
28
+ }
29
+ lastError = `HTTP ${response.status}`;
30
+ }
31
+ catch (err) {
32
+ lastError = err instanceof Error ? err.message : "Unknown error";
33
+ }
34
+ if (attempt < maxAttempts) {
35
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
36
+ }
37
+ }
38
+ return { reachable: false, attempts: maxAttempts, error: lastError };
39
+ }
40
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/tunnel/verify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB;IAClD,OAAO,WAAW,aAAa,CAAC,WAAW,EAAE,kBAAkB,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,OAA6B;IAE7B,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC;IACnD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;IAC7C,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;IAE1C,MAAM,SAAS,GAAG,GAAG,SAAS,SAAS,CAAC;IACxC,IAAI,SAA6B,CAAC;IAElC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE;gBACxC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;aACvC,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YAChD,CAAC;YACD,SAAS,GAAG,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACnE,CAAC;QAED,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;YAC1B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACvE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@opendatalabs/personal-server-ts-server",
3
+ "version": "0.0.1-canary.0078f25",
4
+ "description": "Hono HTTP server for the Vana Personal Server — routes, middleware, composition root",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/vana-com/personal-server-ts.git",
9
+ "directory": "packages/server"
10
+ },
11
+ "homepage": "https://github.com/vana-com/personal-server-ts#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/vana-com/personal-server-ts/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/api.js",
17
+ "types": "./dist/api.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/api.d.ts",
21
+ "import": "./dist/api.js"
22
+ },
23
+ "./runtime": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "scripts": {
35
+ "copy-ui": "mkdir -p dist/ui && cp src/ui/index.html dist/ui/index.html",
36
+ "build": "tsc --build && npm run copy-ui",
37
+ "start": "node dist/index.js",
38
+ "dev": "node --watch dist/index.js"
39
+ },
40
+ "dependencies": {
41
+ "@opendatalabs/personal-server-ts-core": "0.0.1-canary.0078f25",
42
+ "@opendatalabs/personal-server-ts-mcp": "*",
43
+ "@modelcontextprotocol/sdk": "^1.27.0",
44
+ "hono": "^4.7.0",
45
+ "@hono/node-server": "^1.14.0"
46
+ }
47
+ }