@nodetool-ai/config 0.7.0-rc.23 → 0.8.2

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 (94) hide show
  1. package/README.md +50 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/__tests__/credit-policy.test.d.ts +2 -0
  4. package/dist/__tests__/credit-policy.test.d.ts.map +1 -0
  5. package/dist/__tests__/credit-policy.test.js +48 -0
  6. package/dist/__tests__/credit-policy.test.js.map +1 -0
  7. package/dist/__tests__/env-file.test.d.ts +2 -0
  8. package/dist/__tests__/env-file.test.d.ts.map +1 -0
  9. package/dist/__tests__/env-file.test.js +100 -0
  10. package/dist/__tests__/env-file.test.js.map +1 -0
  11. package/dist/__tests__/google-workspace.test.d.ts +2 -0
  12. package/dist/__tests__/google-workspace.test.d.ts.map +1 -0
  13. package/dist/__tests__/google-workspace.test.js +40 -0
  14. package/dist/__tests__/google-workspace.test.js.map +1 -0
  15. package/dist/__tests__/retention.test.d.ts +2 -0
  16. package/dist/__tests__/retention.test.d.ts.map +1 -0
  17. package/dist/__tests__/retention.test.js +21 -0
  18. package/dist/__tests__/retention.test.js.map +1 -0
  19. package/dist/byte-limits.d.ts +13 -0
  20. package/dist/byte-limits.d.ts.map +1 -0
  21. package/dist/byte-limits.js +28 -0
  22. package/dist/byte-limits.js.map +1 -0
  23. package/dist/credit-policy.d.ts +25 -0
  24. package/dist/credit-policy.d.ts.map +1 -0
  25. package/dist/credit-policy.js +63 -0
  26. package/dist/credit-policy.js.map +1 -0
  27. package/dist/deployment.d.ts +8 -0
  28. package/dist/deployment.d.ts.map +1 -0
  29. package/dist/deployment.js +19 -0
  30. package/dist/deployment.js.map +1 -0
  31. package/dist/env-file.d.ts +33 -0
  32. package/dist/env-file.d.ts.map +1 -0
  33. package/dist/env-file.js +83 -0
  34. package/dist/env-file.js.map +1 -0
  35. package/dist/environment.d.ts.map +1 -1
  36. package/dist/environment.js +20 -17
  37. package/dist/environment.js.map +1 -1
  38. package/dist/google-workspace.d.ts +3 -0
  39. package/dist/google-workspace.d.ts.map +1 -0
  40. package/dist/google-workspace.js +23 -0
  41. package/dist/google-workspace.js.map +1 -0
  42. package/dist/index.d.ts +14 -4
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +14 -4
  45. package/dist/index.js.map +1 -1
  46. package/dist/logging.d.ts +12 -0
  47. package/dist/logging.d.ts.map +1 -1
  48. package/dist/logging.js +65 -28
  49. package/dist/logging.js.map +1 -1
  50. package/dist/node-import.d.ts +37 -0
  51. package/dist/node-import.d.ts.map +1 -0
  52. package/dist/node-import.js +119 -0
  53. package/dist/node-import.js.map +1 -0
  54. package/dist/optional-modules.d.ts +10 -0
  55. package/dist/optional-modules.d.ts.map +1 -0
  56. package/dist/optional-modules.js +58 -0
  57. package/dist/optional-modules.js.map +1 -0
  58. package/dist/package-asset-registry.d.ts +102 -0
  59. package/dist/package-asset-registry.d.ts.map +1 -0
  60. package/dist/package-asset-registry.js +157 -0
  61. package/dist/package-asset-registry.js.map +1 -0
  62. package/dist/package-assets.d.ts +52 -0
  63. package/dist/package-assets.d.ts.map +1 -0
  64. package/dist/package-assets.js +98 -0
  65. package/dist/package-assets.js.map +1 -0
  66. package/dist/paths.d.ts +52 -23
  67. package/dist/paths.d.ts.map +1 -1
  68. package/dist/paths.js +166 -47
  69. package/dist/paths.js.map +1 -1
  70. package/dist/retention.d.ts +3 -0
  71. package/dist/retention.d.ts.map +1 -0
  72. package/dist/retention.js +19 -0
  73. package/dist/retention.js.map +1 -0
  74. package/dist/setting-catalog.d.ts +28 -0
  75. package/dist/setting-catalog.d.ts.map +1 -0
  76. package/dist/setting-catalog.js +167 -0
  77. package/dist/setting-catalog.js.map +1 -0
  78. package/dist/storage-config.d.ts +45 -0
  79. package/dist/storage-config.d.ts.map +1 -0
  80. package/dist/storage-config.js +62 -0
  81. package/dist/storage-config.js.map +1 -0
  82. package/dist/trace-redaction.d.ts +5 -0
  83. package/dist/trace-redaction.d.ts.map +1 -0
  84. package/dist/trace-redaction.js +51 -0
  85. package/dist/trace-redaction.js.map +1 -0
  86. package/package.json +23 -8
  87. package/dist/diagnostics.d.ts +0 -27
  88. package/dist/diagnostics.d.ts.map +0 -1
  89. package/dist/diagnostics.js +0 -42
  90. package/dist/diagnostics.js.map +0 -1
  91. package/dist/settings.d.ts +0 -29
  92. package/dist/settings.d.ts.map +0 -1
  93. package/dist/settings.js +0 -29
  94. package/dist/settings.js.map +0 -1
package/dist/paths.js CHANGED
@@ -5,9 +5,21 @@
5
5
  * re-implement OS detection or XDG logic.
6
6
  *
7
7
  * Priority: explicit env var > platform default.
8
+ *
9
+ * The `node:path` / `node:os` / `node:url` imports are loaded lazily via
10
+ * top-level dynamic import so this module loads on non-Node runtimes
11
+ * (browser, Edge). All exported functions throw if invoked off-Node.
8
12
  */
9
- import { join } from "node:path";
10
- import { homedir } from "node:os";
13
+ import { IS_NODE, getNodeBuiltinSync } from "./node-import.js";
14
+ const pathLib = getNodeBuiltinSync("node:path");
15
+ const osLib = getNodeBuiltinSync("node:os");
16
+ const urlLib = getNodeBuiltinSync("node:url");
17
+ function notOnNode(name) {
18
+ throw new Error(`paths.${name}() is Node-only and not available in this runtime`);
19
+ }
20
+ const join = (...parts) => pathLib ? pathLib.join(...parts) : notOnNode("join");
21
+ const homedir = () => (osLib ? osLib.homedir() : notOnNode("homedir"));
22
+ const fileURLToPath = (url) => urlLib ? urlLib.fileURLToPath(url) : notOnNode("fileURLToPath");
11
23
  /**
12
24
  * Base directory for all Nodetool user data.
13
25
  *
@@ -18,15 +30,81 @@ import { homedir } from "node:os";
18
30
  * - macOS/Linux: $XDG_DATA_HOME/nodetool (fallback: ~/.local/share/nodetool)
19
31
  */
20
32
  export function getNodetoolDataDir() {
33
+ if (!IS_NODE)
34
+ return notOnNode("getNodetoolDataDir");
21
35
  if (process.platform === "win32") {
22
36
  return join(process.env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "nodetool");
23
37
  }
24
38
  // macOS and Linux: use XDG standard to match Python side
25
39
  return join(process.env["XDG_DATA_HOME"] ?? join(homedir(), ".local", "share"), "nodetool");
26
40
  }
27
- /** Default path for the main SQLite database. Override with DB_PATH. */
41
+ function stripUrlSuffix(value) {
42
+ return value.split(/[?#]/, 1)[0];
43
+ }
44
+ function normalizeWindowsDrivePath(value) {
45
+ if (process.platform === "win32" && /^\/[A-Za-z]:[\\/]/.test(value)) {
46
+ return value.slice(1);
47
+ }
48
+ return value;
49
+ }
50
+ function assertNoDatabaseOverrideConflict() {
51
+ if (process.env["DB_PATH"]?.trim() && process.env["DATABASE_URL"]?.trim()) {
52
+ throw new Error("DB_PATH and DATABASE_URL are both set. Use only one database configuration variable.");
53
+ }
54
+ }
55
+ export function getPostgresDatabaseUrl() {
56
+ assertNoDatabaseOverrideConflict();
57
+ const raw = process.env["DATABASE_URL"]?.trim();
58
+ if (!raw) {
59
+ return undefined;
60
+ }
61
+ return /^postgres(?:ql)?:\/\//i.test(raw) ? raw : undefined;
62
+ }
63
+ /**
64
+ * Resolve a SQLite database path from DATABASE_URL.
65
+ *
66
+ * Supports common SQLite forms such as:
67
+ * - /absolute/path/nodetool.sqlite3
68
+ * - file:./nodetool.sqlite3
69
+ * - file:///absolute/path/nodetool.sqlite3
70
+ * - sqlite:./nodetool.sqlite3
71
+ * - sqlite:///absolute/path/nodetool.sqlite3
72
+ */
73
+ function getDatabaseUrlDbPath() {
74
+ const raw = process.env["DATABASE_URL"]?.trim();
75
+ if (!raw) {
76
+ return undefined;
77
+ }
78
+ if (/^file:\/\//i.test(raw)) {
79
+ return fileURLToPath(new URL(raw));
80
+ }
81
+ if (/^file:/i.test(raw)) {
82
+ return stripUrlSuffix(raw.slice("file:".length));
83
+ }
84
+ if (/^sqlite:/i.test(raw)) {
85
+ const value = stripUrlSuffix(raw.slice("sqlite:".length));
86
+ if (value.startsWith("///")) {
87
+ return normalizeWindowsDrivePath(`/${value.slice(3)}`);
88
+ }
89
+ if (value.startsWith("//")) {
90
+ return value.slice(2);
91
+ }
92
+ return value;
93
+ }
94
+ if (!/^[a-z][a-z0-9+.-]*:/i.test(raw)) {
95
+ return raw;
96
+ }
97
+ // Non-SQLite DATABASE_URL values are handled by callers that support other
98
+ // dialects (for example PostgreSQL via getPostgresDatabaseUrl()). For SQLite
99
+ // path resolution, ignore them and fall back to the default path.
100
+ return undefined;
101
+ }
102
+ /** Default path for the main SQLite database. Override with DB_PATH or DATABASE_URL. */
28
103
  export function getDefaultDbPath() {
29
- return (process.env["DB_PATH"] ?? join(getNodetoolDataDir(), "nodetool.sqlite3"));
104
+ assertNoDatabaseOverrideConflict();
105
+ return (process.env["DB_PATH"] ??
106
+ getDatabaseUrlDbPath() ??
107
+ join(getNodetoolDataDir(), "nodetool.sqlite3"));
30
108
  }
31
109
  /** Default path for the vector store database. Override with VECTORSTORE_DB_PATH. */
32
110
  export function getDefaultVectorstoreDbPath() {
@@ -52,63 +130,104 @@ export function getDefaultTransformersJsCacheDir() {
52
130
  join(getNodetoolDataDir(), "transformers-js-cache"));
53
131
  }
54
132
  /**
55
- * Public domain for permanent assets (set via ASSET_DOMAIN env var).
133
+ * Per-user cache root for derived artifacts NodeTool can always rebuild.
56
134
  *
57
- * When set, asset URLs are built as `https://<domain>/<key>` instead of
58
- * `/api/storage/<key>`. Accepts bare hostnames (`assets.nodetool.ai`) or
59
- * full origins (`https://assets.nodetool.ai`). Returns `undefined` when not
60
- * configured.
135
+ * Separate from {@link getNodetoolDataDir} on purpose: everything under here is
136
+ * safe to delete. Override with NODETOOL_CACHE_DIR.
137
+ *
138
+ * - Windows: %LOCALAPPDATA%\nodetool\cache
139
+ * - macOS/Linux: $XDG_CACHE_HOME/nodetool (fallback: ~/.cache/nodetool)
140
+ */
141
+ export function getNodetoolCacheDir() {
142
+ if (!IS_NODE)
143
+ return notOnNode("getNodetoolCacheDir");
144
+ const override = process.env["NODETOOL_CACHE_DIR"]?.trim();
145
+ if (override)
146
+ return override;
147
+ if (process.platform === "win32") {
148
+ return join(process.env["LOCALAPPDATA"] ?? join(homedir(), "AppData", "Local"), "nodetool", "cache");
149
+ }
150
+ return join(process.env["XDG_CACHE_HOME"] ?? join(homedir(), ".cache"), "nodetool");
151
+ }
152
+ /**
153
+ * Return the absolute filesystem path for a storage key.
154
+ * Use this on the server side for direct file reads.
155
+ */
156
+ export function getAssetFilePath(key) {
157
+ return join(getDefaultAssetsPath(), key.replace(/^\/+/, ""));
158
+ }
159
+ /**
160
+ * Build a client-facing URL for a storage key.
161
+ * Returns `/api/storage/<key>` — served by the local HTTP server (file
162
+ * backend) or proxied/redirected to cloud storage by the storage handler.
61
163
  */
62
- export function getAssetDomain() {
63
- const value = process.env["ASSET_DOMAIN"];
64
- return value && value.trim() !== "" ? value.trim() : undefined;
164
+ export function buildAssetUrl(key) {
165
+ // Encode each path segment so reserved chars (`#`, `?`, space, `%`) survive
166
+ // the round-trip through the decoding route (storage-api.ts decodeURIComponent
167
+ // and FileStorageAdapter.keyFromUri). `/` separators are preserved.
168
+ const encoded = key
169
+ .replace(/^\/+/, "")
170
+ .split("/")
171
+ .map(encodeURIComponent)
172
+ .join("/");
173
+ return `/api/storage/${encoded}`;
65
174
  }
66
175
  /**
67
- * Public domain for temporary assets (set via TEMP_DOMAIN env var).
176
+ * Root under which NodeTool keeps the workspace folders it manages itself.
68
177
  *
69
- * Applied to keys with the `temp/` prefix. Accepts bare hostnames or full
70
- * origins. Returns `undefined` when not configured, in which case temp URLs
71
- * fall back to `ASSET_DOMAIN` (if set) or the `/api/storage/` path.
178
+ * A managed workspace is the one every user gets without picking a folder, so
179
+ * a chat turn always has somewhere bounded to read and write. It lives under
180
+ * the data dir rather than the cache dir: an agent's outputs are user data, not
181
+ * a derived artifact that is safe to delete. Override with
182
+ * NODETOOL_WORKSPACES_DIR — a server deployment points it at a mounted volume.
72
183
  */
73
- export function getTempDomain() {
74
- const value = process.env["TEMP_DOMAIN"];
75
- return value && value.trim() !== "" ? value.trim() : undefined;
184
+ export function getManagedWorkspacesDir() {
185
+ if (!IS_NODE)
186
+ return notOnNode("getManagedWorkspacesDir");
187
+ const override = process.env["NODETOOL_WORKSPACES_DIR"]?.trim();
188
+ if (override)
189
+ return override;
190
+ return join(getNodetoolDataDir(), "workspaces");
76
191
  }
77
192
  /**
78
- * Return the absolute filesystem path for a storage key.
193
+ * Storage key prefix of a user's workspace on a deployment that keeps
194
+ * workspaces in object storage rather than on a disk.
79
195
  *
80
- * Use this on the server side whenever you need to read an asset from disk.
81
- * Never pass the result to a browser client — use `buildAssetUrl` for that.
196
+ * The same sanitizing as {@link getManagedWorkspaceDir}: the user id is one
197
+ * key segment, and a `/` or `..` inside it would otherwise reach another
198
+ * user's prefix.
82
199
  */
83
- export function getAssetFilePath(key) {
84
- return join(getDefaultAssetsPath(), key.replace(/^\/+/, ""));
200
+ export function managedWorkspaceKey(userId) {
201
+ return `workspaces/${sanitizeUserSegment(userId)}`;
85
202
  }
86
203
  /**
87
- * Build a **client-facing** URL for an asset identified by its storage key.
204
+ * Absolute path of a user's managed default workspace.
88
205
  *
89
- * The key is the storage-relative path (e.g. `abc.png` or `temp/uuid.png`).
90
- * When ASSET_DOMAIN / TEMP_DOMAIN are configured, returns an absolute CDN URL.
91
- * Otherwise returns `/api/storage/<key>` — a dev-mode path that the browser
92
- * can reach via the Vite proxy or the local HTTP server.
206
+ * The user id is a path segment, so anything that is not a safe filename
207
+ * character is replaced — a user id from an external identity provider can
208
+ * carry `/`, `:` or `..`, and each of those would escape the workspaces root.
209
+ */
210
+ export function getManagedWorkspaceDir(userId) {
211
+ return join(getManagedWorkspacesDir(), sanitizeUserSegment(userId));
212
+ }
213
+ function sanitizeUserSegment(userId) {
214
+ const safe = userId.replace(/[^A-Za-z0-9._-]/g, "_").replace(/^\.+/, "_");
215
+ return safe || "default";
216
+ }
217
+ /**
218
+ * Whether this deployment backs workspaces with a local folder or with the
219
+ * object storage it already uses for assets.
93
220
  *
94
- * Do NOT use this for server-side file reads. Use `getAssetFilePath` instead.
221
+ * Production has no durable disk worth writing a user's files to — a Fly
222
+ * machine is replaced and the folder goes with it — so a cloud workspace is a
223
+ * key prefix in the asset bucket. `NODETOOL_WORKSPACE_STORAGE` overrides the
224
+ * default either way, which is how a self-hosted server with a mounted volume
225
+ * keeps local workspaces, and how a local install can be pointed at S3.
95
226
  */
96
- export function buildAssetUrl(key) {
97
- const normalized = key.replace(/^\/+/, "");
98
- const isTemp = normalized.startsWith("temp/");
99
- const domain = isTemp
100
- ? (getTempDomain() ?? getAssetDomain())
101
- : getAssetDomain();
102
- if (!domain) {
103
- return `/api/storage/${normalized}`;
104
- }
105
- const origin = /^https?:\/\//i.test(domain) ? domain : `https://${domain}`;
106
- const trimmedOrigin = origin.replace(/\/+$/, "");
107
- // When serving from a dedicated temp domain, the `temp/` prefix is
108
- // redundant — the domain itself identifies the bucket.
109
- const path = isTemp && getTempDomain() !== undefined
110
- ? normalized.slice("temp/".length)
111
- : normalized;
112
- return `${trimmedOrigin}/${path}`;
227
+ export function workspaceStorageKind() {
228
+ const override = process.env["NODETOOL_WORKSPACE_STORAGE"]?.trim();
229
+ if (override === "local" || override === "cloud")
230
+ return override;
231
+ return process.env["NODETOOL_ENV"] === "production" ? "cloud" : "local";
113
232
  }
114
233
  //# sourceMappingURL=paths.js.map
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CACT,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,EAC/D,UAAU,CACX,CAAC;IACJ,CAAC;IACD,yDAAyD;IACzD,OAAO,IAAI,CACT,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,EAClE,UAAU,CACX,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,EAAE,kBAAkB,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,2BAA2B;IACzC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAClC,IAAI,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,CAAC,CAC7C,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,oBAAoB;IAClC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3B,IAAI,CAAC,kBAAkB,EAAE,EAAE,QAAQ,CAAC,CACrC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gCAAgC;IAC9C,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;QACxC,IAAI,CAAC,kBAAkB,EAAE,EAAE,uBAAuB,CAAC,CACpD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACzC,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,IAAI,CAAC,oBAAoB,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM;QACnB,CAAC,CAAC,CAAC,aAAa,EAAE,IAAI,cAAc,EAAE,CAAC;QACvC,CAAC,CAAC,cAAc,EAAE,CAAC;IAErB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,gBAAgB,UAAU,EAAE,CAAC;IACtC,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC;IAC3E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjD,mEAAmE;IACnE,uDAAuD;IACvD,MAAM,IAAI,GACR,MAAM,IAAI,aAAa,EAAE,KAAK,SAAS;QACrC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAClC,CAAC,CAAC,UAAU,CAAC;IACjB,OAAO,GAAG,aAAa,IAAI,IAAI,EAAE,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Whether the storage retention sweep should run without being asked. */
2
+ export declare function isAutomaticStorageCleanupEnabled(env?: Record<string, string | undefined>): boolean;
3
+ //# sourceMappingURL=retention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../src/retention.ts"],"names":[],"mappings":"AAcA,0EAA0E;AAC1E,wBAAgB,gCAAgC,CAC9C,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAoB,GACzD,OAAO,CAGT"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Whether this server expires personal data on its own schedule.
3
+ *
4
+ * A local install keeps its history until the person using the machine asks for
5
+ * a cleanup — that machine is theirs, and silently deleting their run history
6
+ * would surprise them. A hosted deployment is the opposite case: it holds other
7
+ * people's data under a published retention promise, so the sweep has to run
8
+ * without anyone pressing a button.
9
+ *
10
+ * Set `NODETOOL_STORAGE_AUTO_CLEANUP=1` (or `true`) to run the retention sweep
11
+ * automatically. Unset, or `0`/`false`, keeps the manual behaviour.
12
+ */
13
+ import { safeProcessEnv } from "./node-import.js";
14
+ /** Whether the storage retention sweep should run without being asked. */
15
+ export function isAutomaticStorageCleanupEnabled(env = safeProcessEnv()) {
16
+ const value = env["NODETOOL_STORAGE_AUTO_CLEANUP"]?.trim().toLowerCase();
17
+ return value === "1" || value === "true";
18
+ }
19
+ //# sourceMappingURL=retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention.js","sourceRoot":"","sources":["../src/retention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,0EAA0E;AAC1E,MAAM,UAAU,gCAAgC,CAC9C,GAAG,GAAuC,cAAc,EAAE;IAE1D,MAAM,KAAK,GAAG,GAAG,CAAC,+BAA+B,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzE,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,MAAM,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The setting catalog — every configuration knob NodeTool ships, with its
3
+ * group, description, allowed values, and whether it holds a credential.
4
+ *
5
+ * It lives in `config` rather than in the server because two packages need the
6
+ * same table and neither can import the other: the tRPC settings router reads
7
+ * it to answer `settings.list`, and the `settings` capability module reads it
8
+ * to decide what sandboxed code may see and change. A capability that had to
9
+ * guess whether `OPENAI_API_KEY` is a secret would guess from the name, which
10
+ * is how a credential ends up in a model's context.
11
+ *
12
+ * Definitions only. Reading a value needs the database (`Setting`), which is
13
+ * above this package — `getSetting()` in the server's `settings-registry.ts`
14
+ * does that half.
15
+ */
16
+ export interface SettingCatalogEntry {
17
+ packageName: string;
18
+ envVar: string;
19
+ group: string;
20
+ description: string;
21
+ enum?: string[];
22
+ isSecret?: boolean;
23
+ }
24
+ /** Every registered definition, in registration order. */
25
+ export declare function settingCatalog(): SettingCatalogEntry[];
26
+ /** One definition by env var, or undefined when nothing registered it. */
27
+ export declare function settingDefinition(envVar: string): SettingCatalogEntry | undefined;
28
+ //# sourceMappingURL=setting-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setting-catalog.d.ts","sourceRoot":"","sources":["../src/setting-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD,0DAA0D;AAC1D,wBAAgB,cAAc,IAAI,mBAAmB,EAAE,CAEtD;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,GACb,mBAAmB,GAAG,SAAS,CAEjC"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * The setting catalog — every configuration knob NodeTool ships, with its
3
+ * group, description, allowed values, and whether it holds a credential.
4
+ *
5
+ * It lives in `config` rather than in the server because two packages need the
6
+ * same table and neither can import the other: the tRPC settings router reads
7
+ * it to answer `settings.list`, and the `settings` capability module reads it
8
+ * to decide what sandboxed code may see and change. A capability that had to
9
+ * guess whether `OPENAI_API_KEY` is a secret would guess from the name, which
10
+ * is how a credential ends up in a model's context.
11
+ *
12
+ * Definitions only. Reading a value needs the database (`Setting`), which is
13
+ * above this package — `getSetting()` in the server's `settings-registry.ts`
14
+ * does that half.
15
+ */
16
+ const catalog = [];
17
+ /** Register a definition. First registration of an env var wins. */
18
+ function registerSettingDefinition(def) {
19
+ if (!catalog.some((s) => s.envVar === def.envVar)) {
20
+ catalog.push(def);
21
+ }
22
+ }
23
+ /** Every registered definition, in registration order. */
24
+ export function settingCatalog() {
25
+ return catalog;
26
+ }
27
+ /** One definition by env var, or undefined when nothing registered it. */
28
+ export function settingDefinition(envVar) {
29
+ return catalog.find((s) => s.envVar === envVar);
30
+ }
31
+ // ── Default settings (ported from nodetool/config/settings.py) ────
32
+ function s(envVar, group, description, enumValues) {
33
+ registerSettingDefinition({
34
+ packageName: "nodetool",
35
+ envVar,
36
+ group,
37
+ description,
38
+ enum: enumValues
39
+ });
40
+ }
41
+ function sec(envVar, group, description) {
42
+ registerSettingDefinition({
43
+ packageName: "nodetool",
44
+ envVar,
45
+ group,
46
+ description,
47
+ isSecret: true
48
+ });
49
+ }
50
+ // Folders / paths
51
+ s("FONT_PATH", "Folders", "Location of font folder used by image processing nodes like RenderText. If not specified, the system will use default fonts.");
52
+ s("BLENDER_PATH", "Folders", "Path to the Blender executable used by the nodetool.blender nodes. If not specified, the nodes look for blender on PATH and in the well-known install locations.");
53
+ s("VECTORSTORE_DB_PATH", "Folders", "Location of the sqlite-vec vector database file. Used to store and retrieve embeddings for semantic search and RAG applications.");
54
+ s("USERS_FILE", "Folders", "Path to the users.json registry of API users and hashed bearer tokens. Defaults to ~/.config/nodetool/users.json, or %APPDATA%\\nodetool\\users.json on Windows.");
55
+ s("TRANSFORMERS_JS_CACHE_DIR", "TransformersJs", "Cache directory for Transformers.js (@huggingface/transformers) model downloads. Defaults to <data-dir>/transformers-js-cache. This is separate from the Python HuggingFace Hub cache because the on-disk layout differs.");
56
+ s("NODETOOL_EXTERNAL_ASSET_THRESHOLD_BYTES", "Folders", "Desktop app only: files imported at or above this size, in bytes, stay where they are and the asset references them in place instead of copying them into the asset folder (default: 1073741824, 1 GiB).");
57
+ s("NODETOOL_VIDEO_PROXY_MIN_SIZE_PX", "Folders", "Desktop app only: an imported video whose longer side is at least this many pixels gets a smaller all-intra preview proxy, made in the background, so timeline scrubbing seeks fast. Export always reads the original. 0 makes a proxy for every video, a negative value turns background proxies off (default: 1920).");
58
+ // Autosave
59
+ s("AUTOSAVE_ENABLED", "Autosave", "Enable automatic saving of workflow versions (default: true)", ["true", "false"]);
60
+ s("AUTOSAVE_INTERVAL_MINUTES", "Autosave", "Interval in minutes between automatic workflow autosaves (default: 5, range: 1-60)");
61
+ s("AUTOSAVE_MIN_INTERVAL_SECONDS", "Autosave", "Minimum interval in seconds between autosaves to prevent duplicates (default: 30)");
62
+ s("AUTOSAVE_MAX_VERSIONS_PER_WORKFLOW", "Autosave", "Maximum number of autosave versions to keep per workflow (default: 20)");
63
+ s("AUTOSAVE_KEEP_DAYS", "Autosave", "Number of days to keep autosave versions before cleanup (default: 7)");
64
+ // Execution
65
+ s("MAX_CONCURRENT_JOBS", "Execution", "Maximum number of workflow runs a single client can execute at once (default: 4). Additional runs are queued and start automatically as running ones finish, preventing provider/API overload.");
66
+ s("MAX_CONCURRENT_RUNS_PER_WORKFLOW", "Execution", "Maximum number of concurrent runs of the same workflow before additional runs queue (default: 4). Only applies to runs that opt into concurrency (e.g. timeline/sketch generation); canvas runs always stay sequential per workflow. Also bounded by MAX_CONCURRENT_JOBS.");
67
+ // Agent budgets — the bounds one agent run shares across every loop it starts
68
+ // (a chat turn, its sub-agents, an AgentNode it spawns). See A1 in
69
+ // docs/plans/agent-system-improvements.md.
70
+ s("NODETOOL_AGENT_TURN_COST_CAP_USD", "Agents", "Ceiling on provider spend for one agent run, in US dollars (default: 5.00). The whole run shares it: sub-agents, background subtasks, and agent nodes reserve against the same cap rather than opening their own. A turn whose worst case would cross it is refused before the call, and the run stops with a message naming the cap. Set it to 0 for no cap at all, which is what a local-only install wants — clearing the value restores the default instead, because an empty setting is indistinguishable from an unset one.");
71
+ s("NODETOOL_AGENT_TURN_DEADLINE_MS", "Agents", "Wall-clock bound on one agent run, in milliseconds (default: 1800000, i.e. 30 minutes). Checked before every model turn and every tool call, so a run that stalls on a slow provider ends instead of hanging.");
72
+ s("NODETOOL_AGENT_MAX_CONCURRENCY", "Agents", "Maximum provider conversations an agent run may have open at once (default: 8). Shared by the whole run, so a fan-out of sub-agents inside a fan-out of steps cannot multiply into hundreds of simultaneous calls.");
73
+ s("NODETOOL_AGENT_MAX_TURNS", "Agents", "Maximum model turns an agent run may make in total (default: 200), counted across every loop it starts. This is the bound that still holds for a local model with no price, where the dollar cap cannot apply.");
74
+ s("NODETOOL_AGENT_UNPRICED_TOKEN_CEILING", "Agents", "Prompt-token ceiling for a turn on a model the price catalog does not cover (default: 400000). An unpriced model has no worst-case cost to reserve, so admitting it freely would make the dollar cap advisory; this bounds it by size instead. Such turns are counted as unpriced rather than as free spend.");
75
+ // Chat compaction — replacing the earlier turns of a long thread with one
76
+ // summary the provider is sent instead. See A4 in
77
+ // docs/plans/agent-system-improvements.md.
78
+ s("NODETOOL_CHAT_COMPACTION_TOKENS", "Agents", "Prompt size, in tokens, at which a chat turn summarizes the earlier part of its thread before calling the model. Unset, the threshold is 90% of the model's input window, read from the provider's Models API (Anthropic `max_input_tokens`), then models.dev by provider and model, then a 128000-token fallback. The prompt size is the larger of the provider-reported size of the thread's last call and a local estimate of the messages. A provider that holds the conversation itself (a resumed session, the Claude Agent SDK) is not measured this way; it compacts when it reports that the transcript no longer fits.");
79
+ s("NODETOOL_CHAT_COMPACTION_KEEP_TURNS", "Agents", "How many of the most recent user turns a compaction leaves verbatim (default: 4). Everything before them becomes the summary. The cut always lands on a user message, so a tool call is never separated from its result.");
80
+ s("NODETOOL_COMPACTION_MODEL", "Agents", "Model that writes the compaction summary, as `provider/model` or a bare model id on the turn's own provider. Unset, the turn summarizes with the model it is already running. A summarizer that fails leaves the thread uncompacted and the turn runs against the full history.");
81
+ // Provider endpoints
82
+ s("VLLM_BASE_URL", "vLLM", "Base URL for the vLLM OpenAI-compatible server (e.g., http://localhost:7777)");
83
+ s("OLLAMA_CONTEXT_LENGTH", "Ollama", "Context window size (in tokens) for Ollama models. If not set, the provider will query the model for its default context length.");
84
+ s("LLAMA_CPP_URL", "LlamaCpp", "Base URL for the llama.cpp server (e.g., http://127.0.0.1:8080).");
85
+ s("LLAMA_CPP_CONTEXT_LENGTH", "LlamaCpp", "Context window size (in tokens) for llama.cpp models. Defaults to 128000.");
86
+ s("NODE_LLAMA_CPP_MODELS_DIR", "NodeLlamaCpp", "Directory containing local GGUF model files for in-process llama.cpp inference. Defaults to the platform llama.cpp cache directory.");
87
+ s("NODE_LLAMA_CPP_GPU_BACKEND", "NodeLlamaCpp", "GPU backend for in-process llama.cpp inference. 'auto' lets node-llama-cpp detect the best backend.", ["auto", "metal", "cuda", "vulkan", "cpu"]);
88
+ s("LMSTUDIO_API_URL", "LMStudio", "Base URL for the LM Studio OpenAI-compatible server (e.g., http://localhost:1234)");
89
+ s("WHISPER_CPP_MODELS_DIR", "WhisperCpp", "Additional directory containing local ggml whisper.cpp and VAD model files. The Hugging Face hub cache is always scanned.");
90
+ s("WHISPER_CPP_GPU_BACKEND", "WhisperCpp", "Backend for in-process whisper.cpp inference. 'auto' uses the default build (Metal on macOS). Restart the backend after changing this setting.", ["auto", "metal", "cuda", "vulkan", "cpu"]);
91
+ s("WHISPER_CPP_SERVER_URL", "WhisperCppServer", "Base URL for a user-run whisper.cpp server (e.g., http://127.0.0.1:8080).");
92
+ // NodeSupabase
93
+ s("NODE_SUPABASE_URL", "NodeSupabase", "Supabase project URL used by user-provided nodes (separate from core SUPABASE_URL)");
94
+ s("NODE_SUPABASE_SCHEMA", "NodeSupabase", "Optional schema for user/node Supabase tables (defaults to public when unset)");
95
+ s("NODE_SUPABASE_TABLE_PREFIX", "NodeSupabase", "Optional prefix applied to user/node Supabase tables to avoid clashes with core tables");
96
+ // Observability
97
+ s("TRACELOOP_ENABLED", "Observability", "Enable Traceloop OpenLLMetry tracing", ["true", "false"]);
98
+ s("TRACELOOP_APP_NAME", "Observability", "Override the OpenLLMetry application name (defaults to service name)");
99
+ s("TRACELOOP_BASE_URL", "Observability", "Override the Traceloop OTLP base URL");
100
+ s("TRACELOOP_DISABLE_BATCH", "Observability", "Disable Traceloop batch span processing for local development", ["true", "false"]);
101
+ // Search
102
+ s("SERP_PROVIDER", "Search", "Select which search provider to use for web search operations.", ["serpapi", "dataforseo", "brave", "apify", "openai", "gemini"]);
103
+ s("ZAI_USE_CODING_PLAN", "ZAI", "Use Z.AI coding plan endpoint instead of normal endpoint", ["true", "false"]);
104
+ // Secrets (value shown as "****" when env var is set, null otherwise)
105
+ sec("OPENAI_API_KEY", "OpenAI", "OpenAI API key for accessing GPT models, GPT-Image, and other OpenAI services. Get yours at https://platform.openai.com/api-keys");
106
+ sec("OPENROUTER_API_KEY", "OpenRouter", "OpenRouter API key for accessing multiple AI models through a unified API. Get yours at https://openrouter.ai/settings/keys");
107
+ sec("REQUESTY_API_KEY", "Requesty", "Requesty API key for accessing multiple AI models through one OpenAI-compatible router. Get yours at https://app.requesty.ai/api-keys");
108
+ sec("ANTHROPIC_API_KEY", "Anthropic", "Anthropic API key for accessing Claude models and other Anthropic services. Get yours at https://console.anthropic.com/settings/keys");
109
+ sec("DASHSCOPE_API_KEY", "Alibaba Cloud", "Alibaba Cloud Model Studio (DashScope) API key for accessing Qwen models through the OpenAI-compatible endpoint. Get yours at https://modelstudio.console.alibabacloud.com/");
110
+ s("DASHSCOPE_BASE_URL", "Alibaba Cloud", "Base URL for Alibaba Cloud Model Studio's OpenAI-compatible endpoint. Model Studio keys are region-scoped; set this to your region's endpoint (default: https://dashscope-intl.aliyuncs.com/compatible-mode/v1, the international/Singapore region)");
111
+ sec("CEREBRAS_API_KEY", "Cerebras", "Cerebras API key for accessing fast LLM inference on Cerebras hardware. Get yours at https://cloud.cerebras.ai/");
112
+ sec("GMI_API_KEY", "GMI Cloud", "GMI Cloud API key for accessing open-weight LLMs through GMI's OpenAI-compatible inference API. Get yours at https://console.gmicloud.ai/");
113
+ sec("EVOLINK_API_KEY", "Evolink", "Evolink API key for reaching GPT, Claude, Gemini, DeepSeek and other models through one gateway, plus Evolink's image and video generation. Get yours at https://docs.evolink.ai");
114
+ sec("META_API_KEY", "Meta AI", "Meta AI API key for accessing the Muse Spark models through Meta's OpenAI-compatible API. Get yours at https://dev.meta.ai/");
115
+ sec("TOGETHER_API_KEY", "Together", "Together AI API key for accessing open-source LLMs through Together's inference API. Get yours at https://api.together.ai/settings/api-keys");
116
+ sec("DEEPSEEK_API_KEY", "DeepSeek", "DeepSeek API key for accessing DeepSeek-V3 chat and DeepSeek-R1 reasoning models. Get yours at https://platform.deepseek.com/api-keys");
117
+ sec("XAI_API_KEY", "xAI", "xAI API key for accessing Grok models via xAI's OpenAI-compatible API. Get yours at https://console.x.ai/");
118
+ sec("GROQ_API_KEY", "Groq", "Groq API key for accessing ultra-fast LLM inference on Groq's LPU hardware. Get yours at https://console.groq.com/keys");
119
+ sec("ZHIPU_API_KEY", "ZAI", "Z.AI API key for accessing GLM models through Z.AI's OpenAI-compatible API. Get yours at https://open.bigmodel.cn/usercenter/apikeys");
120
+ sec("MISTRAL_API_KEY", "Mistral", "Mistral API key for accessing Mistral AI models. Get yours at https://console.mistral.ai/api-keys");
121
+ sec("KIMI_API_KEY", "Kimi", "Kimi (Moonshot) API key for accessing Kimi models via the OpenAI-compatible endpoint. Get yours at https://platform.moonshot.ai/console/api-keys");
122
+ sec("MINIMAX_API_KEY", "MiniMax", "MiniMax API key for accessing MiniMax AI models. Get yours at https://platform.minimax.chat/user-center/basic-information/interface-key");
123
+ sec("AKI_API_KEY", "AKI", "AKI.IO API key for accessing the AKI AI Model Hub. Get yours at https://aki.io/");
124
+ sec("GEMINI_API_KEY", "Gemini", "Gemini API key for accessing Google's Gemini AI models. Get yours at https://aistudio.google.com/app/apikey");
125
+ sec("HF_TOKEN", "HF", "Token for HuggingFace Inference Providers. Get yours at https://huggingface.co/settings/tokens");
126
+ sec("COHERE_API_KEY", "Cohere", "Cohere API key for Embed v4 text embeddings and reranking. Get yours at https://dashboard.cohere.com/api-keys");
127
+ sec("JINA_API_KEY", "Jina", "Jina AI API key for Jina embedding and reranker models. Get yours at https://jina.ai/api-dashboard/");
128
+ sec("VOYAGE_API_KEY", "Voyage", "Voyage AI API key for text and multimodal embeddings. Get yours at https://dashboard.voyageai.com/organization/api-keys");
129
+ sec("LLAMA_API_KEY", "LlamaCpp", "API key for authenticating with llama-server");
130
+ sec("REPLICATE_API_TOKEN", "Replicate", "Replicate API Token for running models on Replicate's cloud infrastructure. Get yours at https://replicate.com/account/api-tokens");
131
+ sec("GOOGLE_MAIL_USER", "Google", "Google mail user for email integration features");
132
+ sec("GOOGLE_APP_PASSWORD", "Google", "Google app password for secure authentication with Google services. Manage at https://myaccount.google.com/apppasswords");
133
+ sec("ELEVENLABS_API_KEY", "ElevenLabs", "ElevenLabs API key for high-quality text-to-speech services. Get yours at https://elevenlabs.io/app/settings/api-keys");
134
+ sec("FAL_API_KEY", "FAL", "FAL API key for accessing FAL.ai's serverless AI infrastructure. Get yours at https://fal.ai/dashboard/keys");
135
+ sec("SERPAPI_API_KEY", "Search", "SerpAPI API key. Powers web search and the SerpAPI engine capability — Google and its verticals (news, images, scholar, maps, jobs, flights, trends), Bing, DuckDuckGo, YouTube, Amazon, eBay, Walmart, Yelp, and the rest of its catalog. Get yours at https://serpapi.com/manage-api-key");
136
+ sec("APIFY_API_TOKEN", "Search", "Apify API token. Powers the Apify actor capability (crawling, browser automation, structured extraction, maps, social, media, screenshots, transcripts) and Apify-backed web search. Get yours at https://console.apify.com/account/integrations");
137
+ // The name this install shipped first. Still read as a fallback everywhere the
138
+ // token is resolved, so an existing configuration keeps working; new setups
139
+ // should use APIFY_API_TOKEN, which is what Apify's own docs call it.
140
+ sec("APIFY_API_KEY", "Search", "Deprecated alias for APIFY_API_TOKEN. Existing installs keep working; set APIFY_API_TOKEN for new ones.");
141
+ sec("BRAVE_API_KEY", "Search", "Brave Search API key for web search. Get yours at https://api-dashboard.search.brave.com/");
142
+ sec("BROWSER_URL", "Browser", "Browser URL for accessing a browser instance");
143
+ sec("RUNPOD_API_KEY", "RunPod", "RunPod API key for accessing serverless endpoints. Get yours at https://www.runpod.io/console/user/settings");
144
+ sec("VAST_API_KEY", "Vast.ai", "Vast.ai API key for renting marketplace GPUs to run NodeTool workers. Get yours at https://cloud.vast.ai/manage-keys/");
145
+ sec("VERDA_CLIENT_ID", "Verda", "Verda cloud API client id for renting GPU instances to run NodeTool workers. Create credentials at https://cloud.verda.com/ (distinct from the inference key).");
146
+ sec("VERDA_CLIENT_SECRET", "Verda", "Verda cloud API client secret, paired with VERDA_CLIENT_ID. Credentials are tied to the team member who created them and are deleted when that member is removed.");
147
+ sec("NODE_SUPABASE_KEY", "NodeSupabase", "Supabase service key for user-provided nodes");
148
+ sec("DATA_FOR_SEO_LOGIN", "Search", "DataForSEO login for web search. Sign up at https://app.dataforseo.com/register");
149
+ sec("DATA_FOR_SEO_PASSWORD", "Search", "DataForSEO password for web search. Sign up at https://app.dataforseo.com/register");
150
+ sec("TRACELOOP_API_KEY", "Observability", "Traceloop API key for OpenLLMetry trace export. Get yours at https://app.traceloop.com/");
151
+ sec("KIE_API_KEY", "KIE", "KIE API key for accessing kie.ai. Get yours at https://kie.ai/");
152
+ s("KIE_TIMEOUT_SECONDS", "KIE", "Global timeout in seconds for Kie.ai API calls (0 = use default per-model timeout)");
153
+ sec("COMFY_API_KEY", "Comfy Cloud", "Comfy Cloud API key for running ComfyUI workflows on cloud.comfy.org. Get yours at https://platform.comfy.org");
154
+ sec("TOPAZ_API_KEY", "Topaz", "Topaz Labs API key for image and video enhancement. Get yours at https://developer.topazlabs.com/");
155
+ sec("REVE_API_KEY", "Reve", "Reve API key for image creation, editing, and remix. Get yours at https://api.reve.com/");
156
+ sec("ATLASCLOUD_API_KEY", "AtlasCloud", "AtlasCloud.ai API key for chat models (DeepSeek, Qwen, GPT, Claude, Gemini) plus hosted image (GPT Image, Nano Banana, Seedream) and video (Seedance, Veo, Kling, Wan) generation. Get yours at https://www.atlascloud.ai/");
157
+ sec("HIGGSFIELD_API_KEY_ID", "Higgsfield", "Higgsfield API key ID. Get credentials at https://platform.higgsfield.ai/");
158
+ sec("HIGGSFIELD_API_KEY_SECRET", "Higgsfield", "Higgsfield API key secret. Get credentials at https://platform.higgsfield.ai/");
159
+ sec("USEAPI_API_TOKEN", "useapi.net", "API token for Google Flow and Dreamina through useapi.net. Get yours at https://useapi.net/");
160
+ s("USEAPI_GOOGLE_FLOW_EMAIL", "useapi.net", "Google Flow account email for reference image uploads");
161
+ s("USEAPI_DREAMINA_ACCOUNT", "useapi.net", "Dreamina account ID (region:email) for reference image uploads");
162
+ sec("MESHY_API_KEY", "Meshy", "Meshy AI API key for 3D model generation. Get yours at https://app.meshy.ai/settings/api-keys");
163
+ sec("RODIN_API_KEY", "Rodin", "Rodin AI API key for 3D model generation. Get yours at https://hyperhuman.deemos.com/");
164
+ sec("GITHUB_CLIENT_ID", "GitHub", "GitHub OAuth App Client ID for OAuth PKCE authentication flow. Manage at https://github.com/settings/developers");
165
+ sec("GITHUB_CLIENT_SECRET", "GitHub", "GitHub OAuth App Client Secret for OAuth PKCE authentication flow. Manage at https://github.com/settings/developers");
166
+ sec("SERVER_AUTH_TOKEN", "Deployment", "Bearer auth token for securing NodeTool server endpoints in deployment. If unset, bearer auth is disabled.");
167
+ //# sourceMappingURL=setting-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setting-catalog.js","sourceRoot":"","sources":["../src/setting-catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Storage backend selection. Mirrors `StorageConfig` in `@nodetool-ai/storage`
3
+ * but kept structurally compatible to avoid a config → storage dependency.
4
+ */
5
+ export type StorageConfig = {
6
+ kind: "file";
7
+ rootDir: string;
8
+ } | {
9
+ kind: "s3";
10
+ bucket: string;
11
+ region?: string;
12
+ endpoint?: string;
13
+ } | {
14
+ kind: "supabase";
15
+ url: string;
16
+ apiKey: string;
17
+ bucket: string;
18
+ };
19
+ /** 7 days — S3/Supabase maximum. Long enough that no browser or CDN cache
20
+ * will hold a redirect past expiry. */
21
+ export declare const SIGNED_URL_TTL = 604800;
22
+ /**
23
+ * Asset storage config — permanent user files.
24
+ *
25
+ * Env vars:
26
+ * NODETOOL_STORAGE_BACKEND file | s3 | supabase (default: file)
27
+ * ASSET_BUCKET bucket name (s3 / supabase)
28
+ * SUPABASE_URL Supabase project URL
29
+ * SUPABASE_KEY Supabase API key
30
+ * S3_REGION AWS region (s3)
31
+ * S3_ENDPOINT custom S3 endpoint (s3, optional)
32
+ */
33
+ export declare function loadAssetStorageConfig(): StorageConfig;
34
+ /**
35
+ * Temp storage config — ephemeral workflow outputs.
36
+ *
37
+ * Same backend as assets; uses a separate bucket so temp files can have
38
+ * different retention / access policies.
39
+ *
40
+ * Env vars:
41
+ * TEMP_BUCKET bucket name (s3 / supabase)
42
+ * (all other vars shared with loadAssetStorageConfig)
43
+ */
44
+ export declare function loadTempStorageConfig(): StorageConfig;
45
+ //# sourceMappingURL=storage-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-config.d.ts","sourceRoot":"","sources":["../src/storage-config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAqCtE;wCACwC;AACxC,eAAO,MAAM,cAAc,SAAS,CAAC;AAKrC;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,aAAa,CAErD"}