openmates 0.11.0-alpha.31 → 0.11.0-alpha.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/{chunk-3TZYVNWL.js → chunk-NI7XPZBV.js} +130 -83
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,9 +39,10 @@ The CLI derives the web app URL from the API URL so pair-auth lands on the match
|
|
|
39
39
|
| --- | --- |
|
|
40
40
|
| Production | _(none)_ |
|
|
41
41
|
| Dev server | `OPENMATES_API_URL=https://api.dev.openmates.org` |
|
|
42
|
-
|
|
|
42
|
+
| Installed self-hosted server | _(none after `openmates server install`)_ |
|
|
43
|
+
| Remote self-hosted server | `OPENMATES_API_URL=https://api.example.com` |
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
After `openmates server install`, fresh CLI commands default to that self-hosted server (`http://localhost:8000`) unless you already have a saved login session, set `OPENMATES_API_URL`, or pass `--api-url <url>`. App-skill execution can use your logged-in session, `--api-key <key>`, or `OPENMATES_API_KEY`.
|
|
45
46
|
|
|
46
47
|
## Safety Limits
|
|
47
48
|
|
|
@@ -874,6 +874,67 @@ function isSyncCacheFresh(maxAgeMs = 3e5) {
|
|
|
874
874
|
return Date.now() - cache.syncedAt < maxAgeMs;
|
|
875
875
|
}
|
|
876
876
|
|
|
877
|
+
// src/serverConfig.ts
|
|
878
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
879
|
+
import { homedir as homedir3 } from "os";
|
|
880
|
+
import { join as join2, resolve } from "path";
|
|
881
|
+
var STATE_DIR = join2(homedir3(), ".openmates");
|
|
882
|
+
var CONFIG_FILE = "server.json";
|
|
883
|
+
function ensureStateDir2() {
|
|
884
|
+
if (!existsSync3(STATE_DIR)) {
|
|
885
|
+
mkdirSync2(STATE_DIR, { recursive: true, mode: 448 });
|
|
886
|
+
}
|
|
887
|
+
return STATE_DIR;
|
|
888
|
+
}
|
|
889
|
+
function saveServerConfig(config) {
|
|
890
|
+
const dir = ensureStateDir2();
|
|
891
|
+
const filePath = join2(dir, CONFIG_FILE);
|
|
892
|
+
writeFileSync2(filePath, `${JSON.stringify(config, null, 2)}
|
|
893
|
+
`, { mode: 420 });
|
|
894
|
+
}
|
|
895
|
+
function loadServerConfig() {
|
|
896
|
+
const filePath = join2(STATE_DIR, CONFIG_FILE);
|
|
897
|
+
if (!existsSync3(filePath)) return null;
|
|
898
|
+
try {
|
|
899
|
+
return JSON.parse(readFileSync3(filePath, "utf-8"));
|
|
900
|
+
} catch {
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
function removeServerConfig() {
|
|
905
|
+
const filePath = join2(STATE_DIR, CONFIG_FILE);
|
|
906
|
+
if (existsSync3(filePath)) {
|
|
907
|
+
rmSync2(filePath);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
var SOURCE_COMPOSE_MARKER = join2("backend", "core", "docker-compose.yml");
|
|
911
|
+
var IMAGE_COMPOSE_MARKER = join2("backend", "core", "docker-compose.selfhost.yml");
|
|
912
|
+
function isOpenMatesDir(dir) {
|
|
913
|
+
return existsSync3(join2(dir, SOURCE_COMPOSE_MARKER)) || existsSync3(join2(dir, IMAGE_COMPOSE_MARKER));
|
|
914
|
+
}
|
|
915
|
+
function resolveServerPath(flags) {
|
|
916
|
+
if (typeof flags.path === "string" && flags.path) {
|
|
917
|
+
const explicit = resolve(flags.path);
|
|
918
|
+
if (!isOpenMatesDir(explicit)) {
|
|
919
|
+
throw new Error(
|
|
920
|
+
`${explicit} does not appear to be an OpenMates installation (missing ${SOURCE_COMPOSE_MARKER} or ${IMAGE_COMPOSE_MARKER}).`
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
return explicit;
|
|
924
|
+
}
|
|
925
|
+
const config = loadServerConfig();
|
|
926
|
+
if (config?.installPath && isOpenMatesDir(config.installPath)) {
|
|
927
|
+
return config.installPath;
|
|
928
|
+
}
|
|
929
|
+
const cwd = process.cwd();
|
|
930
|
+
if (isOpenMatesDir(cwd)) {
|
|
931
|
+
return cwd;
|
|
932
|
+
}
|
|
933
|
+
throw new Error(
|
|
934
|
+
"No OpenMates installation found.\nRun 'openmates server install' to set up a new server, or use --path <dir>."
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
|
|
877
938
|
// src/ws.ts
|
|
878
939
|
import { createRequire } from "module";
|
|
879
940
|
var require2 = createRequire(import.meta.url);
|
|
@@ -1910,9 +1971,14 @@ function deriveWebOrigin(apiUrl) {
|
|
|
1910
1971
|
const url = new URL(apiUrl);
|
|
1911
1972
|
if (url.hostname === "api.dev.openmates.org") {
|
|
1912
1973
|
url.hostname = "app.dev.openmates.org";
|
|
1974
|
+
} else if (url.hostname === "api.openmates.org") {
|
|
1975
|
+
url.hostname = "openmates.org";
|
|
1913
1976
|
} else {
|
|
1914
|
-
url.hostname = url.hostname.replace(/^api\./, "");
|
|
1977
|
+
url.hostname = url.hostname.replace(/^api\./, "app.");
|
|
1915
1978
|
}
|
|
1979
|
+
url.pathname = "";
|
|
1980
|
+
url.search = "";
|
|
1981
|
+
url.hash = "";
|
|
1916
1982
|
url.port = "";
|
|
1917
1983
|
return url.origin;
|
|
1918
1984
|
} catch {
|
|
@@ -2382,24 +2448,50 @@ var MATE_NAMES = {
|
|
|
2382
2448
|
general_knowledge: "George",
|
|
2383
2449
|
onboarding_support: "Suki"
|
|
2384
2450
|
};
|
|
2385
|
-
var
|
|
2451
|
+
var CLOUD_API_URL = "https://api.openmates.org";
|
|
2452
|
+
var DEFAULT_API_URL = process.env.OPENMATES_API_URL ?? CLOUD_API_URL;
|
|
2386
2453
|
var SETTINGS_GET_RATE_LIMIT_RETRY_MS = 61e3;
|
|
2387
2454
|
var SKILL_TASK_POLL_INTERVAL_MS = 2e3;
|
|
2388
2455
|
var SKILL_TASK_POLL_TIMEOUT_MS = 3e5;
|
|
2456
|
+
function normalizeOrigin(url) {
|
|
2457
|
+
url.pathname = "";
|
|
2458
|
+
url.search = "";
|
|
2459
|
+
url.hash = "";
|
|
2460
|
+
return url.toString().replace(/\/$/, "");
|
|
2461
|
+
}
|
|
2462
|
+
function isLocalHost(hostname) {
|
|
2463
|
+
return ["localhost", "127.0.0.1", "::1"].includes(hostname);
|
|
2464
|
+
}
|
|
2465
|
+
function loadDefaultServerApiUrl() {
|
|
2466
|
+
const config = loadServerConfig();
|
|
2467
|
+
return config?.apiUrl?.replace(/\/$/, "") ?? null;
|
|
2468
|
+
}
|
|
2389
2469
|
function deriveAppUrl(apiUrl) {
|
|
2390
2470
|
if (process.env.OPENMATES_APP_URL) {
|
|
2391
2471
|
return process.env.OPENMATES_APP_URL.replace(/\/$/, "");
|
|
2392
2472
|
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2473
|
+
const serverAppUrl = loadServerConfig()?.appUrl;
|
|
2474
|
+
if (serverAppUrl && apiUrl.replace(/\/$/, "") === loadDefaultServerApiUrl()) {
|
|
2475
|
+
return serverAppUrl.replace(/\/$/, "");
|
|
2395
2476
|
}
|
|
2396
|
-
|
|
2477
|
+
try {
|
|
2478
|
+
const url = new URL(apiUrl);
|
|
2479
|
+
if (url.hostname === "api.dev.openmates.org") {
|
|
2480
|
+
return "https://app.dev.openmates.org";
|
|
2481
|
+
}
|
|
2482
|
+
if (url.hostname === "api.openmates.org") {
|
|
2483
|
+
return "https://openmates.org";
|
|
2484
|
+
}
|
|
2485
|
+
if (isLocalHost(url.hostname)) {
|
|
2486
|
+
return "http://localhost:5173";
|
|
2487
|
+
}
|
|
2488
|
+
if (url.hostname.startsWith("api.")) {
|
|
2489
|
+
url.hostname = `app.${url.hostname.slice(4)}`;
|
|
2490
|
+
}
|
|
2491
|
+
return normalizeOrigin(url);
|
|
2492
|
+
} catch {
|
|
2397
2493
|
return "https://openmates.org";
|
|
2398
2494
|
}
|
|
2399
|
-
if (apiUrl.includes("localhost")) {
|
|
2400
|
-
return "http://localhost:5173";
|
|
2401
|
-
}
|
|
2402
|
-
return "https://openmates.org";
|
|
2403
2495
|
}
|
|
2404
2496
|
var CLI_DEVICE_NAME_PREFIX = "OpenMates CLI";
|
|
2405
2497
|
var BLOCKED_SETTINGS_MUTATE_PATHS = /* @__PURE__ */ new Set([
|
|
@@ -2420,7 +2512,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
2420
2512
|
http;
|
|
2421
2513
|
constructor(options = {}) {
|
|
2422
2514
|
const diskSession = options.session ?? this.getValidSessionFromDisk();
|
|
2423
|
-
this.apiUrl = (options.apiUrl ?? process.env.OPENMATES_API_URL ?? diskSession?.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
2515
|
+
this.apiUrl = (options.apiUrl ?? process.env.OPENMATES_API_URL ?? diskSession?.apiUrl ?? loadDefaultServerApiUrl() ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
2424
2516
|
this.session = diskSession;
|
|
2425
2517
|
this.http = new OpenMatesHttpClient({
|
|
2426
2518
|
apiUrl: this.apiUrl,
|
|
@@ -5838,9 +5930,9 @@ var OutputRedactor = class {
|
|
|
5838
5930
|
};
|
|
5839
5931
|
|
|
5840
5932
|
// src/fileEmbed.ts
|
|
5841
|
-
import { readFileSync as
|
|
5842
|
-
import { basename, extname, resolve } from "path";
|
|
5843
|
-
import { homedir as
|
|
5933
|
+
import { readFileSync as readFileSync4, statSync, existsSync as existsSync4 } from "fs";
|
|
5934
|
+
import { basename, extname, resolve as resolve2 } from "path";
|
|
5935
|
+
import { homedir as homedir4 } from "os";
|
|
5844
5936
|
import { createHash as createHash4 } from "crypto";
|
|
5845
5937
|
var MAX_PER_FILE_SIZE = 100 * 1024 * 1024;
|
|
5846
5938
|
var BLOCKED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -6045,9 +6137,9 @@ function processEnvFileZeroKnowledge(content) {
|
|
|
6045
6137
|
}
|
|
6046
6138
|
function resolvePath(filePath) {
|
|
6047
6139
|
if (filePath.startsWith("~/")) {
|
|
6048
|
-
return
|
|
6140
|
+
return resolve2(homedir4(), filePath.slice(2));
|
|
6049
6141
|
}
|
|
6050
|
-
return
|
|
6142
|
+
return resolve2(filePath);
|
|
6051
6143
|
}
|
|
6052
6144
|
function processFiles(filePaths, redactor) {
|
|
6053
6145
|
const embeds = [];
|
|
@@ -6057,7 +6149,7 @@ function processFiles(filePaths, redactor) {
|
|
|
6057
6149
|
const resolvedPath = resolvePath(rawPath);
|
|
6058
6150
|
const filename = basename(resolvedPath);
|
|
6059
6151
|
const ext = getExt(filename);
|
|
6060
|
-
if (!
|
|
6152
|
+
if (!existsSync4(resolvedPath)) {
|
|
6061
6153
|
errors.push({ path: rawPath, error: "File not found" });
|
|
6062
6154
|
continue;
|
|
6063
6155
|
}
|
|
@@ -6123,7 +6215,7 @@ function processFiles(filePaths, redactor) {
|
|
|
6123
6215
|
}
|
|
6124
6216
|
function processCodeFile(filePath, filename, redactor) {
|
|
6125
6217
|
try {
|
|
6126
|
-
let content =
|
|
6218
|
+
let content = readFileSync4(filePath, "utf-8");
|
|
6127
6219
|
let secretsRedacted = false;
|
|
6128
6220
|
let zeroKnowledge = false;
|
|
6129
6221
|
if (isEnvFile(filename)) {
|
|
@@ -7544,69 +7636,6 @@ import { copyFileSync, existsSync as existsSync5, mkdirSync as mkdirSync3, readF
|
|
|
7544
7636
|
import { createInterface as createInterface2 } from "readline";
|
|
7545
7637
|
import { homedir as homedir5 } from "os";
|
|
7546
7638
|
import { join as join3, resolve as resolve3 } from "path";
|
|
7547
|
-
|
|
7548
|
-
// src/serverConfig.ts
|
|
7549
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
7550
|
-
import { homedir as homedir4 } from "os";
|
|
7551
|
-
import { join as join2, resolve as resolve2 } from "path";
|
|
7552
|
-
var STATE_DIR = join2(homedir4(), ".openmates");
|
|
7553
|
-
var CONFIG_FILE = "server.json";
|
|
7554
|
-
function ensureStateDir2() {
|
|
7555
|
-
if (!existsSync4(STATE_DIR)) {
|
|
7556
|
-
mkdirSync2(STATE_DIR, { recursive: true, mode: 448 });
|
|
7557
|
-
}
|
|
7558
|
-
return STATE_DIR;
|
|
7559
|
-
}
|
|
7560
|
-
function saveServerConfig(config) {
|
|
7561
|
-
const dir = ensureStateDir2();
|
|
7562
|
-
const filePath = join2(dir, CONFIG_FILE);
|
|
7563
|
-
writeFileSync2(filePath, `${JSON.stringify(config, null, 2)}
|
|
7564
|
-
`, { mode: 420 });
|
|
7565
|
-
}
|
|
7566
|
-
function loadServerConfig() {
|
|
7567
|
-
const filePath = join2(STATE_DIR, CONFIG_FILE);
|
|
7568
|
-
if (!existsSync4(filePath)) return null;
|
|
7569
|
-
try {
|
|
7570
|
-
return JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
7571
|
-
} catch {
|
|
7572
|
-
return null;
|
|
7573
|
-
}
|
|
7574
|
-
}
|
|
7575
|
-
function removeServerConfig() {
|
|
7576
|
-
const filePath = join2(STATE_DIR, CONFIG_FILE);
|
|
7577
|
-
if (existsSync4(filePath)) {
|
|
7578
|
-
rmSync2(filePath);
|
|
7579
|
-
}
|
|
7580
|
-
}
|
|
7581
|
-
var SOURCE_COMPOSE_MARKER = join2("backend", "core", "docker-compose.yml");
|
|
7582
|
-
var IMAGE_COMPOSE_MARKER = join2("backend", "core", "docker-compose.selfhost.yml");
|
|
7583
|
-
function isOpenMatesDir(dir) {
|
|
7584
|
-
return existsSync4(join2(dir, SOURCE_COMPOSE_MARKER)) || existsSync4(join2(dir, IMAGE_COMPOSE_MARKER));
|
|
7585
|
-
}
|
|
7586
|
-
function resolveServerPath(flags) {
|
|
7587
|
-
if (typeof flags.path === "string" && flags.path) {
|
|
7588
|
-
const explicit = resolve2(flags.path);
|
|
7589
|
-
if (!isOpenMatesDir(explicit)) {
|
|
7590
|
-
throw new Error(
|
|
7591
|
-
`${explicit} does not appear to be an OpenMates installation (missing ${SOURCE_COMPOSE_MARKER} or ${IMAGE_COMPOSE_MARKER}).`
|
|
7592
|
-
);
|
|
7593
|
-
}
|
|
7594
|
-
return explicit;
|
|
7595
|
-
}
|
|
7596
|
-
const config = loadServerConfig();
|
|
7597
|
-
if (config?.installPath && isOpenMatesDir(config.installPath)) {
|
|
7598
|
-
return config.installPath;
|
|
7599
|
-
}
|
|
7600
|
-
const cwd = process.cwd();
|
|
7601
|
-
if (isOpenMatesDir(cwd)) {
|
|
7602
|
-
return cwd;
|
|
7603
|
-
}
|
|
7604
|
-
throw new Error(
|
|
7605
|
-
"No OpenMates installation found.\nRun 'openmates server install' to set up a new server, or use --path <dir>."
|
|
7606
|
-
);
|
|
7607
|
-
}
|
|
7608
|
-
|
|
7609
|
-
// src/server.ts
|
|
7610
7639
|
var SOURCE_COMPOSE_FILE = join3("backend", "core", "docker-compose.yml");
|
|
7611
7640
|
var IMAGE_COMPOSE_FILE = join3("backend", "core", "docker-compose.selfhost.yml");
|
|
7612
7641
|
var COMPOSE_OVERRIDE = join3("backend", "core", "docker-compose.override.yml");
|
|
@@ -7779,6 +7808,15 @@ function setEnvVar(content, name, value) {
|
|
|
7779
7808
|
function setEnvIfEmpty(content, name, value) {
|
|
7780
7809
|
return getEnvVar(content, name) ? content : setEnvVar(content, name, value);
|
|
7781
7810
|
}
|
|
7811
|
+
function firstCsvValue(value) {
|
|
7812
|
+
return value.split(",").map((item) => item.trim()).find(Boolean) ?? "";
|
|
7813
|
+
}
|
|
7814
|
+
function deriveSelfHostCliUrls(envContent) {
|
|
7815
|
+
return {
|
|
7816
|
+
apiUrl: firstCsvValue(getEnvVar(envContent, "VITE_API_URL")) || "http://localhost:8000",
|
|
7817
|
+
appUrl: firstCsvValue(getEnvVar(envContent, "PRODUCTION_URL")) || "http://localhost:5173"
|
|
7818
|
+
};
|
|
7819
|
+
}
|
|
7782
7820
|
async function fetchText(url) {
|
|
7783
7821
|
const response = await fetch(url);
|
|
7784
7822
|
if (!response.ok) {
|
|
@@ -8014,6 +8052,7 @@ async function serverInstall(flags) {
|
|
|
8014
8052
|
const imageTag = typeof flags["image-tag"] === "string" ? flags["image-tag"] : getDefaultImageTag();
|
|
8015
8053
|
console.error(`Preparing OpenMates image-mode install at ${installPath}...`);
|
|
8016
8054
|
await writeImageModeRuntimeFiles(installPath, imageTag);
|
|
8055
|
+
const cliUrls2 = deriveSelfHostCliUrls(readFileSync5(join3(installPath, ".env"), "utf-8"));
|
|
8017
8056
|
try {
|
|
8018
8057
|
exec("docker network create openmates", installPath);
|
|
8019
8058
|
} catch {
|
|
@@ -8023,7 +8062,8 @@ async function serverInstall(flags) {
|
|
|
8023
8062
|
installedAt: Date.now(),
|
|
8024
8063
|
composeProfile: "core",
|
|
8025
8064
|
installMode: "image",
|
|
8026
|
-
imageTag
|
|
8065
|
+
imageTag,
|
|
8066
|
+
...cliUrls2
|
|
8027
8067
|
});
|
|
8028
8068
|
if (flags.json === true) {
|
|
8029
8069
|
printJson({ command: "install", status: "success", path: installPath, mode: "image", imageTag });
|
|
@@ -8037,6 +8077,8 @@ OpenMates installed at ${installPath}`);
|
|
|
8037
8077
|
console.log(" 2. Open http://localhost:5173");
|
|
8038
8078
|
if (firstInvite) console.log(` 3. Sign up with invite code: ${firstInvite}`);
|
|
8039
8079
|
console.log(" 4. After signup, make yourself admin: openmates server make-admin your@email.com");
|
|
8080
|
+
console.log(`
|
|
8081
|
+
CLI default API: ${cliUrls2.apiUrl}`);
|
|
8040
8082
|
console.log("\nOptional: edit .env first to add LLM provider API keys. Source builds are available with --from-source.");
|
|
8041
8083
|
}
|
|
8042
8084
|
return;
|
|
@@ -8079,11 +8121,14 @@ OpenMates installed at ${installPath}`);
|
|
|
8079
8121
|
console.error("Setup script failed. Check the output above for details.");
|
|
8080
8122
|
process.exit(setupCode);
|
|
8081
8123
|
}
|
|
8124
|
+
const envPath = join3(installPath, ".env");
|
|
8125
|
+
const cliUrls = deriveSelfHostCliUrls(existsSync5(envPath) ? readFileSync5(envPath, "utf-8") : "");
|
|
8082
8126
|
saveServerConfig({
|
|
8083
8127
|
installPath,
|
|
8084
8128
|
installedAt: Date.now(),
|
|
8085
8129
|
composeProfile: "core",
|
|
8086
|
-
installMode: "source"
|
|
8130
|
+
installMode: "source",
|
|
8131
|
+
...cliUrls
|
|
8087
8132
|
});
|
|
8088
8133
|
if (flags.json === true) {
|
|
8089
8134
|
printJson({ command: "install", status: "success", path: installPath, mode: "source" });
|
|
@@ -8094,6 +8139,8 @@ OpenMates installed at ${installPath}`);
|
|
|
8094
8139
|
console.log(" 1. Run: openmates server start");
|
|
8095
8140
|
console.log(" 2. Open http://localhost:5173");
|
|
8096
8141
|
console.log(" 3. After signup, make yourself admin: openmates server make-admin your@email.com");
|
|
8142
|
+
console.log(`
|
|
8143
|
+
CLI default API: ${cliUrls.apiUrl}`);
|
|
8097
8144
|
console.log("\nOptional: edit .env first to add LLM provider API keys. Without keys, the web app and backend still start, but AI model processing is unavailable.");
|
|
8098
8145
|
}
|
|
8099
8146
|
}
|
|
@@ -45138,7 +45185,7 @@ Commands:
|
|
|
45138
45185
|
|
|
45139
45186
|
Flags:
|
|
45140
45187
|
--json Output raw JSON instead of formatted output
|
|
45141
|
-
--api-url <url> Override API base URL (default: https://api.openmates.org)
|
|
45188
|
+
--api-url <url> Override API base URL (default: installed self-host server, then https://api.openmates.org)
|
|
45142
45189
|
--api-key <key> Optional API key override (or set OPENMATES_API_KEY)
|
|
45143
45190
|
--help Show contextual help for any command`);
|
|
45144
45191
|
}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED