orionfold-relay 0.15.4 → 0.16.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.
- package/dist/cli.js +481 -228
- package/next.config.mjs +21 -1
- package/package.json +2 -2
- package/src/app/layout.tsx +7 -1
- package/src/components/instance/instance-section.tsx +1 -1
- package/src/components/settings/providers-runtimes-section.tsx +47 -1
- package/src/lib/desktop/prebuilt-download.ts +321 -0
package/dist/cli.js
CHANGED
|
@@ -27,11 +27,11 @@ var __copyProps = (to, from, except, desc16) => {
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
|
|
29
29
|
// src/lib/utils/app-root.ts
|
|
30
|
-
import { existsSync as
|
|
31
|
-
import { join as
|
|
30
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
31
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
32
32
|
function getAppRoot(metaDirname, depth) {
|
|
33
33
|
if (metaDirname) {
|
|
34
|
-
const candidate =
|
|
34
|
+
const candidate = join3(metaDirname, ...Array(depth).fill(".."));
|
|
35
35
|
if (isPackageRoot(candidate)) return candidate;
|
|
36
36
|
let dir = metaDirname;
|
|
37
37
|
while (true) {
|
|
@@ -44,10 +44,10 @@ function getAppRoot(metaDirname, depth) {
|
|
|
44
44
|
return process.cwd();
|
|
45
45
|
}
|
|
46
46
|
function isPackageRoot(dir) {
|
|
47
|
-
const pkgPath =
|
|
48
|
-
if (!
|
|
47
|
+
const pkgPath = join3(dir, "package.json");
|
|
48
|
+
if (!existsSync3(pkgPath)) return false;
|
|
49
49
|
try {
|
|
50
|
-
const pkg2 = JSON.parse(
|
|
50
|
+
const pkg2 = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
51
51
|
return pkg2.name === PKG_NAME;
|
|
52
52
|
} catch {
|
|
53
53
|
return false;
|
|
@@ -63,17 +63,17 @@ var init_app_root = __esm({
|
|
|
63
63
|
|
|
64
64
|
// src/lib/config/env.ts
|
|
65
65
|
import { homedir } from "os";
|
|
66
|
-
import { join as
|
|
66
|
+
import { join as join4, resolve } from "path";
|
|
67
67
|
function dataDir() {
|
|
68
|
-
return process.env.RELAY_DATA_DIR ||
|
|
68
|
+
return process.env.RELAY_DATA_DIR || join4(homedir(), DEFAULT_DATA_DIR_NAME);
|
|
69
69
|
}
|
|
70
70
|
function dbPath() {
|
|
71
|
-
return
|
|
71
|
+
return join4(dataDir(), DB_FILENAME);
|
|
72
72
|
}
|
|
73
73
|
function isPrivateDataDir() {
|
|
74
74
|
const override = process.env.RELAY_DATA_DIR;
|
|
75
75
|
if (!override) return false;
|
|
76
|
-
return resolve(override) !== resolve(
|
|
76
|
+
return resolve(override) !== resolve(join4(homedir(), DEFAULT_DATA_DIR_NAME));
|
|
77
77
|
}
|
|
78
78
|
function launchCwd() {
|
|
79
79
|
return process.env.RELAY_LAUNCH_CWD || process.cwd();
|
|
@@ -125,7 +125,7 @@ __export(ainative_paths_exports, {
|
|
|
125
125
|
getAinativeSnapshotsDir: () => getAinativeSnapshotsDir,
|
|
126
126
|
getAinativeUploadsDir: () => getAinativeUploadsDir
|
|
127
127
|
});
|
|
128
|
-
import { join as
|
|
128
|
+
import { join as join5 } from "path";
|
|
129
129
|
function getAinativeDataDir() {
|
|
130
130
|
return dataDir();
|
|
131
131
|
}
|
|
@@ -133,55 +133,55 @@ function getAinativeDbPath() {
|
|
|
133
133
|
return dbPath();
|
|
134
134
|
}
|
|
135
135
|
function getAinativeUploadsDir() {
|
|
136
|
-
return
|
|
136
|
+
return join5(getAinativeDataDir(), "uploads");
|
|
137
137
|
}
|
|
138
138
|
function getAinativeBlueprintsDir() {
|
|
139
|
-
return
|
|
139
|
+
return join5(getAinativeDataDir(), "blueprints");
|
|
140
140
|
}
|
|
141
141
|
function getAinativeScreenshotsDir() {
|
|
142
|
-
return
|
|
142
|
+
return join5(getAinativeDataDir(), "screenshots");
|
|
143
143
|
}
|
|
144
144
|
function getAinativeSnapshotsDir() {
|
|
145
|
-
return
|
|
145
|
+
return join5(getAinativeDataDir(), "snapshots");
|
|
146
146
|
}
|
|
147
147
|
function getAinativeOutputsDir() {
|
|
148
|
-
return
|
|
148
|
+
return join5(getAinativeDataDir(), "outputs");
|
|
149
149
|
}
|
|
150
150
|
function getAinativeSessionsDir() {
|
|
151
|
-
return
|
|
151
|
+
return join5(getAinativeDataDir(), "sessions");
|
|
152
152
|
}
|
|
153
153
|
function getAinativeLogsDir() {
|
|
154
|
-
return
|
|
154
|
+
return join5(getAinativeDataDir(), "logs");
|
|
155
155
|
}
|
|
156
156
|
function getAinativeDocumentsDir() {
|
|
157
|
-
return
|
|
157
|
+
return join5(getAinativeDataDir(), "documents");
|
|
158
158
|
}
|
|
159
159
|
function getAinativeCodexDir() {
|
|
160
|
-
return
|
|
160
|
+
return join5(getAinativeDataDir(), "codex");
|
|
161
161
|
}
|
|
162
162
|
function getAinativeCodexConfigPath() {
|
|
163
|
-
return
|
|
163
|
+
return join5(getAinativeCodexDir(), "config.toml");
|
|
164
164
|
}
|
|
165
165
|
function getAinativeCodexAuthPath() {
|
|
166
|
-
return
|
|
166
|
+
return join5(getAinativeCodexDir(), "auth.json");
|
|
167
167
|
}
|
|
168
168
|
function getAinativeProfilesDir() {
|
|
169
|
-
return
|
|
169
|
+
return join5(getAinativeDataDir(), "profiles");
|
|
170
170
|
}
|
|
171
171
|
function getAinativePluginsDir() {
|
|
172
|
-
return
|
|
172
|
+
return join5(getAinativeDataDir(), "plugins");
|
|
173
173
|
}
|
|
174
174
|
function getAinativeAppsDir() {
|
|
175
|
-
return
|
|
175
|
+
return join5(getAinativeDataDir(), "apps");
|
|
176
176
|
}
|
|
177
177
|
function getAinativePluginsLockPath() {
|
|
178
|
-
return
|
|
178
|
+
return join5(getAinativeDataDir(), "plugins.lock");
|
|
179
179
|
}
|
|
180
180
|
function getAinativeSchedulesDir() {
|
|
181
|
-
return
|
|
181
|
+
return join5(getAinativeDataDir(), "schedules");
|
|
182
182
|
}
|
|
183
183
|
function getAinativePluginExamplesDir() {
|
|
184
|
-
return
|
|
184
|
+
return join5(
|
|
185
185
|
getAppRoot(import.meta.dirname, 3),
|
|
186
186
|
"src",
|
|
187
187
|
"lib",
|
|
@@ -1155,12 +1155,12 @@ var init_bootstrap = __esm({
|
|
|
1155
1155
|
});
|
|
1156
1156
|
|
|
1157
1157
|
// src/lib/instance/detect.ts
|
|
1158
|
-
import { existsSync as
|
|
1159
|
-
import { join as
|
|
1158
|
+
import { existsSync as existsSync5 } from "fs";
|
|
1159
|
+
import { join as join7 } from "path";
|
|
1160
1160
|
function isDevMode(cwd = process.cwd()) {
|
|
1161
1161
|
if (isInstanceModeEnv()) return false;
|
|
1162
1162
|
if (isDevModeEnv()) return true;
|
|
1163
|
-
if (
|
|
1163
|
+
if (existsSync5(join7(cwd, ".git", "relay-dev-mode"))) return true;
|
|
1164
1164
|
return false;
|
|
1165
1165
|
}
|
|
1166
1166
|
function isPrivateInstance() {
|
|
@@ -1221,25 +1221,25 @@ var init_types = __esm({
|
|
|
1221
1221
|
});
|
|
1222
1222
|
|
|
1223
1223
|
// src/lib/environment/parsers/utils.ts
|
|
1224
|
-
import { createHash } from "crypto";
|
|
1225
|
-
import { readFileSync as
|
|
1224
|
+
import { createHash as createHash2 } from "crypto";
|
|
1225
|
+
import { readFileSync as readFileSync4, statSync as statSync2 } from "fs";
|
|
1226
1226
|
function computeHash(content) {
|
|
1227
1227
|
const truncated = content.slice(0, MAX_HASH_BYTES);
|
|
1228
|
-
return
|
|
1228
|
+
return createHash2("sha256").update(truncated).digest("hex");
|
|
1229
1229
|
}
|
|
1230
1230
|
function safePreview(content) {
|
|
1231
1231
|
return content.slice(0, MAX_PREVIEW_CHARS).trim();
|
|
1232
1232
|
}
|
|
1233
1233
|
function safeStat(path19) {
|
|
1234
1234
|
try {
|
|
1235
|
-
return
|
|
1235
|
+
return statSync2(path19);
|
|
1236
1236
|
} catch {
|
|
1237
1237
|
return null;
|
|
1238
1238
|
}
|
|
1239
1239
|
}
|
|
1240
1240
|
function safeReadFile(path19) {
|
|
1241
1241
|
try {
|
|
1242
|
-
return
|
|
1242
|
+
return readFileSync4(path19, "utf-8");
|
|
1243
1243
|
} catch {
|
|
1244
1244
|
return null;
|
|
1245
1245
|
}
|
|
@@ -1344,7 +1344,7 @@ __export(wrap_exports, {
|
|
|
1344
1344
|
import fs from "fs";
|
|
1345
1345
|
import path from "path";
|
|
1346
1346
|
import { execFileSync } from "child_process";
|
|
1347
|
-
import { fileURLToPath } from "url";
|
|
1347
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1348
1348
|
function logToFile(line) {
|
|
1349
1349
|
try {
|
|
1350
1350
|
const logsDir = getAinativeLogsDir();
|
|
@@ -1357,9 +1357,9 @@ function logToFile(line) {
|
|
|
1357
1357
|
} catch {
|
|
1358
1358
|
}
|
|
1359
1359
|
}
|
|
1360
|
-
function profilePath(
|
|
1361
|
-
const moduleDir = path.dirname(
|
|
1362
|
-
return path.join(moduleDir, "profiles",
|
|
1360
|
+
function profilePath(relative2) {
|
|
1361
|
+
const moduleDir = path.dirname(fileURLToPath2(import.meta.url));
|
|
1362
|
+
return path.join(moduleDir, "profiles", relative2);
|
|
1363
1363
|
}
|
|
1364
1364
|
function readSeatbeltProfile(cap, pluginId) {
|
|
1365
1365
|
const p = profilePath(`seatbelt-${cap}.sb`);
|
|
@@ -3114,7 +3114,7 @@ __export(db_exports, {
|
|
|
3114
3114
|
});
|
|
3115
3115
|
import Database2 from "better-sqlite3";
|
|
3116
3116
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
3117
|
-
import { mkdirSync } from "fs";
|
|
3117
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
3118
3118
|
var dataDir2, dbPath2, sqlite, db;
|
|
3119
3119
|
var init_db = __esm({
|
|
3120
3120
|
"src/lib/db/index.ts"() {
|
|
@@ -3123,7 +3123,7 @@ var init_db = __esm({
|
|
|
3123
3123
|
init_env();
|
|
3124
3124
|
init_bootstrap();
|
|
3125
3125
|
dataDir2 = dataDir();
|
|
3126
|
-
|
|
3126
|
+
mkdirSync2(dataDir2, { recursive: true });
|
|
3127
3127
|
dbPath2 = dbPath();
|
|
3128
3128
|
sqlite = new Database2(dbPath2);
|
|
3129
3129
|
sqlite.pragma("journal_mode = WAL");
|
|
@@ -3913,7 +3913,7 @@ __export(load_exports, {
|
|
|
3913
3913
|
loadLicense: () => loadLicense
|
|
3914
3914
|
});
|
|
3915
3915
|
import fs4 from "fs";
|
|
3916
|
-
import { fileURLToPath as
|
|
3916
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3917
3917
|
function assertEnvelope(value, origin) {
|
|
3918
3918
|
if (!value || typeof value !== "object") {
|
|
3919
3919
|
throw new LicenseLoadError(`License at ${origin} is not a JSON object.`);
|
|
@@ -3957,7 +3957,7 @@ async function loadLicense(urlOrPath) {
|
|
|
3957
3957
|
}
|
|
3958
3958
|
return parse2(await res.text(), urlOrPath);
|
|
3959
3959
|
}
|
|
3960
|
-
const filePath = urlOrPath.startsWith("file://") ?
|
|
3960
|
+
const filePath = urlOrPath.startsWith("file://") ? fileURLToPath3(urlOrPath) : urlOrPath;
|
|
3961
3961
|
let text2;
|
|
3962
3962
|
try {
|
|
3963
3963
|
text2 = fs4.readFileSync(filePath, "utf-8");
|
|
@@ -4227,7 +4227,7 @@ var init_query_builder = __esm({
|
|
|
4227
4227
|
});
|
|
4228
4228
|
|
|
4229
4229
|
// src/lib/data/row-hash.ts
|
|
4230
|
-
import { createHash as
|
|
4230
|
+
import { createHash as createHash3 } from "crypto";
|
|
4231
4231
|
function canonicalizeRowForHash(data, columnNames) {
|
|
4232
4232
|
const canonical = {};
|
|
4233
4233
|
for (const name of columnNames) {
|
|
@@ -4237,7 +4237,7 @@ function canonicalizeRowForHash(data, columnNames) {
|
|
|
4237
4237
|
return JSON.stringify(canonical);
|
|
4238
4238
|
}
|
|
4239
4239
|
function hashRowData(data, columnNames) {
|
|
4240
|
-
return
|
|
4240
|
+
return createHash3("sha256").update(canonicalizeRowForHash(data, columnNames)).digest("hex");
|
|
4241
4241
|
}
|
|
4242
4242
|
var init_row_hash = __esm({
|
|
4243
4243
|
"src/lib/data/row-hash.ts"() {
|
|
@@ -5763,24 +5763,24 @@ __export(crypto_exports, {
|
|
|
5763
5763
|
getOrCreateKeyfile: () => getOrCreateKeyfile
|
|
5764
5764
|
});
|
|
5765
5765
|
import { randomBytes, createCipheriv, createDecipheriv } from "crypto";
|
|
5766
|
-
import { readFileSync as
|
|
5767
|
-
import { join as
|
|
5766
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync3, chmodSync } from "fs";
|
|
5767
|
+
import { join as join8 } from "path";
|
|
5768
5768
|
function getKeyfilePath() {
|
|
5769
|
-
return
|
|
5769
|
+
return join8(dataDir(), ".keyfile");
|
|
5770
5770
|
}
|
|
5771
5771
|
function getOrCreateKeyfile() {
|
|
5772
5772
|
const keyfilePath = getKeyfilePath();
|
|
5773
|
-
if (
|
|
5774
|
-
const key2 =
|
|
5773
|
+
if (existsSync6(keyfilePath)) {
|
|
5774
|
+
const key2 = readFileSync5(keyfilePath);
|
|
5775
5775
|
if (key2.length !== KEY_LENGTH) {
|
|
5776
5776
|
throw new Error(`Invalid keyfile: expected ${KEY_LENGTH} bytes, got ${key2.length}`);
|
|
5777
5777
|
}
|
|
5778
5778
|
return key2;
|
|
5779
5779
|
}
|
|
5780
|
-
const dir =
|
|
5781
|
-
|
|
5780
|
+
const dir = join8(keyfilePath, "..");
|
|
5781
|
+
mkdirSync3(dir, { recursive: true });
|
|
5782
5782
|
const key = randomBytes(KEY_LENGTH);
|
|
5783
|
-
|
|
5783
|
+
writeFileSync2(keyfilePath, key, { mode: 384 });
|
|
5784
5784
|
chmodSync(keyfilePath, 384);
|
|
5785
5785
|
return key;
|
|
5786
5786
|
}
|
|
@@ -6737,18 +6737,18 @@ __export(workspace_context_exports, {
|
|
|
6737
6737
|
getLaunchCwd: () => getLaunchCwd,
|
|
6738
6738
|
getWorkspaceContext: () => getWorkspaceContext
|
|
6739
6739
|
});
|
|
6740
|
-
import { basename, dirname as dirname3 } from "path";
|
|
6740
|
+
import { basename as basename2, dirname as dirname3 } from "path";
|
|
6741
6741
|
import { homedir as homedir4 } from "os";
|
|
6742
6742
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
6743
|
-
import { statSync as
|
|
6744
|
-
import { join as
|
|
6743
|
+
import { statSync as statSync3 } from "fs";
|
|
6744
|
+
import { join as join9 } from "path";
|
|
6745
6745
|
function getLaunchCwd() {
|
|
6746
6746
|
return launchCwd();
|
|
6747
6747
|
}
|
|
6748
6748
|
function getWorkspaceContext() {
|
|
6749
6749
|
const cwd = getLaunchCwd();
|
|
6750
6750
|
const home = homedir4();
|
|
6751
|
-
const folderName =
|
|
6751
|
+
const folderName = basename2(cwd);
|
|
6752
6752
|
const parent = dirname3(cwd);
|
|
6753
6753
|
const parentPath = parent.startsWith(home) ? "~" + parent.slice(home.length) : parent;
|
|
6754
6754
|
let gitBranch = null;
|
|
@@ -6762,8 +6762,8 @@ function getWorkspaceContext() {
|
|
|
6762
6762
|
}
|
|
6763
6763
|
let isWorktree = false;
|
|
6764
6764
|
try {
|
|
6765
|
-
const gitPath =
|
|
6766
|
-
const stat2 =
|
|
6765
|
+
const gitPath = join9(cwd, ".git");
|
|
6766
|
+
const stat2 = statSync3(gitPath);
|
|
6767
6767
|
isWorktree = stat2.isFile();
|
|
6768
6768
|
} catch {
|
|
6769
6769
|
}
|
|
@@ -7045,12 +7045,12 @@ var init_browser_mcp = __esm({
|
|
|
7045
7045
|
|
|
7046
7046
|
// src/lib/screenshots/persist.ts
|
|
7047
7047
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
7048
|
-
import { mkdirSync as
|
|
7049
|
-
import { join as
|
|
7048
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, unlinkSync } from "fs";
|
|
7049
|
+
import { join as join10 } from "path";
|
|
7050
7050
|
async function persistScreenshot(base64Data, opts2) {
|
|
7051
7051
|
const screenshotsDir = getAinativeScreenshotsDir();
|
|
7052
7052
|
const id = randomUUID3();
|
|
7053
|
-
const originalPath =
|
|
7053
|
+
const originalPath = join10(screenshotsDir, `${id}.png`);
|
|
7054
7054
|
let thumbnailPath = null;
|
|
7055
7055
|
try {
|
|
7056
7056
|
if (base64Data.length > MAX_BASE64_BYTES) {
|
|
@@ -7064,9 +7064,9 @@ async function persistScreenshot(base64Data, opts2) {
|
|
|
7064
7064
|
const dimensions = imageSize(new Uint8Array(buffer));
|
|
7065
7065
|
const width = dimensions.width ?? 0;
|
|
7066
7066
|
const height = dimensions.height ?? 0;
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
thumbnailPath =
|
|
7067
|
+
mkdirSync4(screenshotsDir, { recursive: true });
|
|
7068
|
+
writeFileSync3(originalPath, buffer);
|
|
7069
|
+
thumbnailPath = join10(screenshotsDir, `${id}_thumb.png`);
|
|
7070
7070
|
try {
|
|
7071
7071
|
const sharp = (await import("sharp")).default;
|
|
7072
7072
|
await sharp(buffer).resize(THUMBNAIL_WIDTH, void 0, { withoutEnlargement: true }).png({ quality: 80 }).toFile(thumbnailPath);
|
|
@@ -7131,7 +7131,7 @@ var init_persist = __esm({
|
|
|
7131
7131
|
});
|
|
7132
7132
|
|
|
7133
7133
|
// src/lib/usage/pricing-registry.ts
|
|
7134
|
-
import { createHash as
|
|
7134
|
+
import { createHash as createHash4 } from "crypto";
|
|
7135
7135
|
function buildDefaultProviders() {
|
|
7136
7136
|
const nowIso = "2026-03-17T00:00:00.000Z";
|
|
7137
7137
|
return {
|
|
@@ -11297,7 +11297,7 @@ var init_schedule_tools = __esm({
|
|
|
11297
11297
|
import { z as z13 } from "zod";
|
|
11298
11298
|
import { eq as eq25, and as and14, desc as desc10 } from "drizzle-orm";
|
|
11299
11299
|
import { access, stat, copyFile, mkdir } from "fs/promises";
|
|
11300
|
-
import { basename as
|
|
11300
|
+
import { basename as basename3, extname, join as join11 } from "path";
|
|
11301
11301
|
import crypto4 from "crypto";
|
|
11302
11302
|
function resolveMimeType(filename) {
|
|
11303
11303
|
return MIME_TYPES[extname(filename).toLowerCase()] ?? "application/octet-stream";
|
|
@@ -11389,14 +11389,14 @@ function documentTools(ctx) {
|
|
|
11389
11389
|
await access(args.file_path);
|
|
11390
11390
|
const stats = await stat(args.file_path);
|
|
11391
11391
|
if (!stats.isFile()) return err(`Not a file: ${args.file_path}`);
|
|
11392
|
-
const originalName =
|
|
11392
|
+
const originalName = basename3(args.file_path);
|
|
11393
11393
|
const mimeType = resolveMimeType(originalName);
|
|
11394
11394
|
const id = crypto4.randomUUID();
|
|
11395
11395
|
const ext = extname(originalName);
|
|
11396
11396
|
const filename = `${id}${ext}`;
|
|
11397
11397
|
const uploadsDir = getAinativeUploadsDir();
|
|
11398
11398
|
await mkdir(uploadsDir, { recursive: true });
|
|
11399
|
-
const storagePath =
|
|
11399
|
+
const storagePath = join11(uploadsDir, filename);
|
|
11400
11400
|
await copyFile(args.file_path, storagePath);
|
|
11401
11401
|
const effectiveProjectId = args.projectId ?? ctx.projectId ?? null;
|
|
11402
11402
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -12863,8 +12863,8 @@ var list_fused_profiles_exports = {};
|
|
|
12863
12863
|
__export(list_fused_profiles_exports, {
|
|
12864
12864
|
listFusedProfiles: () => listFusedProfiles
|
|
12865
12865
|
});
|
|
12866
|
-
import { readdirSync, readFileSync as
|
|
12867
|
-
import { join as
|
|
12866
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync4, existsSync as existsSync7 } from "fs";
|
|
12867
|
+
import { join as join12 } from "path";
|
|
12868
12868
|
import { homedir as homedir5 } from "os";
|
|
12869
12869
|
function parseFrontmatter2(content) {
|
|
12870
12870
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -12880,15 +12880,15 @@ function parseFrontmatter2(content) {
|
|
|
12880
12880
|
return result;
|
|
12881
12881
|
}
|
|
12882
12882
|
function loadFilesystemSkills(skillsDir, origin, projectRootDir) {
|
|
12883
|
-
if (!
|
|
12883
|
+
if (!existsSync7(skillsDir)) return [];
|
|
12884
12884
|
const profiles = [];
|
|
12885
|
-
for (const entry of
|
|
12886
|
-
const skillPath =
|
|
12885
|
+
for (const entry of readdirSync2(skillsDir)) {
|
|
12886
|
+
const skillPath = join12(skillsDir, entry);
|
|
12887
12887
|
try {
|
|
12888
|
-
if (!
|
|
12889
|
-
const skillMdPath =
|
|
12890
|
-
if (!
|
|
12891
|
-
const content =
|
|
12888
|
+
if (!statSync4(skillPath).isDirectory()) continue;
|
|
12889
|
+
const skillMdPath = join12(skillPath, "SKILL.md");
|
|
12890
|
+
if (!existsSync7(skillMdPath)) continue;
|
|
12891
|
+
const content = readFileSync6(skillMdPath, "utf8");
|
|
12892
12892
|
const fm = parseFrontmatter2(content);
|
|
12893
12893
|
if (!fm || !fm.name) {
|
|
12894
12894
|
console.warn(
|
|
@@ -12921,14 +12921,14 @@ function loadFilesystemSkills(skillsDir, origin, projectRootDir) {
|
|
|
12921
12921
|
}
|
|
12922
12922
|
return profiles;
|
|
12923
12923
|
}
|
|
12924
|
-
async function listFusedProfiles(projectDir, userSkillsDir =
|
|
12924
|
+
async function listFusedProfiles(projectDir, userSkillsDir = join12(homedir5(), ".claude", "skills")) {
|
|
12925
12925
|
const registry2 = listProfiles();
|
|
12926
12926
|
const registryIds = new Set(registry2.map((p) => p.id));
|
|
12927
12927
|
const userSkills = loadFilesystemSkills(userSkillsDir, "filesystem-user", void 0).filter(
|
|
12928
12928
|
(p) => !registryIds.has(p.id)
|
|
12929
12929
|
);
|
|
12930
12930
|
const projectSkills = projectDir ? loadFilesystemSkills(
|
|
12931
|
-
|
|
12931
|
+
join12(projectDir, ".claude", "skills"),
|
|
12932
12932
|
"filesystem-project",
|
|
12933
12933
|
projectDir
|
|
12934
12934
|
).filter((p) => !registryIds.has(p.id) && !userSkills.some((u) => u.id === p.id)) : [];
|
|
@@ -15604,21 +15604,21 @@ var init_active_skills = __esm({
|
|
|
15604
15604
|
});
|
|
15605
15605
|
|
|
15606
15606
|
// src/lib/environment/parsers/skill.ts
|
|
15607
|
-
import { readdirSync as
|
|
15608
|
-
import { join as
|
|
15607
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
15608
|
+
import { join as join13, basename as basename4 } from "path";
|
|
15609
15609
|
function parseSkillDir(dirPath, tool, scope, baseDir) {
|
|
15610
15610
|
const stat2 = safeStat(dirPath);
|
|
15611
15611
|
if (!stat2?.isDirectory()) return null;
|
|
15612
|
-
const name =
|
|
15612
|
+
const name = basename4(dirPath);
|
|
15613
15613
|
if (name.startsWith(".")) return null;
|
|
15614
15614
|
let mainFile = "";
|
|
15615
15615
|
let content = "";
|
|
15616
15616
|
try {
|
|
15617
|
-
const files =
|
|
15617
|
+
const files = readdirSync3(dirPath);
|
|
15618
15618
|
const skillFile = files.find((f) => f === "SKILL.md") || files.find((f) => f.endsWith(".md")) || files[0];
|
|
15619
15619
|
if (skillFile) {
|
|
15620
|
-
mainFile =
|
|
15621
|
-
content =
|
|
15620
|
+
mainFile = join13(dirPath, skillFile);
|
|
15621
|
+
content = readFileSync7(mainFile, "utf-8");
|
|
15622
15622
|
}
|
|
15623
15623
|
} catch {
|
|
15624
15624
|
return null;
|
|
@@ -15664,8 +15664,8 @@ var init_skill = __esm({
|
|
|
15664
15664
|
});
|
|
15665
15665
|
|
|
15666
15666
|
// src/lib/environment/parsers/settings.ts
|
|
15667
|
-
import { readdirSync as
|
|
15668
|
-
import { join as
|
|
15667
|
+
import { readdirSync as readdirSync4 } from "fs";
|
|
15668
|
+
import { join as join14, basename as basename5 } from "path";
|
|
15669
15669
|
function parseClaudeSettings(filePath, scope, baseDir) {
|
|
15670
15670
|
const content = safeReadFile(filePath);
|
|
15671
15671
|
if (!content) return [];
|
|
@@ -15679,7 +15679,7 @@ function parseClaudeSettings(filePath, scope, baseDir) {
|
|
|
15679
15679
|
tool: "claude-code",
|
|
15680
15680
|
category: "permission",
|
|
15681
15681
|
scope,
|
|
15682
|
-
name: `${
|
|
15682
|
+
name: `${basename5(filePath, ".json")}-allow`,
|
|
15683
15683
|
relPath: filePath.replace(baseDir, "").replace(/^\//, ""),
|
|
15684
15684
|
absPath: filePath,
|
|
15685
15685
|
contentHash: computeHash(JSON.stringify(config.permissions.allow)),
|
|
@@ -15694,7 +15694,7 @@ function parseClaudeSettings(filePath, scope, baseDir) {
|
|
|
15694
15694
|
tool: "claude-code",
|
|
15695
15695
|
category: "permission",
|
|
15696
15696
|
scope,
|
|
15697
|
-
name: `${
|
|
15697
|
+
name: `${basename5(filePath, ".json")}-deny`,
|
|
15698
15698
|
relPath: filePath.replace(baseDir, "").replace(/^\//, ""),
|
|
15699
15699
|
absPath: filePath,
|
|
15700
15700
|
contentHash: computeHash(JSON.stringify(config.permissions.deny)),
|
|
@@ -15768,8 +15768,8 @@ function parseOutputStyles(dirPath, tool, baseDir) {
|
|
|
15768
15768
|
if (!stat2?.isDirectory()) return [];
|
|
15769
15769
|
const artifacts = [];
|
|
15770
15770
|
try {
|
|
15771
|
-
for (const entry of
|
|
15772
|
-
const fullPath =
|
|
15771
|
+
for (const entry of readdirSync4(dirPath)) {
|
|
15772
|
+
const fullPath = join14(dirPath, entry);
|
|
15773
15773
|
const content = safeReadFile(fullPath);
|
|
15774
15774
|
if (!content) continue;
|
|
15775
15775
|
const fStat = safeStat(fullPath);
|
|
@@ -15778,7 +15778,7 @@ function parseOutputStyles(dirPath, tool, baseDir) {
|
|
|
15778
15778
|
tool,
|
|
15779
15779
|
category: "output-style",
|
|
15780
15780
|
scope: "user",
|
|
15781
|
-
name:
|
|
15781
|
+
name: basename5(entry, ".md"),
|
|
15782
15782
|
relPath: fullPath.replace(baseDir, "").replace(/^\//, ""),
|
|
15783
15783
|
absPath: fullPath,
|
|
15784
15784
|
contentHash: computeHash(content),
|
|
@@ -15846,18 +15846,18 @@ var init_instructions = __esm({
|
|
|
15846
15846
|
});
|
|
15847
15847
|
|
|
15848
15848
|
// src/lib/environment/scanners/claude-code.ts
|
|
15849
|
-
import { readdirSync as
|
|
15850
|
-
import { join as
|
|
15849
|
+
import { readdirSync as readdirSync5, existsSync as existsSync8 } from "fs";
|
|
15850
|
+
import { join as join15 } from "path";
|
|
15851
15851
|
function scanUserLevel(userHome) {
|
|
15852
|
-
const claudeDir =
|
|
15852
|
+
const claudeDir = join15(userHome, ".claude");
|
|
15853
15853
|
const artifacts = [];
|
|
15854
15854
|
const errors = [];
|
|
15855
|
-
if (!
|
|
15856
|
-
const skillsDir =
|
|
15857
|
-
if (
|
|
15855
|
+
if (!existsSync8(claudeDir)) return { artifacts, errors };
|
|
15856
|
+
const skillsDir = join15(claudeDir, "skills");
|
|
15857
|
+
if (existsSync8(skillsDir)) {
|
|
15858
15858
|
try {
|
|
15859
|
-
for (const entry of
|
|
15860
|
-
const skillPath =
|
|
15859
|
+
for (const entry of readdirSync5(skillsDir)) {
|
|
15860
|
+
const skillPath = join15(skillsDir, entry);
|
|
15861
15861
|
const artifact = parseSkillDir(skillPath, "claude-code", "user", userHome);
|
|
15862
15862
|
if (artifact) artifacts.push(artifact);
|
|
15863
15863
|
}
|
|
@@ -15865,32 +15865,32 @@ function scanUserLevel(userHome) {
|
|
|
15865
15865
|
errors.push({ path: skillsDir, error: String(e) });
|
|
15866
15866
|
}
|
|
15867
15867
|
}
|
|
15868
|
-
const mcpPath =
|
|
15869
|
-
if (
|
|
15868
|
+
const mcpPath = join15(claudeDir, ".mcp.json");
|
|
15869
|
+
if (existsSync8(mcpPath)) {
|
|
15870
15870
|
artifacts.push(...parseClaudeMcpConfig(mcpPath, "user", userHome));
|
|
15871
15871
|
}
|
|
15872
|
-
const pluginsFile =
|
|
15873
|
-
if (
|
|
15872
|
+
const pluginsFile = join15(claudeDir, "plugins", "installed_plugins.json");
|
|
15873
|
+
if (existsSync8(pluginsFile)) {
|
|
15874
15874
|
artifacts.push(...parseClaudePlugins(pluginsFile, userHome));
|
|
15875
15875
|
}
|
|
15876
15876
|
for (const settingsFile of ["settings.json", "settings.local.json"]) {
|
|
15877
|
-
const settingsPath =
|
|
15878
|
-
if (
|
|
15877
|
+
const settingsPath = join15(claudeDir, settingsFile);
|
|
15878
|
+
if (existsSync8(settingsPath)) {
|
|
15879
15879
|
artifacts.push(...parseClaudeSettings(settingsPath, "user", userHome));
|
|
15880
15880
|
}
|
|
15881
15881
|
}
|
|
15882
|
-
const outputStylesDir =
|
|
15883
|
-
if (
|
|
15882
|
+
const outputStylesDir = join15(claudeDir, "output-styles");
|
|
15883
|
+
if (existsSync8(outputStylesDir)) {
|
|
15884
15884
|
artifacts.push(...parseOutputStyles(outputStylesDir, "claude-code", userHome));
|
|
15885
15885
|
}
|
|
15886
|
-
const projectsDir =
|
|
15887
|
-
if (
|
|
15886
|
+
const projectsDir = join15(claudeDir, "projects");
|
|
15887
|
+
if (existsSync8(projectsDir)) {
|
|
15888
15888
|
try {
|
|
15889
|
-
for (const projEntry of
|
|
15890
|
-
const memoryDir =
|
|
15891
|
-
if (!
|
|
15892
|
-
const memoryIndex =
|
|
15893
|
-
if (
|
|
15889
|
+
for (const projEntry of readdirSync5(projectsDir)) {
|
|
15890
|
+
const memoryDir = join15(projectsDir, projEntry, "memory");
|
|
15891
|
+
if (!existsSync8(memoryDir)) continue;
|
|
15892
|
+
const memoryIndex = join15(memoryDir, "MEMORY.md");
|
|
15893
|
+
if (existsSync8(memoryIndex)) {
|
|
15894
15894
|
const artifact = parseInstructionFile(
|
|
15895
15895
|
memoryIndex,
|
|
15896
15896
|
"user",
|
|
@@ -15911,16 +15911,16 @@ function scanUserLevel(userHome) {
|
|
|
15911
15911
|
return { artifacts, errors };
|
|
15912
15912
|
}
|
|
15913
15913
|
function scanProjectLevel(projectDir) {
|
|
15914
|
-
const claudeDir =
|
|
15914
|
+
const claudeDir = join15(projectDir, ".claude");
|
|
15915
15915
|
const artifacts = [];
|
|
15916
15916
|
const errors = [];
|
|
15917
15917
|
artifacts.push(...scanInstructionFiles(projectDir, "project", projectDir));
|
|
15918
|
-
if (!
|
|
15919
|
-
const skillsDir =
|
|
15920
|
-
if (
|
|
15918
|
+
if (!existsSync8(claudeDir)) return { artifacts, errors };
|
|
15919
|
+
const skillsDir = join15(claudeDir, "skills");
|
|
15920
|
+
if (existsSync8(skillsDir)) {
|
|
15921
15921
|
try {
|
|
15922
|
-
for (const entry of
|
|
15923
|
-
const skillPath =
|
|
15922
|
+
for (const entry of readdirSync5(skillsDir)) {
|
|
15923
|
+
const skillPath = join15(skillsDir, entry);
|
|
15924
15924
|
const artifact = parseSkillDir(skillPath, "claude-code", "project", projectDir);
|
|
15925
15925
|
if (artifact) artifacts.push(artifact);
|
|
15926
15926
|
}
|
|
@@ -15928,21 +15928,21 @@ function scanProjectLevel(projectDir) {
|
|
|
15928
15928
|
errors.push({ path: skillsDir, error: String(e) });
|
|
15929
15929
|
}
|
|
15930
15930
|
}
|
|
15931
|
-
const mcpPath =
|
|
15932
|
-
if (
|
|
15931
|
+
const mcpPath = join15(claudeDir, ".mcp.json");
|
|
15932
|
+
if (existsSync8(mcpPath)) {
|
|
15933
15933
|
artifacts.push(...parseClaudeMcpConfig(mcpPath, "project", projectDir));
|
|
15934
15934
|
}
|
|
15935
15935
|
for (const settingsFile of ["settings.json", "settings.local.json"]) {
|
|
15936
|
-
const settingsPath =
|
|
15937
|
-
if (
|
|
15936
|
+
const settingsPath = join15(claudeDir, settingsFile);
|
|
15937
|
+
if (existsSync8(settingsPath)) {
|
|
15938
15938
|
artifacts.push(...parseClaudeSettings(settingsPath, "project", projectDir));
|
|
15939
15939
|
}
|
|
15940
15940
|
}
|
|
15941
|
-
const hooksDir =
|
|
15942
|
-
if (
|
|
15941
|
+
const hooksDir = join15(claudeDir, "hooks");
|
|
15942
|
+
if (existsSync8(hooksDir)) {
|
|
15943
15943
|
try {
|
|
15944
|
-
for (const entry of
|
|
15945
|
-
const hookPath =
|
|
15944
|
+
for (const entry of readdirSync5(hooksDir)) {
|
|
15945
|
+
const hookPath = join15(hooksDir, entry);
|
|
15946
15946
|
const content = safeReadFile(hookPath);
|
|
15947
15947
|
if (!content) continue;
|
|
15948
15948
|
const stat2 = safeStat(hookPath);
|
|
@@ -15987,18 +15987,18 @@ var init_claude_code = __esm({
|
|
|
15987
15987
|
});
|
|
15988
15988
|
|
|
15989
15989
|
// src/lib/environment/scanners/codex.ts
|
|
15990
|
-
import { readdirSync as
|
|
15991
|
-
import { join as
|
|
15990
|
+
import { readdirSync as readdirSync6, existsSync as existsSync9 } from "fs";
|
|
15991
|
+
import { join as join16 } from "path";
|
|
15992
15992
|
function scanUserLevel2(userHome) {
|
|
15993
|
-
const codexDir =
|
|
15993
|
+
const codexDir = join16(userHome, ".codex");
|
|
15994
15994
|
const artifacts = [];
|
|
15995
15995
|
const errors = [];
|
|
15996
|
-
if (!
|
|
15997
|
-
const skillsDir =
|
|
15998
|
-
if (
|
|
15996
|
+
if (!existsSync9(codexDir)) return { artifacts, errors };
|
|
15997
|
+
const skillsDir = join16(codexDir, "skills");
|
|
15998
|
+
if (existsSync9(skillsDir)) {
|
|
15999
15999
|
try {
|
|
16000
|
-
for (const entry of
|
|
16001
|
-
const skillPath =
|
|
16000
|
+
for (const entry of readdirSync6(skillsDir)) {
|
|
16001
|
+
const skillPath = join16(skillsDir, entry);
|
|
16002
16002
|
const artifact = parseSkillDir(skillPath, "codex", "user", userHome);
|
|
16003
16003
|
if (artifact) artifacts.push(artifact);
|
|
16004
16004
|
}
|
|
@@ -16006,16 +16006,16 @@ function scanUserLevel2(userHome) {
|
|
|
16006
16006
|
errors.push({ path: skillsDir, error: String(e) });
|
|
16007
16007
|
}
|
|
16008
16008
|
}
|
|
16009
|
-
const configPath =
|
|
16010
|
-
if (
|
|
16009
|
+
const configPath = join16(codexDir, "config.toml");
|
|
16010
|
+
if (existsSync9(configPath)) {
|
|
16011
16011
|
artifacts.push(...parseCodexSettings(configPath, userHome));
|
|
16012
16012
|
artifacts.push(...parseCodexMcpConfig(configPath, userHome));
|
|
16013
16013
|
}
|
|
16014
|
-
const rulesDir =
|
|
16015
|
-
if (
|
|
16014
|
+
const rulesDir = join16(codexDir, "rules");
|
|
16015
|
+
if (existsSync9(rulesDir)) {
|
|
16016
16016
|
try {
|
|
16017
|
-
for (const entry of
|
|
16018
|
-
const rulePath =
|
|
16017
|
+
for (const entry of readdirSync6(rulesDir)) {
|
|
16018
|
+
const rulePath = join16(rulesDir, entry);
|
|
16019
16019
|
const content = safeReadFile(rulePath);
|
|
16020
16020
|
if (!content) continue;
|
|
16021
16021
|
const stat2 = safeStat(rulePath);
|
|
@@ -16038,11 +16038,11 @@ function scanUserLevel2(userHome) {
|
|
|
16038
16038
|
errors.push({ path: rulesDir, error: String(e) });
|
|
16039
16039
|
}
|
|
16040
16040
|
}
|
|
16041
|
-
const memoriesDir =
|
|
16042
|
-
if (
|
|
16041
|
+
const memoriesDir = join16(codexDir, "memories");
|
|
16042
|
+
if (existsSync9(memoriesDir)) {
|
|
16043
16043
|
try {
|
|
16044
|
-
for (const entry of
|
|
16045
|
-
const memPath =
|
|
16044
|
+
for (const entry of readdirSync6(memoriesDir)) {
|
|
16045
|
+
const memPath = join16(memoriesDir, entry);
|
|
16046
16046
|
const content = safeReadFile(memPath);
|
|
16047
16047
|
if (!content) continue;
|
|
16048
16048
|
const stat2 = safeStat(memPath);
|
|
@@ -16070,8 +16070,8 @@ function scanUserLevel2(userHome) {
|
|
|
16070
16070
|
function scanProjectLevel2(projectDir) {
|
|
16071
16071
|
const artifacts = [];
|
|
16072
16072
|
const errors = [];
|
|
16073
|
-
const codexMd =
|
|
16074
|
-
if (
|
|
16073
|
+
const codexMd = join16(projectDir, "codex.md");
|
|
16074
|
+
if (existsSync9(codexMd)) {
|
|
16075
16075
|
const artifact = parseInstructionFile(codexMd, "project", projectDir, "codex");
|
|
16076
16076
|
if (artifact) artifacts.push(artifact);
|
|
16077
16077
|
}
|
|
@@ -16097,13 +16097,13 @@ var init_codex = __esm({
|
|
|
16097
16097
|
});
|
|
16098
16098
|
|
|
16099
16099
|
// src/lib/environment/scanner.ts
|
|
16100
|
-
import { existsSync as
|
|
16101
|
-
import { join as
|
|
16100
|
+
import { existsSync as existsSync10 } from "fs";
|
|
16101
|
+
import { join as join17 } from "path";
|
|
16102
16102
|
import { homedir as homedir6 } from "os";
|
|
16103
16103
|
function detectPersonas(userHome, projectDir) {
|
|
16104
16104
|
const personas = [];
|
|
16105
|
-
const hasClaudeCode =
|
|
16106
|
-
const hasCodex =
|
|
16105
|
+
const hasClaudeCode = existsSync10(join17(userHome, ".claude")) || existsSync10(join17(projectDir, ".claude"));
|
|
16106
|
+
const hasCodex = existsSync10(join17(userHome, ".codex"));
|
|
16107
16107
|
if (hasClaudeCode) personas.push("claude-code");
|
|
16108
16108
|
if (hasCodex) personas.push("codex");
|
|
16109
16109
|
return personas;
|
|
@@ -16254,8 +16254,8 @@ __export(list_skills_exports, {
|
|
|
16254
16254
|
listSkills: () => listSkills,
|
|
16255
16255
|
listSkillsEnriched: () => listSkillsEnriched
|
|
16256
16256
|
});
|
|
16257
|
-
import { readFileSync as
|
|
16258
|
-
import { join as
|
|
16257
|
+
import { readFileSync as readFileSync8, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
16258
|
+
import { join as join18 } from "path";
|
|
16259
16259
|
function listSkills(options = {}) {
|
|
16260
16260
|
const projectDir = options.projectDir ?? getLaunchCwd();
|
|
16261
16261
|
const scan = scanEnvironment({ projectDir });
|
|
@@ -16279,7 +16279,7 @@ function getSkill(id, options = {}) {
|
|
|
16279
16279
|
const filePath = resolveSkillFile(hit.absPath);
|
|
16280
16280
|
if (!filePath) return null;
|
|
16281
16281
|
try {
|
|
16282
|
-
const content =
|
|
16282
|
+
const content = readFileSync8(filePath, "utf8");
|
|
16283
16283
|
return { ...hit, content };
|
|
16284
16284
|
} catch {
|
|
16285
16285
|
return null;
|
|
@@ -16287,7 +16287,7 @@ function getSkill(id, options = {}) {
|
|
|
16287
16287
|
}
|
|
16288
16288
|
function resolveSkillFile(dirPath) {
|
|
16289
16289
|
try {
|
|
16290
|
-
const stat2 =
|
|
16290
|
+
const stat2 = statSync5(dirPath);
|
|
16291
16291
|
if (!stat2.isDirectory()) {
|
|
16292
16292
|
return dirPath;
|
|
16293
16293
|
}
|
|
@@ -16295,15 +16295,15 @@ function resolveSkillFile(dirPath) {
|
|
|
16295
16295
|
return null;
|
|
16296
16296
|
}
|
|
16297
16297
|
for (const name of ["SKILL.md", "skill.md"]) {
|
|
16298
|
-
const candidate =
|
|
16298
|
+
const candidate = join18(dirPath, name);
|
|
16299
16299
|
try {
|
|
16300
|
-
if (
|
|
16300
|
+
if (statSync5(candidate).isFile()) return candidate;
|
|
16301
16301
|
} catch {
|
|
16302
16302
|
}
|
|
16303
16303
|
}
|
|
16304
16304
|
try {
|
|
16305
|
-
const fallback =
|
|
16306
|
-
if (fallback) return
|
|
16305
|
+
const fallback = readdirSync7(dirPath).find((f) => f.toLowerCase().endsWith(".md"));
|
|
16306
|
+
if (fallback) return join18(dirPath, fallback);
|
|
16307
16307
|
} catch {
|
|
16308
16308
|
}
|
|
16309
16309
|
return null;
|
|
@@ -18704,7 +18704,7 @@ __export(openai_auth_exports, {
|
|
|
18704
18704
|
updateOpenAIAuthStatus: () => updateOpenAIAuthStatus,
|
|
18705
18705
|
updateOpenAIOAuthStatus: () => updateOpenAIOAuthStatus
|
|
18706
18706
|
});
|
|
18707
|
-
import { existsSync as
|
|
18707
|
+
import { existsSync as existsSync12 } from "fs";
|
|
18708
18708
|
function parseJson(raw) {
|
|
18709
18709
|
if (!raw) return null;
|
|
18710
18710
|
try {
|
|
@@ -18738,7 +18738,7 @@ async function getOpenAIAuthSettings() {
|
|
|
18738
18738
|
} else {
|
|
18739
18739
|
apiKeySource = "unknown";
|
|
18740
18740
|
}
|
|
18741
|
-
const oauthConnected = storedOauthConnected === "true" || storedOauthConnected == null &&
|
|
18741
|
+
const oauthConnected = storedOauthConnected === "true" || storedOauthConnected == null && existsSync12(getAinativeCodexAuthPath());
|
|
18742
18742
|
return {
|
|
18743
18743
|
method,
|
|
18744
18744
|
hasKey: hasDbKey || hasEnvKey,
|
|
@@ -18828,13 +18828,13 @@ __export(mcp_sync_exports, {
|
|
|
18828
18828
|
preparePluginMcpCodexSync: () => preparePluginMcpCodexSync,
|
|
18829
18829
|
syncPluginMcpToCodex: () => syncPluginMcpToCodex
|
|
18830
18830
|
});
|
|
18831
|
-
import { writeFileSync as
|
|
18832
|
-
import { join as
|
|
18831
|
+
import { writeFileSync as writeFileSync5 } from "fs";
|
|
18832
|
+
import { join as join20 } from "path";
|
|
18833
18833
|
import { homedir as homedir7 } from "os";
|
|
18834
18834
|
function prepareMcpToClaude(artifact, scope, projectDir) {
|
|
18835
18835
|
const metadata = artifact.metadata ? JSON.parse(artifact.metadata) : {};
|
|
18836
18836
|
const serverName = artifact.name;
|
|
18837
|
-
const targetPath = scope === "user" ?
|
|
18837
|
+
const targetPath = scope === "user" ? join20(homedir7(), ".claude", ".mcp.json") : join20(projectDir || getLaunchCwd(), ".claude", ".mcp.json");
|
|
18838
18838
|
const existing = safeReadFile(targetPath);
|
|
18839
18839
|
let config;
|
|
18840
18840
|
try {
|
|
@@ -18859,7 +18859,7 @@ function prepareMcpToClaude(artifact, scope, projectDir) {
|
|
|
18859
18859
|
function prepareMcpToCodex(artifact) {
|
|
18860
18860
|
const metadata = artifact.metadata ? JSON.parse(artifact.metadata) : {};
|
|
18861
18861
|
const serverName = artifact.name;
|
|
18862
|
-
const targetPath =
|
|
18862
|
+
const targetPath = join20(homedir7(), ".codex", "config.toml");
|
|
18863
18863
|
const existing = safeReadFile(targetPath) || "";
|
|
18864
18864
|
const lines = [];
|
|
18865
18865
|
lines.push(`[mcp_servers.${serverName}]`);
|
|
@@ -18894,7 +18894,7 @@ function prepareMcpSync(artifact, targetTool, scope, projectDir) {
|
|
|
18894
18894
|
return prepareMcpToCodex(artifact);
|
|
18895
18895
|
}
|
|
18896
18896
|
function preparePluginMcpCodexSync(registrations, targetPath) {
|
|
18897
|
-
const resolvedPath = targetPath ??
|
|
18897
|
+
const resolvedPath = targetPath ?? join20(homedir7(), ".codex", "config.toml");
|
|
18898
18898
|
const existing = safeReadFile(resolvedPath) || "";
|
|
18899
18899
|
const pluginKeys = new Set(
|
|
18900
18900
|
registrations.map((r) => `${r.pluginId}-${r.serverName}`)
|
|
@@ -18959,7 +18959,7 @@ async function syncPluginMcpToCodex() {
|
|
|
18959
18959
|
const { listPluginMcpRegistrations: listPluginMcpRegistrations2 } = await Promise.resolve().then(() => (init_mcp_loader(), mcp_loader_exports));
|
|
18960
18960
|
const registrations = await listPluginMcpRegistrations2();
|
|
18961
18961
|
const op = preparePluginMcpCodexSync(registrations);
|
|
18962
|
-
|
|
18962
|
+
writeFileSync5(op.targetPath, op.content, "utf8");
|
|
18963
18963
|
}
|
|
18964
18964
|
var init_mcp_sync = __esm({
|
|
18965
18965
|
"src/lib/environment/sync/mcp-sync.ts"() {
|
|
@@ -25235,8 +25235,8 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
25235
25235
|
import yaml12 from "js-yaml";
|
|
25236
25236
|
import semver from "semver";
|
|
25237
25237
|
function relayCoreVersion() {
|
|
25238
|
-
if (semver.valid("0.
|
|
25239
|
-
return "0.
|
|
25238
|
+
if (semver.valid("0.16.0")) {
|
|
25239
|
+
return "0.16.0";
|
|
25240
25240
|
}
|
|
25241
25241
|
try {
|
|
25242
25242
|
const root = getAppRoot(import.meta.dirname, 3);
|
|
@@ -25606,14 +25606,14 @@ var init_cli = __esm({
|
|
|
25606
25606
|
|
|
25607
25607
|
// bin/cli.ts
|
|
25608
25608
|
import { program } from "commander";
|
|
25609
|
-
import { basename as
|
|
25609
|
+
import { basename as basename6, dirname as dirname5, join as join21 } from "path";
|
|
25610
25610
|
import { homedir as homedir8 } from "os";
|
|
25611
|
-
import { fileURLToPath as
|
|
25611
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
25612
25612
|
import {
|
|
25613
|
-
mkdirSync as
|
|
25614
|
-
existsSync as
|
|
25615
|
-
readFileSync as
|
|
25616
|
-
writeFileSync as
|
|
25613
|
+
mkdirSync as mkdirSync6,
|
|
25614
|
+
existsSync as existsSync13,
|
|
25615
|
+
readFileSync as readFileSync9,
|
|
25616
|
+
writeFileSync as writeFileSync6,
|
|
25617
25617
|
cpSync as cpSync2,
|
|
25618
25618
|
unlinkSync as unlinkSync2
|
|
25619
25619
|
} from "fs";
|
|
@@ -25685,19 +25685,249 @@ function isNonLoopbackHost(host) {
|
|
|
25685
25685
|
return true;
|
|
25686
25686
|
}
|
|
25687
25687
|
|
|
25688
|
+
// src/lib/desktop/prebuilt-download.ts
|
|
25689
|
+
import { createHash } from "crypto";
|
|
25690
|
+
import {
|
|
25691
|
+
copyFileSync,
|
|
25692
|
+
createWriteStream,
|
|
25693
|
+
createReadStream,
|
|
25694
|
+
existsSync as existsSync2,
|
|
25695
|
+
mkdirSync,
|
|
25696
|
+
readdirSync,
|
|
25697
|
+
readFileSync,
|
|
25698
|
+
rmSync,
|
|
25699
|
+
statSync,
|
|
25700
|
+
symlinkSync,
|
|
25701
|
+
writeFileSync
|
|
25702
|
+
} from "fs";
|
|
25703
|
+
import { basename, join as join2, relative } from "path";
|
|
25704
|
+
import { Readable } from "stream";
|
|
25705
|
+
import { pipeline } from "stream/promises";
|
|
25706
|
+
import { fileURLToPath } from "url";
|
|
25707
|
+
import * as tar from "tar";
|
|
25708
|
+
var PrebuiltDownloadError = class extends Error {
|
|
25709
|
+
constructor(message, options) {
|
|
25710
|
+
super(message, options);
|
|
25711
|
+
this.name = "PrebuiltDownloadError";
|
|
25712
|
+
}
|
|
25713
|
+
};
|
|
25714
|
+
var RELEASE_DOWNLOAD_BASE = "https://github.com/orionfold/relay/releases/download";
|
|
25715
|
+
function artifactFileName(version) {
|
|
25716
|
+
return `relay-next-build-${version}.tgz`;
|
|
25717
|
+
}
|
|
25718
|
+
function buildArtifactUrl(version, override) {
|
|
25719
|
+
if (override && override.trim()) {
|
|
25720
|
+
return override.trim();
|
|
25721
|
+
}
|
|
25722
|
+
return `${RELEASE_DOWNLOAD_BASE}/v${version}/${artifactFileName(version)}`;
|
|
25723
|
+
}
|
|
25724
|
+
function artifactCachePaths(buildsDir, version) {
|
|
25725
|
+
const tgz = join2(buildsDir, artifactFileName(version));
|
|
25726
|
+
return { tgz, sha: `${tgz}.sha256` };
|
|
25727
|
+
}
|
|
25728
|
+
function parseSha256File(text2) {
|
|
25729
|
+
const match = text2.match(/\b[0-9a-f]{64}\b/i);
|
|
25730
|
+
if (!match) {
|
|
25731
|
+
throw new PrebuiltDownloadError(
|
|
25732
|
+
`Checksum file did not contain a sha256 digest: "${text2.slice(0, 80)}"`
|
|
25733
|
+
);
|
|
25734
|
+
}
|
|
25735
|
+
return match[0].toLowerCase();
|
|
25736
|
+
}
|
|
25737
|
+
async function sha256OfFile(filePath) {
|
|
25738
|
+
const hash = createHash("sha256");
|
|
25739
|
+
await pipeline(createReadStream(filePath), hash);
|
|
25740
|
+
return hash.digest("hex");
|
|
25741
|
+
}
|
|
25742
|
+
async function downloadToFile(url, destPath) {
|
|
25743
|
+
let parsed;
|
|
25744
|
+
try {
|
|
25745
|
+
parsed = new URL(url);
|
|
25746
|
+
} catch (cause) {
|
|
25747
|
+
throw new PrebuiltDownloadError(`Invalid artifact URL: ${url}`, { cause });
|
|
25748
|
+
}
|
|
25749
|
+
if (parsed.protocol === "file:") {
|
|
25750
|
+
const sourcePath = fileURLToPath(parsed);
|
|
25751
|
+
if (!existsSync2(sourcePath)) {
|
|
25752
|
+
throw new PrebuiltDownloadError(`Artifact not found at ${sourcePath}`);
|
|
25753
|
+
}
|
|
25754
|
+
copyFileSync(sourcePath, destPath);
|
|
25755
|
+
return;
|
|
25756
|
+
}
|
|
25757
|
+
let response;
|
|
25758
|
+
try {
|
|
25759
|
+
response = await fetch(url, { redirect: "follow" });
|
|
25760
|
+
} catch (cause) {
|
|
25761
|
+
throw new PrebuiltDownloadError(
|
|
25762
|
+
`Network error downloading ${url}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
25763
|
+
{ cause }
|
|
25764
|
+
);
|
|
25765
|
+
}
|
|
25766
|
+
if (!response.ok || !response.body) {
|
|
25767
|
+
throw new PrebuiltDownloadError(
|
|
25768
|
+
`Download of ${url} failed with HTTP ${response.status} ${response.statusText}`
|
|
25769
|
+
);
|
|
25770
|
+
}
|
|
25771
|
+
try {
|
|
25772
|
+
await pipeline(
|
|
25773
|
+
Readable.fromWeb(response.body),
|
|
25774
|
+
createWriteStream(destPath)
|
|
25775
|
+
);
|
|
25776
|
+
} catch (cause) {
|
|
25777
|
+
rmSync(destPath, { force: true });
|
|
25778
|
+
throw new PrebuiltDownloadError(
|
|
25779
|
+
`Failed writing artifact to ${destPath}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
25780
|
+
{ cause }
|
|
25781
|
+
);
|
|
25782
|
+
}
|
|
25783
|
+
}
|
|
25784
|
+
async function extractPrebuilt(tgzPath, destDir) {
|
|
25785
|
+
try {
|
|
25786
|
+
await tar.extract({ file: tgzPath, cwd: destDir, strict: true });
|
|
25787
|
+
} catch (cause) {
|
|
25788
|
+
throw new PrebuiltDownloadError(
|
|
25789
|
+
`Failed extracting ${basename(tgzPath)}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
25790
|
+
{ cause }
|
|
25791
|
+
);
|
|
25792
|
+
}
|
|
25793
|
+
if (!existsSync2(join2(destDir, ".next", "BUILD_ID"))) {
|
|
25794
|
+
throw new PrebuiltDownloadError(
|
|
25795
|
+
`Artifact ${basename(tgzPath)} extracted but contains no .next/BUILD_ID \u2014 not a valid prebuilt bundle.`
|
|
25796
|
+
);
|
|
25797
|
+
}
|
|
25798
|
+
relinkExternalPackages(destDir);
|
|
25799
|
+
}
|
|
25800
|
+
function relinkExternalPackages(destDir) {
|
|
25801
|
+
const manifestPath = join2(destDir, ".next", "relay-external-packages.json");
|
|
25802
|
+
if (!existsSync2(manifestPath)) {
|
|
25803
|
+
return;
|
|
25804
|
+
}
|
|
25805
|
+
let links;
|
|
25806
|
+
try {
|
|
25807
|
+
links = JSON.parse(readFileSync(manifestPath, "utf-8")).links ?? {};
|
|
25808
|
+
} catch (cause) {
|
|
25809
|
+
throw new PrebuiltDownloadError(
|
|
25810
|
+
`Artifact manifest ${manifestPath} is not valid JSON.`,
|
|
25811
|
+
{ cause }
|
|
25812
|
+
);
|
|
25813
|
+
}
|
|
25814
|
+
const linksDir = join2(destDir, ".next", "node_modules");
|
|
25815
|
+
mkdirSync(linksDir, { recursive: true });
|
|
25816
|
+
for (const [hashedName, packagePath] of Object.entries(links)) {
|
|
25817
|
+
const target = join2(destDir, "node_modules", packagePath);
|
|
25818
|
+
if (!existsSync2(target)) {
|
|
25819
|
+
throw new PrebuiltDownloadError(
|
|
25820
|
+
`Prebuilt server expects package "${packagePath}" (as ${hashedName}) but it is not installed at ${target}. The npm install may be incomplete \u2014 reinstall and retry.`
|
|
25821
|
+
);
|
|
25822
|
+
}
|
|
25823
|
+
const linkPath = join2(linksDir, hashedName);
|
|
25824
|
+
rmSync(linkPath, { recursive: true, force: true });
|
|
25825
|
+
try {
|
|
25826
|
+
if (process.platform === "win32") {
|
|
25827
|
+
symlinkSync(target, linkPath, "junction");
|
|
25828
|
+
} else {
|
|
25829
|
+
symlinkSync(relative(linksDir, target), linkPath);
|
|
25830
|
+
}
|
|
25831
|
+
} catch (cause) {
|
|
25832
|
+
throw new PrebuiltDownloadError(
|
|
25833
|
+
`Could not link ${hashedName} \u2192 ${target}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
25834
|
+
{ cause }
|
|
25835
|
+
);
|
|
25836
|
+
}
|
|
25837
|
+
}
|
|
25838
|
+
}
|
|
25839
|
+
function pruneBuildCache(buildsDir, currentVersion, keep = 2) {
|
|
25840
|
+
let entries;
|
|
25841
|
+
try {
|
|
25842
|
+
entries = readdirSync(buildsDir).filter(
|
|
25843
|
+
(name) => /^relay-next-build-.+\.tgz$/.test(name)
|
|
25844
|
+
);
|
|
25845
|
+
} catch {
|
|
25846
|
+
return;
|
|
25847
|
+
}
|
|
25848
|
+
const current = artifactFileName(currentVersion);
|
|
25849
|
+
const others = entries.filter((name) => name !== current).map((name) => {
|
|
25850
|
+
const filePath = join2(buildsDir, name);
|
|
25851
|
+
let mtime = 0;
|
|
25852
|
+
try {
|
|
25853
|
+
mtime = statSync(filePath).mtimeMs;
|
|
25854
|
+
} catch {
|
|
25855
|
+
}
|
|
25856
|
+
return { name, filePath, mtime };
|
|
25857
|
+
}).sort((a, b) => b.mtime - a.mtime);
|
|
25858
|
+
const keepOthers = entries.includes(current) ? keep - 1 : keep;
|
|
25859
|
+
for (const stale of others.slice(Math.max(keepOthers, 0))) {
|
|
25860
|
+
rmSync(stale.filePath, { force: true });
|
|
25861
|
+
rmSync(`${stale.filePath}.sha256`, { force: true });
|
|
25862
|
+
}
|
|
25863
|
+
}
|
|
25864
|
+
async function ensurePrebuilt({
|
|
25865
|
+
version,
|
|
25866
|
+
effectiveCwd,
|
|
25867
|
+
buildsDir,
|
|
25868
|
+
artifactUrlOverride,
|
|
25869
|
+
log
|
|
25870
|
+
}) {
|
|
25871
|
+
if (existsSync2(join2(effectiveCwd, ".next", "BUILD_ID"))) {
|
|
25872
|
+
return "already-present";
|
|
25873
|
+
}
|
|
25874
|
+
mkdirSync(buildsDir, { recursive: true });
|
|
25875
|
+
const cache = artifactCachePaths(buildsDir, version);
|
|
25876
|
+
if (existsSync2(cache.tgz) && existsSync2(cache.sha)) {
|
|
25877
|
+
log(`Using cached production build for ${version} (${cache.tgz}).`);
|
|
25878
|
+
await verifyChecksum(cache.tgz, readFileSync(cache.sha, "utf-8"));
|
|
25879
|
+
await extractPrebuilt(cache.tgz, effectiveCwd);
|
|
25880
|
+
return "from-cache";
|
|
25881
|
+
}
|
|
25882
|
+
const url = buildArtifactUrl(version, artifactUrlOverride);
|
|
25883
|
+
log(`Downloading production build for ${version} (~40 MB) from ${url} ...`);
|
|
25884
|
+
try {
|
|
25885
|
+
await downloadToFile(url, cache.tgz);
|
|
25886
|
+
const shaText = await fetchChecksumText(`${url}.sha256`, buildsDir);
|
|
25887
|
+
writeFileSync(cache.sha, shaText, "utf-8");
|
|
25888
|
+
await verifyChecksum(cache.tgz, shaText);
|
|
25889
|
+
await extractPrebuilt(cache.tgz, effectiveCwd);
|
|
25890
|
+
} catch (error) {
|
|
25891
|
+
rmSync(cache.tgz, { force: true });
|
|
25892
|
+
rmSync(cache.sha, { force: true });
|
|
25893
|
+
throw error;
|
|
25894
|
+
}
|
|
25895
|
+
log(`Production build ready (cached at ${cache.tgz}).`);
|
|
25896
|
+
pruneBuildCache(buildsDir, version);
|
|
25897
|
+
return "downloaded";
|
|
25898
|
+
}
|
|
25899
|
+
async function fetchChecksumText(shaUrl, buildsDir) {
|
|
25900
|
+
const tempPath = join2(buildsDir, `.sha-download-${process.pid}`);
|
|
25901
|
+
try {
|
|
25902
|
+
await downloadToFile(shaUrl, tempPath);
|
|
25903
|
+
return readFileSync(tempPath, "utf-8");
|
|
25904
|
+
} finally {
|
|
25905
|
+
rmSync(tempPath, { force: true });
|
|
25906
|
+
}
|
|
25907
|
+
}
|
|
25908
|
+
async function verifyChecksum(tgzPath, shaFileText) {
|
|
25909
|
+
const expected = parseSha256File(shaFileText);
|
|
25910
|
+
const actual = await sha256OfFile(tgzPath);
|
|
25911
|
+
if (actual !== expected) {
|
|
25912
|
+
throw new PrebuiltDownloadError(
|
|
25913
|
+
`Checksum mismatch for ${basename(tgzPath)}: expected ${expected}, got ${actual}. The download may be corrupt or tampered with.`
|
|
25914
|
+
);
|
|
25915
|
+
}
|
|
25916
|
+
}
|
|
25917
|
+
|
|
25688
25918
|
// bin/cli.ts
|
|
25689
25919
|
init_ainative_paths();
|
|
25690
25920
|
init_bootstrap();
|
|
25691
25921
|
|
|
25692
25922
|
// src/lib/utils/migrate-to-ainative.ts
|
|
25693
|
-
import { existsSync as
|
|
25694
|
-
import { join as
|
|
25923
|
+
import { existsSync as existsSync4, renameSync, cpSync, rmSync as rmSync2, readFileSync as readFileSync3 } from "fs";
|
|
25924
|
+
import { join as join6 } from "path";
|
|
25695
25925
|
import { homedir as homedir2 } from "os";
|
|
25696
25926
|
import Database from "better-sqlite3";
|
|
25697
25927
|
function hasSqliteHeader(path19) {
|
|
25698
25928
|
const SQLITE_MAGIC = "SQLite format 3\0";
|
|
25699
25929
|
try {
|
|
25700
|
-
const header =
|
|
25930
|
+
const header = readFileSync3(path19, { encoding: null });
|
|
25701
25931
|
return header.length >= 16 && header.subarray(0, 16).toString("binary") === SQLITE_MAGIC;
|
|
25702
25932
|
} catch {
|
|
25703
25933
|
return false;
|
|
@@ -25705,7 +25935,7 @@ function hasSqliteHeader(path19) {
|
|
|
25705
25935
|
}
|
|
25706
25936
|
async function migrateLegacyData(options = {}) {
|
|
25707
25937
|
const home = options.home ?? homedir2();
|
|
25708
|
-
const gitDir = options.gitDir ??
|
|
25938
|
+
const gitDir = options.gitDir ?? join6(process.cwd(), ".git");
|
|
25709
25939
|
const log = options.logger ?? ((m) => console.log(`[migrate] ${m}`));
|
|
25710
25940
|
const report = {
|
|
25711
25941
|
dirMigrated: false,
|
|
@@ -25715,9 +25945,9 @@ async function migrateLegacyData(options = {}) {
|
|
|
25715
25945
|
keychainMigrated: false,
|
|
25716
25946
|
errors: []
|
|
25717
25947
|
};
|
|
25718
|
-
const oldDir =
|
|
25719
|
-
const newDir =
|
|
25720
|
-
if (
|
|
25948
|
+
const oldDir = join6(home, ".stagent");
|
|
25949
|
+
const newDir = join6(home, ".ainative");
|
|
25950
|
+
if (existsSync4(oldDir) && !existsSync4(newDir)) {
|
|
25721
25951
|
try {
|
|
25722
25952
|
renameSync(oldDir, newDir);
|
|
25723
25953
|
report.dirMigrated = true;
|
|
@@ -25727,7 +25957,7 @@ async function migrateLegacyData(options = {}) {
|
|
|
25727
25957
|
if (e.code === "EXDEV") {
|
|
25728
25958
|
try {
|
|
25729
25959
|
cpSync(oldDir, newDir, { recursive: true });
|
|
25730
|
-
|
|
25960
|
+
rmSync2(oldDir, { recursive: true, force: true });
|
|
25731
25961
|
report.dirMigrated = true;
|
|
25732
25962
|
log(`copied ${oldDir} -> ${newDir} (cross-device fallback)`);
|
|
25733
25963
|
} catch (copyErr) {
|
|
@@ -25740,11 +25970,11 @@ async function migrateLegacyData(options = {}) {
|
|
|
25740
25970
|
}
|
|
25741
25971
|
}
|
|
25742
25972
|
}
|
|
25743
|
-
if (
|
|
25973
|
+
if (existsSync4(newDir)) {
|
|
25744
25974
|
for (const suffix of ["", "-shm", "-wal"]) {
|
|
25745
|
-
const oldName =
|
|
25746
|
-
const newName =
|
|
25747
|
-
if (
|
|
25975
|
+
const oldName = join6(newDir, `stagent.db${suffix}`);
|
|
25976
|
+
const newName = join6(newDir, `ainative.db${suffix}`);
|
|
25977
|
+
if (existsSync4(oldName) && !existsSync4(newName)) {
|
|
25748
25978
|
try {
|
|
25749
25979
|
renameSync(oldName, newName);
|
|
25750
25980
|
report.dbFilesRenamed++;
|
|
@@ -25754,11 +25984,11 @@ async function migrateLegacyData(options = {}) {
|
|
|
25754
25984
|
}
|
|
25755
25985
|
}
|
|
25756
25986
|
}
|
|
25757
|
-
const dbPath4 =
|
|
25758
|
-
if (
|
|
25987
|
+
const dbPath4 = join6(newDir, "ainative.db");
|
|
25988
|
+
if (existsSync4(dbPath4) && !hasSqliteHeader(dbPath4)) {
|
|
25759
25989
|
log(`skipping SQL migration \u2014 ${dbPath4} exists but lacks SQLite header`);
|
|
25760
25990
|
}
|
|
25761
|
-
if (
|
|
25991
|
+
if (existsSync4(dbPath4) && hasSqliteHeader(dbPath4)) {
|
|
25762
25992
|
try {
|
|
25763
25993
|
const db3 = new Database(dbPath4);
|
|
25764
25994
|
try {
|
|
@@ -25789,10 +26019,10 @@ async function migrateLegacyData(options = {}) {
|
|
|
25789
26019
|
report.errors.push(`SQL migration failed: ${String(err2)}`);
|
|
25790
26020
|
}
|
|
25791
26021
|
}
|
|
25792
|
-
if (
|
|
25793
|
-
const oldSentinel =
|
|
25794
|
-
const newSentinel =
|
|
25795
|
-
if (
|
|
26022
|
+
if (existsSync4(gitDir)) {
|
|
26023
|
+
const oldSentinel = join6(gitDir, "stagent-dev-mode");
|
|
26024
|
+
const newSentinel = join6(gitDir, "ainative-dev-mode");
|
|
26025
|
+
if (existsSync4(oldSentinel) && !existsSync4(newSentinel)) {
|
|
25796
26026
|
try {
|
|
25797
26027
|
renameSync(oldSentinel, newSentinel);
|
|
25798
26028
|
report.sentinelRenamed = true;
|
|
@@ -25819,16 +26049,16 @@ async function migrateLegacyData(options = {}) {
|
|
|
25819
26049
|
|
|
25820
26050
|
// bin/cli.ts
|
|
25821
26051
|
init_detect();
|
|
25822
|
-
var __dirname = dirname5(
|
|
25823
|
-
var appDir =
|
|
26052
|
+
var __dirname = dirname5(fileURLToPath4(import.meta.url));
|
|
26053
|
+
var appDir = join21(__dirname, "..");
|
|
25824
26054
|
var launchCwd2 = process.cwd();
|
|
25825
|
-
var _envLocalPath =
|
|
25826
|
-
var _firstRunNeedsEnv = !
|
|
26055
|
+
var _envLocalPath = join21(launchCwd2, ".env.local");
|
|
26056
|
+
var _firstRunNeedsEnv = !existsSync13(_envLocalPath) && !process.env.RELAY_DATA_DIR && !isDevMode(launchCwd2);
|
|
25827
26057
|
if (_firstRunNeedsEnv) {
|
|
25828
|
-
const folderName =
|
|
25829
|
-
const autoDataDir =
|
|
26058
|
+
const folderName = basename6(launchCwd2);
|
|
26059
|
+
const autoDataDir = join21(homedir8(), `.${folderName}`);
|
|
25830
26060
|
try {
|
|
25831
|
-
|
|
26061
|
+
writeFileSync6(
|
|
25832
26062
|
_envLocalPath,
|
|
25833
26063
|
`# Auto-created by orionfold-relay on first run.
|
|
25834
26064
|
# Points this folder's install at an isolated data directory.
|
|
@@ -25850,8 +26080,8 @@ Continuing with the default data directory (~/.relay). This folder will not get
|
|
|
25850
26080
|
}
|
|
25851
26081
|
}
|
|
25852
26082
|
}
|
|
25853
|
-
if (
|
|
25854
|
-
for (const line of
|
|
26083
|
+
if (existsSync13(_envLocalPath)) {
|
|
26084
|
+
for (const line of readFileSync9(_envLocalPath, "utf-8").split("\n")) {
|
|
25855
26085
|
const trimmed = line.trim();
|
|
25856
26086
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
25857
26087
|
const eqIdx = trimmed.indexOf("=");
|
|
@@ -25863,7 +26093,7 @@ if (existsSync12(_envLocalPath)) {
|
|
|
25863
26093
|
}
|
|
25864
26094
|
}
|
|
25865
26095
|
}
|
|
25866
|
-
var pkg = JSON.parse(
|
|
26096
|
+
var pkg = JSON.parse(readFileSync9(join21(appDir, "package.json"), "utf-8"));
|
|
25867
26097
|
function getHelpText() {
|
|
25868
26098
|
const dir = getAinativeDataDir();
|
|
25869
26099
|
const db3 = getAinativeDbPath();
|
|
@@ -25871,8 +26101,8 @@ function getHelpText() {
|
|
|
25871
26101
|
Data:
|
|
25872
26102
|
Directory ${dir}
|
|
25873
26103
|
Database ${db3}
|
|
25874
|
-
Sessions ${
|
|
25875
|
-
Logs ${
|
|
26104
|
+
Sessions ${join21(dir, "sessions")}
|
|
26105
|
+
Logs ${join21(dir, "logs")}
|
|
25876
26106
|
|
|
25877
26107
|
Environment variables:
|
|
25878
26108
|
RELAY_DATA_DIR Custom data directory for the web app
|
|
@@ -25938,15 +26168,15 @@ var requestedPort = Number.parseInt(opts.port, 10);
|
|
|
25938
26168
|
if (Number.isNaN(requestedPort) || requestedPort <= 0) {
|
|
25939
26169
|
program.error(`Invalid port: ${opts.port}`);
|
|
25940
26170
|
}
|
|
25941
|
-
for (const dir of [DATA_DIR,
|
|
25942
|
-
|
|
26171
|
+
for (const dir of [DATA_DIR, join21(DATA_DIR, "logs"), join21(DATA_DIR, "sessions")]) {
|
|
26172
|
+
mkdirSync6(dir, { recursive: true });
|
|
25943
26173
|
}
|
|
25944
26174
|
if (opts.reset) {
|
|
25945
|
-
if (
|
|
26175
|
+
if (existsSync13(dbPath3)) {
|
|
25946
26176
|
unlinkSync2(dbPath3);
|
|
25947
26177
|
for (const suffix of ["-wal", "-shm"]) {
|
|
25948
26178
|
const filePath = dbPath3 + suffix;
|
|
25949
|
-
if (
|
|
26179
|
+
if (existsSync13(filePath)) unlinkSync2(filePath);
|
|
25950
26180
|
}
|
|
25951
26181
|
console.log("Database reset.");
|
|
25952
26182
|
} else {
|
|
@@ -25956,7 +26186,7 @@ if (opts.reset) {
|
|
|
25956
26186
|
var sqlite2 = new Database3(dbPath3);
|
|
25957
26187
|
sqlite2.pragma("journal_mode = WAL");
|
|
25958
26188
|
sqlite2.pragma("foreign_keys = ON");
|
|
25959
|
-
var migrationsDir =
|
|
26189
|
+
var migrationsDir = join21(appDir, "src", "lib", "db", "migrations");
|
|
25960
26190
|
var db2 = drizzle2(sqlite2);
|
|
25961
26191
|
var needsLegacyRecovery = hasLegacyTables(sqlite2) && !hasMigrationHistory(sqlite2);
|
|
25962
26192
|
if (needsLegacyRecovery) {
|
|
@@ -25987,17 +26217,17 @@ async function main() {
|
|
|
25987
26217
|
findAvailablePort
|
|
25988
26218
|
});
|
|
25989
26219
|
let effectiveCwd = appDir;
|
|
25990
|
-
const localNm =
|
|
25991
|
-
if (!
|
|
26220
|
+
const localNm = join21(appDir, "node_modules");
|
|
26221
|
+
if (!existsSync13(join21(localNm, "next", "package.json"))) {
|
|
25992
26222
|
let searchDir = dirname5(appDir);
|
|
25993
26223
|
while (searchDir !== dirname5(searchDir)) {
|
|
25994
|
-
const candidate =
|
|
25995
|
-
if (
|
|
26224
|
+
const candidate = join21(searchDir, "node_modules", "next", "package.json");
|
|
26225
|
+
if (existsSync13(candidate)) {
|
|
25996
26226
|
const hoistedRoot = searchDir;
|
|
25997
26227
|
for (const name of ["src", "public"]) {
|
|
25998
|
-
const dest =
|
|
25999
|
-
const src =
|
|
26000
|
-
if (!
|
|
26228
|
+
const dest = join21(hoistedRoot, name);
|
|
26229
|
+
const src = join21(appDir, name);
|
|
26230
|
+
if (!existsSync13(dest) && existsSync13(src)) {
|
|
26001
26231
|
cpSync2(src, dest, { recursive: true });
|
|
26002
26232
|
}
|
|
26003
26233
|
}
|
|
@@ -26009,10 +26239,10 @@ async function main() {
|
|
|
26009
26239
|
"components.json",
|
|
26010
26240
|
"drizzle.config.ts"
|
|
26011
26241
|
]) {
|
|
26012
|
-
const dest =
|
|
26013
|
-
const src =
|
|
26014
|
-
if (!
|
|
26015
|
-
|
|
26242
|
+
const dest = join21(hoistedRoot, name);
|
|
26243
|
+
const src = join21(appDir, name);
|
|
26244
|
+
if (!existsSync13(dest) && existsSync13(src)) {
|
|
26245
|
+
writeFileSync6(dest, readFileSync9(src));
|
|
26016
26246
|
}
|
|
26017
26247
|
}
|
|
26018
26248
|
effectiveCwd = hoistedRoot;
|
|
@@ -26021,8 +26251,25 @@ async function main() {
|
|
|
26021
26251
|
searchDir = dirname5(searchDir);
|
|
26022
26252
|
}
|
|
26023
26253
|
}
|
|
26254
|
+
if (!existsSync13(join21(effectiveCwd, ".next", "BUILD_ID")) && !isDevMode(launchCwd2)) {
|
|
26255
|
+
try {
|
|
26256
|
+
await ensurePrebuilt({
|
|
26257
|
+
version: pkg.version,
|
|
26258
|
+
effectiveCwd,
|
|
26259
|
+
buildsDir: join21(DATA_DIR, "builds"),
|
|
26260
|
+
artifactUrlOverride: process.env.RELAY_BUILD_ARTIFACT_URL,
|
|
26261
|
+
log: (message) => console.log(message)
|
|
26262
|
+
});
|
|
26263
|
+
} catch (e) {
|
|
26264
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
26265
|
+
console.warn(
|
|
26266
|
+
`\u26A0 Could not set up the production build (${reason}).
|
|
26267
|
+
Falling back to development mode for this run \u2014 Relay still works, but slower and with dev-mode console noise. Check your network (the build downloads once per version from GitHub Releases) and re-run, or set RELAY_BUILD_ARTIFACT_URL to a mirror.`
|
|
26268
|
+
);
|
|
26269
|
+
}
|
|
26270
|
+
}
|
|
26024
26271
|
const nextEntrypoint = resolveNextEntrypoint(effectiveCwd);
|
|
26025
|
-
const isPrebuilt =
|
|
26272
|
+
const isPrebuilt = existsSync13(join21(effectiveCwd, ".next", "BUILD_ID"));
|
|
26026
26273
|
const bindHost = opts.hostname || "127.0.0.1";
|
|
26027
26274
|
if (isNonLoopbackHost(bindHost)) {
|
|
26028
26275
|
console.warn(
|
|
@@ -26049,7 +26296,13 @@ async function main() {
|
|
|
26049
26296
|
RELAY_DATA_DIR: DATA_DIR,
|
|
26050
26297
|
RELAY_LAUNCH_CWD: launchCwd2,
|
|
26051
26298
|
PORT: String(actualPort),
|
|
26052
|
-
...opts.safeMode ? { RELAY_SAFE_MODE: "true" } : {}
|
|
26299
|
+
...opts.safeMode ? { RELAY_SAFE_MODE: "true" } : {},
|
|
26300
|
+
// In dev mode, Next blocks cross-origin /_next/* dev-asset requests from
|
|
26301
|
+
// the LAN client's IP, breaking the app over the network (issue #13).
|
|
26302
|
+
// When the operator has opted into non-loopback binding, tell next.config
|
|
26303
|
+
// to allow any dev origin. Mirrors the same trust decision as the warning
|
|
26304
|
+
// above; harmless for the prebuilt `next start` path (no dev-origin gate).
|
|
26305
|
+
...isNonLoopbackHost(bindHost) ? { RELAY_ALLOW_LAN_ORIGINS: "true" } : {}
|
|
26053
26306
|
}
|
|
26054
26307
|
});
|
|
26055
26308
|
if (opts.open !== false) {
|