vana-cli 0.25.0 → 0.26.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 (40) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/auth.d.ts +2 -0
  3. package/dist/cli/auth.d.ts.map +1 -1
  4. package/dist/cli/auth.js +2 -1
  5. package/dist/cli/auth.js.map +1 -1
  6. package/dist/cli/index.d.ts.map +1 -1
  7. package/dist/cli/index.js +37 -1
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/server-start.d.ts +42 -0
  10. package/dist/cli/server-start.d.ts.map +1 -0
  11. package/dist/cli/server-start.js +189 -0
  12. package/dist/cli/server-start.js.map +1 -0
  13. package/dist/personal-server/index.d.ts +1 -0
  14. package/dist/personal-server/index.d.ts.map +1 -1
  15. package/dist/personal-server/index.js +17 -2
  16. package/dist/personal-server/index.js.map +1 -1
  17. package/dist/personal-server/local/config.d.ts +23 -0
  18. package/dist/personal-server/local/config.d.ts.map +1 -0
  19. package/dist/personal-server/local/config.js +51 -0
  20. package/dist/personal-server/local/config.js.map +1 -0
  21. package/dist/personal-server/local/owner-binding.d.ts +33 -0
  22. package/dist/personal-server/local/owner-binding.d.ts.map +1 -0
  23. package/dist/personal-server/local/owner-binding.js +155 -0
  24. package/dist/personal-server/local/owner-binding.js.map +1 -0
  25. package/dist/personal-server/local/owner-secret.d.ts +17 -0
  26. package/dist/personal-server/local/owner-secret.d.ts.map +1 -0
  27. package/dist/personal-server/local/owner-secret.js +119 -0
  28. package/dist/personal-server/local/owner-secret.js.map +1 -0
  29. package/dist/personal-server/local/runtime-pkg/entry.mjs +153 -0
  30. package/dist/personal-server/local/runtime-pkg/package-lock.json +2342 -0
  31. package/dist/personal-server/local/runtime-pkg/package.json +13 -0
  32. package/dist/personal-server/local/runtime.d.ts +9 -0
  33. package/dist/personal-server/local/runtime.d.ts.map +1 -0
  34. package/dist/personal-server/local/runtime.js +66 -0
  35. package/dist/personal-server/local/runtime.js.map +1 -0
  36. package/dist/personal-server/local/server.d.ts +39 -0
  37. package/dist/personal-server/local/server.d.ts.map +1 -0
  38. package/dist/personal-server/local/server.js +203 -0
  39. package/dist/personal-server/local/server.js.map +1 -0
  40. package/package.json +1 -1
@@ -0,0 +1,119 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { localServerHome } from "./config.js";
5
+ const KEYCHAIN_SERVICE = "org.vana.cli.personal-server-owner";
6
+ export function ownerSecretKey(accountUrl, address) {
7
+ return `${new URL(accountUrl).host}:${address.toLowerCase()}`;
8
+ }
9
+ function parse(raw) {
10
+ if (!raw)
11
+ return null;
12
+ try {
13
+ const value = JSON.parse(raw);
14
+ if (typeof value.signature === "string" &&
15
+ typeof value.signerAddress === "string") {
16
+ return {
17
+ signature: value.signature,
18
+ signerAddress: value.signerAddress,
19
+ trustToken: typeof value.trustToken === "string" ? value.trustToken : null,
20
+ };
21
+ }
22
+ }
23
+ catch {
24
+ // Unreadable entry: treat as absent.
25
+ }
26
+ return null;
27
+ }
28
+ function keychainStore() {
29
+ const run = (args) => execFileSync("security", args, {
30
+ encoding: "utf8",
31
+ stdio: ["ignore", "pipe", "ignore"],
32
+ });
33
+ return {
34
+ get(key) {
35
+ try {
36
+ return parse(run([
37
+ "find-generic-password",
38
+ "-s",
39
+ KEYCHAIN_SERVICE,
40
+ "-a",
41
+ key,
42
+ "-w",
43
+ ]).trim());
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ },
49
+ set(key, binding) {
50
+ run([
51
+ "add-generic-password",
52
+ "-U",
53
+ "-s",
54
+ KEYCHAIN_SERVICE,
55
+ "-a",
56
+ key,
57
+ "-w",
58
+ JSON.stringify(binding),
59
+ ]);
60
+ },
61
+ delete(key) {
62
+ try {
63
+ run(["delete-generic-password", "-s", KEYCHAIN_SERVICE, "-a", key]);
64
+ }
65
+ catch {
66
+ // Already gone.
67
+ }
68
+ },
69
+ };
70
+ }
71
+ function fileStore(file = path.join(localServerHome(), "owner-bindings.json")) {
72
+ const read = () => {
73
+ try {
74
+ return JSON.parse(fs.readFileSync(file, "utf8"));
75
+ }
76
+ catch {
77
+ return {};
78
+ }
79
+ };
80
+ const write = (entries) => {
81
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
82
+ fs.writeFileSync(file, `${JSON.stringify(entries, null, 2)}\n`, {
83
+ mode: 0o600,
84
+ });
85
+ };
86
+ return {
87
+ get: (key) => parse(read()[key]),
88
+ set(key, binding) {
89
+ write({ ...read(), [key]: JSON.stringify(binding) });
90
+ },
91
+ delete(key) {
92
+ const entries = read();
93
+ delete entries[key];
94
+ write(entries);
95
+ },
96
+ };
97
+ }
98
+ // Without a default keychain (a HOME with no login keychain, a fresh
99
+ // account), `security add-generic-password` does not fail: it puts up a GUI
100
+ // dialog and waits. Asking for the default keychain never prompts.
101
+ function hasDefaultKeychain() {
102
+ try {
103
+ execFileSync("security", ["default-keychain"], {
104
+ stdio: ["ignore", "ignore", "ignore"],
105
+ timeout: 5_000,
106
+ });
107
+ return true;
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ export function defaultOwnerSecretStore() {
114
+ return process.platform === "darwin" && hasDefaultKeychain()
115
+ ? keychainStore()
116
+ : fileStore();
117
+ }
118
+ export { fileStore as fileOwnerSecretStore };
119
+ //# sourceMappingURL=owner-secret.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-secret.js","sourceRoot":"","sources":["../../../src/personal-server/local/owner-secret.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ // The Personal Server process `vana server start` runs, modeled on Vana
2
+ // Desktop's sidecar (apps/desktop/personal-server/index.js in unity-surfaces).
3
+ //
4
+ // It reads one JSON line on stdin, so the owner signature never appears in the
5
+ // process list or environment:
6
+ // { rootPath, port, ownerSignature, ownerAddress, network: { gatewayUrl, chainId,
7
+ // contracts, storageApiUrl } }
8
+ // and writes one JSON object per line on stdout: ready, error, stopped.
9
+ // Logs go to stderr.
10
+
11
+ import { readFile, rename, writeFile } from "node:fs/promises";
12
+ import { join } from "node:path";
13
+ import readline from "node:readline";
14
+
15
+ import {
16
+ loadConfig,
17
+ startPersonalServer,
18
+ } from "@opendatalabs/personal-server-ts/node";
19
+
20
+ const send = (message) => process.stdout.write(`${JSON.stringify(message)}\n`);
21
+
22
+ function isPlainObject(value) {
23
+ return (
24
+ typeof value === "object" &&
25
+ value !== null &&
26
+ !Array.isArray(value) &&
27
+ Object.getPrototypeOf(value) !== null
28
+ );
29
+ }
30
+
31
+ // Derived leaves win and every other persisted key survives, as in Desktop's
32
+ // applyDerivedServerConfig.
33
+ function applyDerived(persisted, derived) {
34
+ if (!isPlainObject(persisted)) return structuredClone(derived);
35
+ const merged = { ...persisted };
36
+ for (const [key, value] of Object.entries(derived)) {
37
+ merged[key] =
38
+ isPlainObject(value) && isPlainObject(merged[key])
39
+ ? applyDerived(merged[key], value)
40
+ : structuredClone(value);
41
+ }
42
+ return merged;
43
+ }
44
+
45
+ // Everything that follows from the network. Local only for now: no tunnel,
46
+ // so nothing is reachable from outside and nothing may be registered, and no
47
+ // sync to Vana storage until registration exists.
48
+ function derivedConfig(network) {
49
+ return {
50
+ devUi: { enabled: true },
51
+ gateway: {
52
+ url: network.gatewayUrl,
53
+ chainId: network.chainId,
54
+ contracts: network.contracts,
55
+ },
56
+ inference: {
57
+ baseUrl: `${network.gatewayUrl.replace(/\/+$/, "")}/v1/inference`,
58
+ },
59
+ logging: { level: "info", pretty: false },
60
+ storage: {
61
+ backend: "vana",
62
+ config: { vana: { apiUrl: network.storageApiUrl } },
63
+ },
64
+ sync: { enabled: false },
65
+ tunnel: { enabled: false },
66
+ };
67
+ }
68
+
69
+ async function readInput() {
70
+ const rl = readline.createInterface({ input: process.stdin });
71
+ for await (const line of rl) {
72
+ if (line.trim()) {
73
+ rl.close();
74
+ return JSON.parse(line);
75
+ }
76
+ }
77
+ throw new Error("No configuration on stdin.");
78
+ }
79
+
80
+ let ps = null;
81
+
82
+ async function main() {
83
+ const input = await readInput();
84
+ const { rootPath, port, ownerSignature, ownerAddress, network } = input;
85
+ const configPath = join(rootPath, "server.json");
86
+ const derived = derivedConfig(network);
87
+
88
+ // Persist the derived block the way Desktop does, so a network change can
89
+ // never leave an old gateway or storage host behind in server.json.
90
+ let persisted = null;
91
+ try {
92
+ persisted = JSON.parse(await readFile(configPath, "utf8"));
93
+ } catch {
94
+ persisted = null;
95
+ }
96
+ const next = applyDerived(persisted, derived);
97
+ const temporary = `${configPath}.${process.pid}.tmp`;
98
+ await writeFile(temporary, `${JSON.stringify(next, null, 2)}\n`, {
99
+ mode: 0o600,
100
+ });
101
+ await rename(temporary, configPath);
102
+
103
+ // configDefaults merges shallowly for some sections, so hand back whole
104
+ // sections from the schema-complete loaded config.
105
+ const loaded = await loadConfig({ configPath, rootPath });
106
+ const configDefaults = {
107
+ server: {
108
+ ...loaded.server,
109
+ port,
110
+ ...(ownerAddress ? { address: ownerAddress } : {}),
111
+ },
112
+ };
113
+ for (const key of Object.keys(derived)) {
114
+ configDefaults[key] = applyDerived(loaded[key], derived[key]);
115
+ }
116
+
117
+ ps = await startPersonalServer({
118
+ configPath,
119
+ rootPath,
120
+ port,
121
+ ownerSignature,
122
+ mcpOAuthApprovalUrl: "vana://mcp-authorization",
123
+ configDefaults,
124
+ onStatus: (status) => process.stderr.write(`[status] ${status}\n`),
125
+ });
126
+ const info = await ps.ready();
127
+ send({
128
+ type: "ready",
129
+ port,
130
+ url: info.urls?.local ?? `http://localhost:${port}`,
131
+ });
132
+ }
133
+
134
+ async function shutdown(signal) {
135
+ process.stderr.write(`[entry] ${signal}, stopping\n`);
136
+ try {
137
+ await ps?.stop();
138
+ } finally {
139
+ send({ type: "stopped" });
140
+ process.exit(0);
141
+ }
142
+ }
143
+
144
+ process.on("SIGINT", () => void shutdown("SIGINT"));
145
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
146
+
147
+ main().catch((error) => {
148
+ send({
149
+ type: "error",
150
+ message: error instanceof Error ? error.message : String(error),
151
+ });
152
+ process.exit(1);
153
+ });