openmates 0.27.0-alpha.22 → 0.27.0-alpha.24
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/{chunk-XVGLSNRM.js → chunk-U5L7EZHI.js} +350 -169
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/manifest.json +9 -9
- package/package.json +4 -3
|
@@ -692,7 +692,7 @@ async function readCodexThread(threadId, socketPath) {
|
|
|
692
692
|
codexResumeArguments({ provider: "codex", id: threadId });
|
|
693
693
|
const socket = socketPath ?? await daemonSocket();
|
|
694
694
|
if (!isAbsolute(socket) || socket.includes(":")) throw new Error("Codex requires an absolute local socket path.");
|
|
695
|
-
return new Promise((
|
|
695
|
+
return new Promise((resolve18, reject) => {
|
|
696
696
|
const ws = new WebSocket(`ws+unix://${socket}:/`, {
|
|
697
697
|
perMessageDeflate: false,
|
|
698
698
|
handshakeTimeout: CONNECTION_TIMEOUT_MS,
|
|
@@ -706,7 +706,7 @@ async function readCodexThread(threadId, socketPath) {
|
|
|
706
706
|
if (ws.readyState === WebSocket.OPEN) ws.close();
|
|
707
707
|
else if (ws.readyState !== WebSocket.CLOSED) ws.terminate();
|
|
708
708
|
if (error) reject(error);
|
|
709
|
-
else
|
|
709
|
+
else resolve18(value);
|
|
710
710
|
};
|
|
711
711
|
const timer = setTimeout(() => finish(new Error("Codex connection timed out.")), CONNECTION_TIMEOUT_MS);
|
|
712
712
|
ws.on("error", () => finish(new Error("Could not connect to the local Codex daemon.")));
|
|
@@ -747,10 +747,10 @@ async function resumeCodexTask(context) {
|
|
|
747
747
|
const args = codexResumeArguments(context);
|
|
748
748
|
if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error("Task resume requires an interactive terminal; status and connect never launch work.");
|
|
749
749
|
await readCodexThread(context.id);
|
|
750
|
-
await new Promise((
|
|
750
|
+
await new Promise((resolve18, reject) => {
|
|
751
751
|
const child = spawn("codex", args, { stdio: "inherit" });
|
|
752
752
|
child.once("error", () => reject(new Error("Could not open the installed Codex CLI.")));
|
|
753
|
-
child.once("exit", (code) => code === 0 ?
|
|
753
|
+
child.once("exit", (code) => code === 0 ? resolve18() : reject(new Error(`Codex resume exited with status ${code ?? "interrupted"}.`)));
|
|
754
754
|
});
|
|
755
755
|
}
|
|
756
756
|
function taskOwnerConflict(owner) {
|
|
@@ -4996,14 +4996,14 @@ var OpenMatesWsClient = class {
|
|
|
4996
4996
|
});
|
|
4997
4997
|
}
|
|
4998
4998
|
async open(timeoutMs = 1e4) {
|
|
4999
|
-
await new Promise((
|
|
4999
|
+
await new Promise((resolve18, reject) => {
|
|
5000
5000
|
const timeout = setTimeout(
|
|
5001
5001
|
() => reject(new Error("WebSocket open timeout")),
|
|
5002
5002
|
timeoutMs
|
|
5003
5003
|
);
|
|
5004
5004
|
this.socket.once("open", () => {
|
|
5005
5005
|
clearTimeout(timeout);
|
|
5006
|
-
|
|
5006
|
+
resolve18();
|
|
5007
5007
|
});
|
|
5008
5008
|
this.socket.once("error", (error) => {
|
|
5009
5009
|
clearTimeout(timeout);
|
|
@@ -5068,10 +5068,10 @@ var OpenMatesWsClient = class {
|
|
|
5068
5068
|
}
|
|
5069
5069
|
}
|
|
5070
5070
|
sendAsync(type, payload) {
|
|
5071
|
-
return new Promise((
|
|
5071
|
+
return new Promise((resolve18, reject) => {
|
|
5072
5072
|
this.socket.send(JSON.stringify({ type, payload }), (error) => {
|
|
5073
5073
|
if (error) reject(error);
|
|
5074
|
-
else
|
|
5074
|
+
else resolve18();
|
|
5075
5075
|
});
|
|
5076
5076
|
});
|
|
5077
5077
|
}
|
|
@@ -5139,9 +5139,9 @@ var OpenMatesWsClient = class {
|
|
|
5139
5139
|
return () => this.socket.off("message", onMessage);
|
|
5140
5140
|
}
|
|
5141
5141
|
waitForClose() {
|
|
5142
|
-
return new Promise((
|
|
5142
|
+
return new Promise((resolve18) => {
|
|
5143
5143
|
this.socket.once("close", (code, reason) => {
|
|
5144
|
-
|
|
5144
|
+
resolve18({ code, reason: reason.toString("utf-8") });
|
|
5145
5145
|
});
|
|
5146
5146
|
});
|
|
5147
5147
|
}
|
|
@@ -5236,7 +5236,7 @@ var OpenMatesWsClient = class {
|
|
|
5236
5236
|
if (this.recoveryOutputDiscoveryError) throw this.recoveryOutputDiscoveryError;
|
|
5237
5237
|
}
|
|
5238
5238
|
waitForMessage(expectedType, predicate, timeoutMs = 2e4) {
|
|
5239
|
-
return new Promise((
|
|
5239
|
+
return new Promise((resolve18, reject) => {
|
|
5240
5240
|
const seenTypes = /* @__PURE__ */ new Set();
|
|
5241
5241
|
let predicateMisses = 0;
|
|
5242
5242
|
const onMessage = (rawData) => {
|
|
@@ -5258,7 +5258,7 @@ var OpenMatesWsClient = class {
|
|
|
5258
5258
|
return;
|
|
5259
5259
|
}
|
|
5260
5260
|
cleanup();
|
|
5261
|
-
|
|
5261
|
+
resolve18(parsed);
|
|
5262
5262
|
} catch {
|
|
5263
5263
|
}
|
|
5264
5264
|
};
|
|
@@ -5296,7 +5296,7 @@ var OpenMatesWsClient = class {
|
|
|
5296
5296
|
* Used by ensureSynced to consume the full phased-sync event stream.
|
|
5297
5297
|
*/
|
|
5298
5298
|
collectMessages(terminatorType, timeoutMs = 9e4) {
|
|
5299
|
-
return new Promise((
|
|
5299
|
+
return new Promise((resolve18, reject) => {
|
|
5300
5300
|
const collected = [];
|
|
5301
5301
|
const onMessage = (rawData) => {
|
|
5302
5302
|
try {
|
|
@@ -5309,7 +5309,7 @@ var OpenMatesWsClient = class {
|
|
|
5309
5309
|
}
|
|
5310
5310
|
if (parsed.type === terminatorType) {
|
|
5311
5311
|
cleanup();
|
|
5312
|
-
|
|
5312
|
+
resolve18(collected);
|
|
5313
5313
|
return;
|
|
5314
5314
|
}
|
|
5315
5315
|
collected.push(parsed);
|
|
@@ -5322,7 +5322,7 @@ var OpenMatesWsClient = class {
|
|
|
5322
5322
|
};
|
|
5323
5323
|
const onClose = () => {
|
|
5324
5324
|
cleanup();
|
|
5325
|
-
|
|
5325
|
+
resolve18(collected);
|
|
5326
5326
|
};
|
|
5327
5327
|
const timeout = setTimeout(() => {
|
|
5328
5328
|
cleanup();
|
|
@@ -5360,7 +5360,7 @@ var OpenMatesWsClient = class {
|
|
|
5360
5360
|
const timeoutMs = options?.timeoutMs ?? 9e4;
|
|
5361
5361
|
const onStream = options?.onStream;
|
|
5362
5362
|
const asyncEmbedWaitMs = options?.asyncEmbedWaitMs ?? DEFAULT_ASYNC_EMBED_WAIT_MS;
|
|
5363
|
-
return new Promise((
|
|
5363
|
+
return new Promise((resolve18, reject) => {
|
|
5364
5364
|
let latestContent = "";
|
|
5365
5365
|
let messageId = null;
|
|
5366
5366
|
let taskId = null;
|
|
@@ -5469,7 +5469,7 @@ var OpenMatesWsClient = class {
|
|
|
5469
5469
|
if (waitingForUserPayload) {
|
|
5470
5470
|
if (pendingSubChatHandlers.size > 0) return;
|
|
5471
5471
|
cleanup();
|
|
5472
|
-
|
|
5472
|
+
resolve18({
|
|
5473
5473
|
status: "waiting_for_user",
|
|
5474
5474
|
messageId,
|
|
5475
5475
|
taskId,
|
|
@@ -5506,7 +5506,7 @@ var OpenMatesWsClient = class {
|
|
|
5506
5506
|
if (processingEmbedIds.size > 0 && !asyncEmbedTimer) {
|
|
5507
5507
|
asyncEmbedTimer = setTimeout(() => {
|
|
5508
5508
|
cleanup();
|
|
5509
|
-
|
|
5509
|
+
resolve18({
|
|
5510
5510
|
status: "completed",
|
|
5511
5511
|
messageId,
|
|
5512
5512
|
taskId,
|
|
@@ -5538,7 +5538,7 @@ var OpenMatesWsClient = class {
|
|
|
5538
5538
|
}
|
|
5539
5539
|
if (processingEmbedIds.size > 0) return;
|
|
5540
5540
|
cleanup();
|
|
5541
|
-
|
|
5541
|
+
resolve18({
|
|
5542
5542
|
status: "completed",
|
|
5543
5543
|
messageId,
|
|
5544
5544
|
taskId,
|
|
@@ -5955,7 +5955,7 @@ var OpenMatesWsClient = class {
|
|
|
5955
5955
|
const onClose = () => {
|
|
5956
5956
|
if (aiResponseDone && pendingProjectOperations.size === 0 && !awaitingUnidentifiedAsyncContinuation) {
|
|
5957
5957
|
cleanup();
|
|
5958
|
-
|
|
5958
|
+
resolve18({
|
|
5959
5959
|
status: "completed",
|
|
5960
5960
|
messageId,
|
|
5961
5961
|
taskId,
|
|
@@ -6493,8 +6493,8 @@ function registerProjectFocusCountdown(options) {
|
|
|
6493
6493
|
const projectId = focusId.slice("project-".length);
|
|
6494
6494
|
let finish = () => {
|
|
6495
6495
|
};
|
|
6496
|
-
const done = new Promise((
|
|
6497
|
-
finish =
|
|
6496
|
+
const done = new Promise((resolve18) => {
|
|
6497
|
+
finish = resolve18;
|
|
6498
6498
|
});
|
|
6499
6499
|
const entry = { requestId, timer: null, cancelled: false, done, finish };
|
|
6500
6500
|
current = entry;
|
|
@@ -8420,7 +8420,7 @@ function validateProtonBridgeCredentials(credentials) {
|
|
|
8420
8420
|
}
|
|
8421
8421
|
async function validateProtonBridgeImap(credentials, timeoutMs = DEFAULT_IMAP_TIMEOUT_MS) {
|
|
8422
8422
|
validateProtonBridgeCredentials(credentials);
|
|
8423
|
-
await new Promise((
|
|
8423
|
+
await new Promise((resolve18, reject) => {
|
|
8424
8424
|
const socket = connectTcp({ host: credentials.imapHost, port: credentials.imapPort });
|
|
8425
8425
|
const timer = setTimeout(() => {
|
|
8426
8426
|
socket.destroy();
|
|
@@ -8429,7 +8429,7 @@ async function validateProtonBridgeImap(credentials, timeoutMs = DEFAULT_IMAP_TI
|
|
|
8429
8429
|
socket.once("connect", () => {
|
|
8430
8430
|
clearTimeout(timer);
|
|
8431
8431
|
socket.end();
|
|
8432
|
-
|
|
8432
|
+
resolve18();
|
|
8433
8433
|
});
|
|
8434
8434
|
socket.once("error", (error) => {
|
|
8435
8435
|
clearTimeout(timer);
|
|
@@ -8606,8 +8606,8 @@ async function localConnectorRequestLoop(client2, params) {
|
|
|
8606
8606
|
const ws = await client2.openLocalConnectorWebSocket();
|
|
8607
8607
|
const sendQueue = new ProtonDelayedSendQueue();
|
|
8608
8608
|
let resolveOnce = null;
|
|
8609
|
-
const onceHandled = new Promise((
|
|
8610
|
-
resolveOnce =
|
|
8609
|
+
const onceHandled = new Promise((resolve18) => {
|
|
8610
|
+
resolveOnce = resolve18;
|
|
8611
8611
|
});
|
|
8612
8612
|
const removeListener = ws.onLocalConnectorRequest((request) => {
|
|
8613
8613
|
void handleLocalConnectorRequest(client2, request, params, sendQueue).finally(() => {
|
|
@@ -8675,8 +8675,8 @@ async function handleLocalConnectorRequest(client2, request, params, sendQueue)
|
|
|
8675
8675
|
}
|
|
8676
8676
|
async function waitForAbort(signal) {
|
|
8677
8677
|
if (signal.aborted) return;
|
|
8678
|
-
await new Promise((
|
|
8679
|
-
signal.addEventListener("abort", () =>
|
|
8678
|
+
await new Promise((resolve18) => {
|
|
8679
|
+
signal.addEventListener("abort", () => resolve18(), { once: true });
|
|
8680
8680
|
});
|
|
8681
8681
|
}
|
|
8682
8682
|
async function searchProtonBridgeImap(credentials, arguments_) {
|
|
@@ -8838,14 +8838,14 @@ async function openTextSocket(host, port, timeoutMs) {
|
|
|
8838
8838
|
socket.on("data", (chunk) => {
|
|
8839
8839
|
buffer += String(chunk);
|
|
8840
8840
|
});
|
|
8841
|
-
await new Promise((
|
|
8841
|
+
await new Promise((resolve18, reject) => {
|
|
8842
8842
|
const timer = setTimeout(() => {
|
|
8843
8843
|
socket.destroy();
|
|
8844
8844
|
reject(new Error(`Timed out connecting to ${host}:${port}.`));
|
|
8845
8845
|
}, timeoutMs);
|
|
8846
8846
|
socket.once("connect", () => {
|
|
8847
8847
|
clearTimeout(timer);
|
|
8848
|
-
|
|
8848
|
+
resolve18();
|
|
8849
8849
|
});
|
|
8850
8850
|
socket.once("error", (error) => {
|
|
8851
8851
|
clearTimeout(timer);
|
|
@@ -8885,11 +8885,11 @@ async function openTextSocket(host, port, timeoutMs) {
|
|
|
8885
8885
|
};
|
|
8886
8886
|
}
|
|
8887
8887
|
async function waitForSocketText(socket, getBuffer, done, timeoutMs) {
|
|
8888
|
-
return await new Promise((
|
|
8888
|
+
return await new Promise((resolve18, reject) => {
|
|
8889
8889
|
const timer = setTimeout(() => cleanup(() => reject(new Error("Timed out waiting for local mail server response."))), timeoutMs);
|
|
8890
8890
|
const check = () => {
|
|
8891
8891
|
const text6 = getBuffer();
|
|
8892
|
-
if (done(text6)) cleanup(() =>
|
|
8892
|
+
if (done(text6)) cleanup(() => resolve18(text6));
|
|
8893
8893
|
};
|
|
8894
8894
|
const onData = () => check();
|
|
8895
8895
|
const onError = (error) => cleanup(() => reject(error));
|
|
@@ -8914,7 +8914,7 @@ function startProtonBridgeProcess(command, args) {
|
|
|
8914
8914
|
if (child.exitCode !== null || child.killed) return;
|
|
8915
8915
|
child.kill("SIGTERM");
|
|
8916
8916
|
await Promise.race([
|
|
8917
|
-
new Promise((
|
|
8917
|
+
new Promise((resolve18) => child.once("exit", () => resolve18())),
|
|
8918
8918
|
sleep(2e3).then(() => {
|
|
8919
8919
|
if (child.exitCode === null && !child.killed) child.kill("SIGKILL");
|
|
8920
8920
|
})
|
|
@@ -9013,7 +9013,7 @@ async function captureOrPromptBridgeCredentials(command, args) {
|
|
|
9013
9013
|
}
|
|
9014
9014
|
}
|
|
9015
9015
|
async function captureProtonBridgeInfo(command, args) {
|
|
9016
|
-
return await new Promise((
|
|
9016
|
+
return await new Promise((resolve18, reject) => {
|
|
9017
9017
|
const child = spawn2(command, args, { stdio: "pipe" });
|
|
9018
9018
|
let output = "";
|
|
9019
9019
|
let errorOutput = "";
|
|
@@ -9033,7 +9033,7 @@ async function captureProtonBridgeInfo(command, args) {
|
|
|
9033
9033
|
});
|
|
9034
9034
|
child.once("exit", () => {
|
|
9035
9035
|
clearTimeout(timer);
|
|
9036
|
-
if (output.trim())
|
|
9036
|
+
if (output.trim()) resolve18(output);
|
|
9037
9037
|
else reject(new Error(redactProtonBridgeSecrets(errorOutput || "Proton Bridge info produced no output.")));
|
|
9038
9038
|
});
|
|
9039
9039
|
child.stdin.write("info\nquit\n");
|
|
@@ -9063,7 +9063,7 @@ async function promptHidden(prompt) {
|
|
|
9063
9063
|
const wasRaw = stdin.isRaw === true;
|
|
9064
9064
|
stdin.setRawMode(true);
|
|
9065
9065
|
stdin.resume();
|
|
9066
|
-
return await new Promise((
|
|
9066
|
+
return await new Promise((resolve18, reject) => {
|
|
9067
9067
|
let value = "";
|
|
9068
9068
|
const onData = (chunk) => {
|
|
9069
9069
|
const text6 = chunk.toString("utf8");
|
|
@@ -9076,7 +9076,7 @@ async function promptHidden(prompt) {
|
|
|
9076
9076
|
if (char === "\r" || char === "\n") {
|
|
9077
9077
|
cleanup();
|
|
9078
9078
|
stderr.write("\n");
|
|
9079
|
-
|
|
9079
|
+
resolve18(value);
|
|
9080
9080
|
return;
|
|
9081
9081
|
}
|
|
9082
9082
|
if (char === "\x7F" || char === "\b") {
|
|
@@ -13496,7 +13496,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
13496
13496
|
}
|
|
13497
13497
|
async requestAssistantSpeechMessage(ws, chatId, messageId, segments2) {
|
|
13498
13498
|
const timeoutMs = 10 * 60 * 1e3;
|
|
13499
|
-
return await new Promise((
|
|
13499
|
+
return await new Promise((resolve18, reject) => {
|
|
13500
13500
|
const expected = /* @__PURE__ */ new Set();
|
|
13501
13501
|
const queued = /* @__PURE__ */ new Set();
|
|
13502
13502
|
const terminal = /* @__PURE__ */ new Map();
|
|
@@ -13505,7 +13505,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
13505
13505
|
if (!accepted || expected.size === 0 || terminal.size !== expected.size) return;
|
|
13506
13506
|
cleanup();
|
|
13507
13507
|
const statuses = [...terminal.values()];
|
|
13508
|
-
|
|
13508
|
+
resolve18({
|
|
13509
13509
|
generated: statuses.filter((status) => status.status === "ready" && queued.has(String(status.segment_id))).length,
|
|
13510
13510
|
reused: statuses.filter((status) => status.status === "ready" && !queued.has(String(status.segment_id))).length,
|
|
13511
13511
|
failed: statuses.filter((status) => status.status === "error").length,
|
|
@@ -15007,8 +15007,8 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
15007
15007
|
}
|
|
15008
15008
|
let dispatchHandlersReady = () => {
|
|
15009
15009
|
};
|
|
15010
|
-
const handlersReady = new Promise((
|
|
15011
|
-
dispatchHandlersReady =
|
|
15010
|
+
const handlersReady = new Promise((resolve18) => {
|
|
15011
|
+
dispatchHandlersReady = resolve18;
|
|
15012
15012
|
});
|
|
15013
15013
|
let precollectedResponse = params.precollectResponse && params.incognito && shouldWaitForAi ? ws.collectAiResponse(messageId, chatId, { onStream: params.onStream, timeoutMs: params.responseTimeoutMs }) : null;
|
|
15014
15014
|
if (!params.incognito && chatKeyBytes && encryptedChatKey) {
|
|
@@ -15597,7 +15597,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
15597
15597
|
);
|
|
15598
15598
|
const remainingMs = claimRetryDeadline - Date.now();
|
|
15599
15599
|
if (remainingMs <= claimRetryDelayMs) throw error;
|
|
15600
|
-
await new Promise((
|
|
15600
|
+
await new Promise((resolve18) => setTimeout(resolve18, claimRetryDelayMs));
|
|
15601
15601
|
claimRetryDelayMs = Math.min(claimRetryDelayMs * 2, 2e3);
|
|
15602
15602
|
} finally {
|
|
15603
15603
|
stopWatchingErrors();
|
|
@@ -16452,13 +16452,13 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
16452
16452
|
);
|
|
16453
16453
|
} catch (error) {
|
|
16454
16454
|
lastTransientError = error instanceof Error ? error.message : String(error);
|
|
16455
|
-
await new Promise((
|
|
16455
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS));
|
|
16456
16456
|
continue;
|
|
16457
16457
|
}
|
|
16458
16458
|
if (!response.ok) {
|
|
16459
16459
|
if (response.status >= SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS) {
|
|
16460
16460
|
lastTransientError = `HTTP ${response.status}`;
|
|
16461
|
-
await new Promise((
|
|
16461
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS));
|
|
16462
16462
|
continue;
|
|
16463
16463
|
}
|
|
16464
16464
|
throw new Error(`Task ${taskId} polling failed with HTTP ${response.status}. Generation was not retried; retain this task ID for recovery.`);
|
|
@@ -16470,7 +16470,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
16470
16470
|
if (response.data.status === "failed") {
|
|
16471
16471
|
throw new Error(response.data.error ?? "Task failed");
|
|
16472
16472
|
}
|
|
16473
|
-
await new Promise((
|
|
16473
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS));
|
|
16474
16474
|
}
|
|
16475
16475
|
if (lastTransientError) {
|
|
16476
16476
|
throw new Error(
|
|
@@ -18592,7 +18592,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
18592
18592
|
`Rate limited by settings API; retrying in ${Math.ceil(SETTINGS_GET_RATE_LIMIT_RETRY_MS / 1e3)}s...
|
|
18593
18593
|
`
|
|
18594
18594
|
);
|
|
18595
|
-
await new Promise((
|
|
18595
|
+
await new Promise((resolve18) => setTimeout(resolve18, SETTINGS_GET_RATE_LIMIT_RETRY_MS));
|
|
18596
18596
|
response = await this.http.get(normalizedPath, headers);
|
|
18597
18597
|
}
|
|
18598
18598
|
if (!response.ok) {
|
|
@@ -20831,7 +20831,7 @@ function filenameFromContentDisposition(header2) {
|
|
|
20831
20831
|
return plain?.trim() ?? null;
|
|
20832
20832
|
}
|
|
20833
20833
|
function sleep2(ms) {
|
|
20834
|
-
return new Promise((
|
|
20834
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
20835
20835
|
}
|
|
20836
20836
|
function printLogo() {
|
|
20837
20837
|
const W = "\x1B[1;37m";
|
|
@@ -27925,13 +27925,13 @@ var OpenMates = class {
|
|
|
27925
27925
|
});
|
|
27926
27926
|
} catch (error) {
|
|
27927
27927
|
lastTransientError = error instanceof Error ? error.message : String(error);
|
|
27928
|
-
await new Promise((
|
|
27928
|
+
await new Promise((resolve18) => setTimeout(resolve18, CODE_RUN_POLL_INTERVAL_MS));
|
|
27929
27929
|
continue;
|
|
27930
27930
|
}
|
|
27931
27931
|
if (!response.ok) {
|
|
27932
27932
|
if (response.status >= SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS2) {
|
|
27933
27933
|
lastTransientError = `HTTP ${response.status}`;
|
|
27934
|
-
await new Promise((
|
|
27934
|
+
await new Promise((resolve18) => setTimeout(resolve18, CODE_RUN_POLL_INTERVAL_MS));
|
|
27935
27935
|
continue;
|
|
27936
27936
|
}
|
|
27937
27937
|
throw new OpenMatesApiError(response.status, await this.safeJson(response));
|
|
@@ -27940,7 +27940,7 @@ var OpenMates = class {
|
|
|
27940
27940
|
const status = await this.parseResponse(response);
|
|
27941
27941
|
const value = typeof status.status === "string" ? status.status : "";
|
|
27942
27942
|
if (CODE_RUN_TERMINAL_STATUSES.has(value)) return status;
|
|
27943
|
-
await new Promise((
|
|
27943
|
+
await new Promise((resolve18) => setTimeout(resolve18, CODE_RUN_POLL_INTERVAL_MS));
|
|
27944
27944
|
}
|
|
27945
27945
|
if (lastTransientError) {
|
|
27946
27946
|
throw new Error(`Code Run did not complete within ${CODE_RUN_POLL_TIMEOUT_MS / 1e3}s; last polling error: ${lastTransientError}`);
|
|
@@ -27965,13 +27965,13 @@ var OpenMates = class {
|
|
|
27965
27965
|
});
|
|
27966
27966
|
} catch (error) {
|
|
27967
27967
|
lastTransientError = error instanceof Error ? error.message : String(error);
|
|
27968
|
-
await new Promise((
|
|
27968
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS2));
|
|
27969
27969
|
continue;
|
|
27970
27970
|
}
|
|
27971
27971
|
if (!response.ok) {
|
|
27972
27972
|
if (response.status >= SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS2) {
|
|
27973
27973
|
lastTransientError = `HTTP ${response.status}`;
|
|
27974
|
-
await new Promise((
|
|
27974
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS2));
|
|
27975
27975
|
continue;
|
|
27976
27976
|
}
|
|
27977
27977
|
throw new OpenMatesApiError(response.status, await this.safeJson(response));
|
|
@@ -27980,7 +27980,7 @@ var OpenMates = class {
|
|
|
27980
27980
|
const task = await this.parseResponse(response);
|
|
27981
27981
|
if (task.status === "completed") return task;
|
|
27982
27982
|
if (task.status === "failed") throw new Error(task.error ?? "Task failed");
|
|
27983
|
-
await new Promise((
|
|
27983
|
+
await new Promise((resolve18) => setTimeout(resolve18, SKILL_TASK_POLL_INTERVAL_MS2));
|
|
27984
27984
|
}
|
|
27985
27985
|
if (lastTransientError) {
|
|
27986
27986
|
throw new Error(`Task ${taskId} did not complete within ${SKILL_TASK_POLL_TIMEOUT_MS2 / 1e3}s; last polling error: ${lastTransientError}`);
|
|
@@ -29057,7 +29057,7 @@ var OpenMatesChats = class {
|
|
|
29057
29057
|
}
|
|
29058
29058
|
const remainingMs = deadline - Date.now();
|
|
29059
29059
|
if (remainingMs <= 0) break;
|
|
29060
|
-
await new Promise((
|
|
29060
|
+
await new Promise((resolve18) => setTimeout(resolve18, Math.min(pollIntervalMs, remainingMs)));
|
|
29061
29061
|
}
|
|
29062
29062
|
throw new OpenMatesConfigError("Timed out waiting for saved chat recovery");
|
|
29063
29063
|
}
|
|
@@ -30345,7 +30345,7 @@ function isTaskVersionConflict(error) {
|
|
|
30345
30345
|
return error instanceof OpenMatesApiError && error.status === 409 && String(JSON.stringify(error.data)).includes("TASK_VERSION_CONFLICT");
|
|
30346
30346
|
}
|
|
30347
30347
|
function delay(ms) {
|
|
30348
|
-
return new Promise((
|
|
30348
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
30349
30349
|
}
|
|
30350
30350
|
var OpenMatesPlans = class {
|
|
30351
30351
|
client;
|
|
@@ -31304,7 +31304,7 @@ var OpenMatesEmbedPreview = class {
|
|
|
31304
31304
|
if (["running", "failed", "timeout", "cancelled", "stopped"].includes(status.status)) {
|
|
31305
31305
|
return status;
|
|
31306
31306
|
}
|
|
31307
|
-
await new Promise((
|
|
31307
|
+
await new Promise((resolve18) => setTimeout(resolve18, 1e3));
|
|
31308
31308
|
}
|
|
31309
31309
|
throw new OpenMatesApiError(408, { detail: "Application preview did not reach running state before timeout" });
|
|
31310
31310
|
}
|
|
@@ -33350,8 +33350,8 @@ async function renderRemotionShareLink(embedId, client2, ln) {
|
|
|
33350
33350
|
}
|
|
33351
33351
|
}
|
|
33352
33352
|
function generateQr(value) {
|
|
33353
|
-
return new Promise((
|
|
33354
|
-
qrcode2.generate(value, { small: true }, (qr) =>
|
|
33353
|
+
return new Promise((resolve18) => {
|
|
33354
|
+
qrcode2.generate(value, { small: true }, (qr) => resolve18(qr));
|
|
33355
33355
|
});
|
|
33356
33356
|
}
|
|
33357
33357
|
function remotionMeta(c) {
|
|
@@ -34248,7 +34248,7 @@ import { appendFileSync, chmodSync as chmodSync7, closeSync as closeSync4, copyF
|
|
|
34248
34248
|
import { createInterface as createInterface4 } from "readline";
|
|
34249
34249
|
import { createInterface as createPromptInterface } from "readline/promises";
|
|
34250
34250
|
import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
|
|
34251
|
-
import { dirname as dirname9, join as join15, resolve as
|
|
34251
|
+
import { dirname as dirname9, join as join15, resolve as resolve7 } from "path";
|
|
34252
34252
|
|
|
34253
34253
|
// src/branding.ts
|
|
34254
34254
|
var OPENMATES_WORDMARK = "OPENMATES";
|
|
@@ -35074,8 +35074,42 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
35074
35074
|
import { createHash as createHash16 } from "crypto";
|
|
35075
35075
|
import { accessSync, constants as constants2, existsSync as existsSync9, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync10, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
35076
35076
|
import { tmpdir } from "os";
|
|
35077
|
-
import { dirname as dirname7, join as join12 } from "path";
|
|
35077
|
+
import { dirname as dirname7, join as join12, isAbsolute as isAbsolute3, resolve as resolve6 } from "path";
|
|
35078
35078
|
var hash2 = (text6) => createHash16("sha256").update(text6).digest("hex");
|
|
35079
|
+
function caddyConfigFromArgs(args, cwd) {
|
|
35080
|
+
const index = args.indexOf("--config");
|
|
35081
|
+
const value = index >= 0 ? args[index + 1] : args.find((arg) => arg.startsWith("--config="))?.slice(9);
|
|
35082
|
+
if (!value || value.startsWith("--")) return void 0;
|
|
35083
|
+
if (!isAbsolute3(value) && !cwd) throw new Error("caddy_relative_config_requires_explicit_path");
|
|
35084
|
+
return resolve6(cwd ?? "/", value);
|
|
35085
|
+
}
|
|
35086
|
+
function detectCaddyConfigPath(explicit) {
|
|
35087
|
+
if (explicit) return resolve6(explicit);
|
|
35088
|
+
let pid;
|
|
35089
|
+
try {
|
|
35090
|
+
pid = execFileSync3("systemctl", ["show", "caddy", "--property=MainPID", "--value"], {
|
|
35091
|
+
encoding: "utf8",
|
|
35092
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
35093
|
+
timeout: 5e3
|
|
35094
|
+
}).trim();
|
|
35095
|
+
} catch {
|
|
35096
|
+
}
|
|
35097
|
+
if (pid && /^[1-9]\d*$/.test(pid)) {
|
|
35098
|
+
try {
|
|
35099
|
+
const args = readFileSync10(`/proc/${pid}/cmdline`, "utf8").split("\0").filter(Boolean);
|
|
35100
|
+
const config = caddyConfigFromArgs(args);
|
|
35101
|
+
if (config) return config;
|
|
35102
|
+
} catch {
|
|
35103
|
+
throw new Error("caddy_running_config_requires_explicit_path");
|
|
35104
|
+
}
|
|
35105
|
+
throw new Error("caddy_running_config_requires_explicit_path");
|
|
35106
|
+
}
|
|
35107
|
+
return existsSync9("/etc/caddy/Caddyfile") ? "/etc/caddy/Caddyfile" : void 0;
|
|
35108
|
+
}
|
|
35109
|
+
function caddyUpdateRetryCommand(input) {
|
|
35110
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
35111
|
+
return `sudo -v && openmates server caddy update --path ${quote(input.installPath)} --role ${quote(input.role)} --caddy-config ${quote(input.configPath)}` + (input.profile === "official-upload" ? " --caddy-profile official-upload" : "");
|
|
35112
|
+
}
|
|
35079
35113
|
function resolveCaddyProfile(role, explicit, previous) {
|
|
35080
35114
|
if (explicit === void 0) return previous ?? "self-host";
|
|
35081
35115
|
if (role !== "upload" || explicit !== "official-upload") throw new Error("caddy_profile_unsupported");
|
|
@@ -35286,7 +35320,17 @@ var HOST_TRANSACTION = String.raw`
|
|
|
35286
35320
|
const fs = require('node:fs'), cp = require('node:child_process'), crypto = require('node:crypto'), path = require('node:path');
|
|
35287
35321
|
const input = JSON.parse(fs.readFileSync(0, 'utf8'));
|
|
35288
35322
|
const digest = text => crypto.createHash('sha256').update(text).digest('hex');
|
|
35289
|
-
function run(command, args) {
|
|
35323
|
+
function run(command, args) {
|
|
35324
|
+
const options = {stdio: ['ignore','pipe','pipe'], timeout: 20000};
|
|
35325
|
+
try { cp.execFileSync(command, args, options); }
|
|
35326
|
+
catch (error) {
|
|
35327
|
+
// A user-owned Caddyfile can still belong to a root-managed service.
|
|
35328
|
+
// Honor a cached sudo session for reload without elevating file access.
|
|
35329
|
+
if (command !== 'systemctl') throw error;
|
|
35330
|
+
try { cp.execFileSync('sudo', ['-n', command, ...args], options); }
|
|
35331
|
+
catch { throw error; }
|
|
35332
|
+
}
|
|
35333
|
+
}
|
|
35290
35334
|
function replace(content, metadata) {
|
|
35291
35335
|
const temp = input.configPath + '.openmates-' + crypto.randomUUID();
|
|
35292
35336
|
let fd;
|
|
@@ -35346,7 +35390,7 @@ try {
|
|
|
35346
35390
|
function caddyHostOperation(input) {
|
|
35347
35391
|
let privileged = false;
|
|
35348
35392
|
try {
|
|
35349
|
-
accessSync(dirname7(input.configPath), constants2.W_OK);
|
|
35393
|
+
accessSync(input.action === "read" ? input.configPath : dirname7(input.configPath), input.action === "read" ? constants2.R_OK : constants2.W_OK);
|
|
35350
35394
|
} catch {
|
|
35351
35395
|
privileged = true;
|
|
35352
35396
|
}
|
|
@@ -35390,6 +35434,12 @@ async function verifyCaddyCoreRoutes(apiUrl, origin) {
|
|
|
35390
35434
|
redirect: "error",
|
|
35391
35435
|
signal: AbortSignal.timeout(5e3)
|
|
35392
35436
|
});
|
|
35437
|
+
const embedPreflight = await request("/v1/embeds/chats/00000000-0000-4000-8000-000000000000/references/availability", { method: "OPTIONS", headers: {
|
|
35438
|
+
Origin: origin,
|
|
35439
|
+
"Access-Control-Request-Method": "POST",
|
|
35440
|
+
"Access-Control-Request-Headers": "content-type"
|
|
35441
|
+
} });
|
|
35442
|
+
if (!embedPreflight.ok || embedPreflight.headers.get("access-control-allow-origin") !== origin || embedPreflight.headers.get("access-control-allow-credentials") !== "true") throw new Error("caddy_embed_reference_cors_failed");
|
|
35393
35443
|
const availability = await request("/v1/features/availability");
|
|
35394
35444
|
if (!availability.ok) throw new Error("caddy_availability_route_failed");
|
|
35395
35445
|
const features = await availability.json();
|
|
@@ -35682,7 +35732,7 @@ function isBrevoAcceptedResponse(pathName, method, status, responseBody) {
|
|
|
35682
35732
|
}
|
|
35683
35733
|
async function requestBrevo(pathName, method, apiKey, payload) {
|
|
35684
35734
|
const body = payload ? JSON.stringify(payload) : void 0;
|
|
35685
|
-
await new Promise((
|
|
35735
|
+
await new Promise((resolve18, reject) => {
|
|
35686
35736
|
const request = httpsRequest(buildBrevoRequestOptions(pathName, method, apiKey, body), (response) => {
|
|
35687
35737
|
let responseBytes = 0;
|
|
35688
35738
|
const chunks = [];
|
|
@@ -35694,8 +35744,8 @@ async function requestBrevo(pathName, method, apiKey, payload) {
|
|
|
35694
35744
|
response.on("end", () => {
|
|
35695
35745
|
const status = response.statusCode ?? 0;
|
|
35696
35746
|
const responseBody = Buffer.concat(chunks).toString("utf8");
|
|
35697
|
-
if (isBrevoAcceptedResponse(pathName, method, status, responseBody))
|
|
35698
|
-
else if (isBrevoIdempotencyDuplicate(status, responseBody, payload))
|
|
35747
|
+
if (isBrevoAcceptedResponse(pathName, method, status, responseBody)) resolve18();
|
|
35748
|
+
else if (isBrevoIdempotencyDuplicate(status, responseBody, payload)) resolve18();
|
|
35699
35749
|
else reject(new Error(`brevo_delivery_failed:${status}`));
|
|
35700
35750
|
});
|
|
35701
35751
|
});
|
|
@@ -35863,7 +35913,7 @@ async function sendGenericWebhook(target, secret, payload, allowLocalDevelopment
|
|
|
35863
35913
|
const eventId = randomUUID12();
|
|
35864
35914
|
const signed = signRuntimeWebhookPayload(payload, secret, timestamp, eventId);
|
|
35865
35915
|
const selected = addresses[0];
|
|
35866
|
-
await new Promise((
|
|
35916
|
+
await new Promise((resolve18, reject) => {
|
|
35867
35917
|
const requestFunction = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
35868
35918
|
const request = requestFunction({
|
|
35869
35919
|
protocol: url.protocol,
|
|
@@ -35883,7 +35933,7 @@ async function sendGenericWebhook(target, secret, payload, allowLocalDevelopment
|
|
|
35883
35933
|
});
|
|
35884
35934
|
response.on("end", () => {
|
|
35885
35935
|
const status = response.statusCode ?? 0;
|
|
35886
|
-
if (status >= 200 && status < 300)
|
|
35936
|
+
if (status >= 200 && status < 300) resolve18();
|
|
35887
35937
|
else reject(new Error(`webhook_delivery_failed:${status}`));
|
|
35888
35938
|
});
|
|
35889
35939
|
});
|
|
@@ -35964,7 +36014,7 @@ async function deliverWithRetries(channel, send) {
|
|
|
35964
36014
|
await send();
|
|
35965
36015
|
return { channel, status: "delivered", attempts: attempt };
|
|
35966
36016
|
} catch {
|
|
35967
|
-
if (attempt < 3) await new Promise((
|
|
36017
|
+
if (attempt < 3) await new Promise((resolve18) => setTimeout(resolve18, 250 * 2 ** (attempt - 1)));
|
|
35968
36018
|
}
|
|
35969
36019
|
}
|
|
35970
36020
|
return { channel, status: "exhausted", attempts: 3, sanitizedReason: "delivery_failed" };
|
|
@@ -35977,7 +36027,7 @@ async function deliverUpdateCompletionEmail(config, payload, send = sendUpdateCo
|
|
|
35977
36027
|
await send(config, payload);
|
|
35978
36028
|
return { status: "accepted", attempts };
|
|
35979
36029
|
} catch {
|
|
35980
|
-
if (attempts < 3) await new Promise((
|
|
36030
|
+
if (attempts < 3) await new Promise((resolve18) => setTimeout(resolve18, 250 * 2 ** (attempts - 1)));
|
|
35981
36031
|
}
|
|
35982
36032
|
}
|
|
35983
36033
|
return { status: "failed", attempts: Math.max(previousAttempts, 3), sanitizedReason: "delivery_failed" };
|
|
@@ -36608,9 +36658,9 @@ function exec(cmd, cwd) {
|
|
|
36608
36658
|
return execSync(cmd, { cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
36609
36659
|
}
|
|
36610
36660
|
function runInteractive(cmd, args, cwd) {
|
|
36611
|
-
return new Promise((
|
|
36661
|
+
return new Promise((resolve18, reject) => {
|
|
36612
36662
|
const child = nodeSpawn(cmd, args, { cwd, stdio: "inherit", shell: false });
|
|
36613
|
-
child.on("close", (code) =>
|
|
36663
|
+
child.on("close", (code) => resolve18(code ?? 1));
|
|
36614
36664
|
child.on("error", reject);
|
|
36615
36665
|
});
|
|
36616
36666
|
}
|
|
@@ -36703,7 +36753,7 @@ function getInstallDeploymentMode(installPath, config) {
|
|
|
36703
36753
|
function getOpenMatesCloudOverlayPath(flags, config) {
|
|
36704
36754
|
const explicit = flags["openmatescloud-path"] ?? flags["openmates-cloud-path"];
|
|
36705
36755
|
if (explicit === true) throw new Error("Provide an OpenMatesCloud path: --openmatescloud-path <dir>.");
|
|
36706
|
-
if (typeof explicit === "string") return
|
|
36756
|
+
if (typeof explicit === "string") return resolve7(explicit);
|
|
36707
36757
|
return config?.openMatesCloudOverlayPath;
|
|
36708
36758
|
}
|
|
36709
36759
|
function hasServiceFilter(flags) {
|
|
@@ -37095,7 +37145,7 @@ function fileHash(path2) {
|
|
|
37095
37145
|
async function loadSelfHostComposeTemplate(templateRef, role, imageTag, packageVersion = getPackageVersion()) {
|
|
37096
37146
|
const templateDir = process.env.OPENMATES_SELFHOST_TEMPLATE_DIR;
|
|
37097
37147
|
if (templateDir) {
|
|
37098
|
-
return readFileSync12(join15(
|
|
37148
|
+
return readFileSync12(join15(resolve7(templateDir), ROLE_TEMPLATE_FILES[role]), "utf-8");
|
|
37099
37149
|
}
|
|
37100
37150
|
const packaged = packagedTemplatePath(role);
|
|
37101
37151
|
const source = resolveTemplateSource({
|
|
@@ -37236,10 +37286,10 @@ function warnIfMissingLlmCredentials(installPath) {
|
|
|
37236
37286
|
}
|
|
37237
37287
|
async function confirmDestructive(phrase) {
|
|
37238
37288
|
const rl = createInterface4({ input: process.stdin, output: process.stderr });
|
|
37239
|
-
return new Promise((
|
|
37289
|
+
return new Promise((resolve18) => {
|
|
37240
37290
|
rl.question(`Type "${phrase}" to confirm: `, (answer) => {
|
|
37241
37291
|
rl.close();
|
|
37242
|
-
|
|
37292
|
+
resolve18(answer.trim() === phrase);
|
|
37243
37293
|
});
|
|
37244
37294
|
});
|
|
37245
37295
|
}
|
|
@@ -37628,7 +37678,7 @@ function writeDeploymentModeEnv(installPath, deploymentMode, overlayPath) {
|
|
|
37628
37678
|
writeEnvContent(installPath, content);
|
|
37629
37679
|
return { overlayPath: null };
|
|
37630
37680
|
}
|
|
37631
|
-
const resolvedOverlayPath =
|
|
37681
|
+
const resolvedOverlayPath = resolve7(overlayPath ?? defaultOpenMatesCloudOverlayPath(installPath));
|
|
37632
37682
|
const overlayComposeFile = defaultOpenMatesCloudComposeFile(resolvedOverlayPath);
|
|
37633
37683
|
if (!existsSync11(resolvedOverlayPath) || !existsSync11(overlayComposeFile)) {
|
|
37634
37684
|
throw new Error(
|
|
@@ -37739,7 +37789,7 @@ function printServerCommandStart(subcommand, rest, flags) {
|
|
|
37739
37789
|
console.log(renderOpenMatesAsciiLogo());
|
|
37740
37790
|
console.log("");
|
|
37741
37791
|
console.log(`Running OpenMates ${command}...`);
|
|
37742
|
-
if (typeof flags.path === "string") console.log(`Path: ${
|
|
37792
|
+
if (typeof flags.path === "string") console.log(`Path: ${resolve7(flags.path)}`);
|
|
37743
37793
|
if (typeof flags.role === "string") console.log(`Role: ${flags.role}`);
|
|
37744
37794
|
console.log("");
|
|
37745
37795
|
}
|
|
@@ -37881,7 +37931,7 @@ function createServerBackup(installPath, role, options = {}) {
|
|
|
37881
37931
|
const plan = planBackup({ role, includeObservability: options.includeObservability });
|
|
37882
37932
|
const backupDir = roleBackupDir(installPath, role);
|
|
37883
37933
|
mkdirSync12(backupDir, { recursive: true, mode: 448 });
|
|
37884
|
-
const archivePath = options.output ?
|
|
37934
|
+
const archivePath = options.output ? resolve7(options.output) : join15(backupDir, options.preUpdate ? `latest-pre-update-${role}.tar.gz` : `openmates-${role}-${nowStamp()}.tar.gz`);
|
|
37885
37935
|
mkdirSync12(dirname9(archivePath), { recursive: true, mode: 448 });
|
|
37886
37936
|
const tempDir = mkdtempSync2(join15(backupDir, ".tmp-"));
|
|
37887
37937
|
const env = readEnvMap(installPath);
|
|
@@ -37936,7 +37986,7 @@ function validateExtractedServerBackup(tempDir, role) {
|
|
|
37936
37986
|
}
|
|
37937
37987
|
}
|
|
37938
37988
|
function withValidatedServerBackup(installPath, role, file, useBackup, tempRoot = roleBackupDir(installPath, role)) {
|
|
37939
|
-
const archivePath =
|
|
37989
|
+
const archivePath = resolve7(file);
|
|
37940
37990
|
if (!existsSync11(archivePath)) throw new Error(`Backup file not found: ${archivePath}`);
|
|
37941
37991
|
mkdirSync12(tempRoot, { recursive: true, mode: 448 });
|
|
37942
37992
|
const tempDir = mkdtempSync2(join15(tempRoot, ".restore-"));
|
|
@@ -38107,6 +38157,15 @@ async function serverStatus(flags) {
|
|
|
38107
38157
|
if (migration.message_pages) console.log(`Message pages: ${JSON.stringify(migration.message_pages)}`);
|
|
38108
38158
|
if (migration.version_rows) console.log(`Version rows: ${JSON.stringify(migration.version_rows)}`);
|
|
38109
38159
|
}
|
|
38160
|
+
function sourceBuildCommitSha(installPath) {
|
|
38161
|
+
try {
|
|
38162
|
+
if (exec("git status --porcelain", installPath).trim()) return "";
|
|
38163
|
+
const revision = exec("git rev-parse HEAD", installPath).trim();
|
|
38164
|
+
return /^[a-f0-9]{40}$/i.test(revision) ? revision.toLowerCase() : "";
|
|
38165
|
+
} catch {
|
|
38166
|
+
return "";
|
|
38167
|
+
}
|
|
38168
|
+
}
|
|
38110
38169
|
async function serverStart(flags) {
|
|
38111
38170
|
requireDocker();
|
|
38112
38171
|
const installPath = resolveServerPath(flags);
|
|
@@ -38138,6 +38197,18 @@ async function serverStart(flags) {
|
|
|
38138
38197
|
code = await runInteractive("docker", pullArgs, installPath);
|
|
38139
38198
|
if (code !== 0) process.exit(code);
|
|
38140
38199
|
}
|
|
38200
|
+
if (installMode === "source") {
|
|
38201
|
+
const buildArgs = [
|
|
38202
|
+
...composeArgs(installPath, withOverrides, installMode, role),
|
|
38203
|
+
"build",
|
|
38204
|
+
"--build-arg",
|
|
38205
|
+
`BUILD_COMMIT_SHA=${sourceBuildCommitSha(installPath)}`
|
|
38206
|
+
];
|
|
38207
|
+
if (selection.requested) buildArgs.push(...selection.services);
|
|
38208
|
+
console.error("Building source containers...");
|
|
38209
|
+
code = await runInteractive("docker", buildArgs, installPath);
|
|
38210
|
+
if (code !== 0) process.exit(code);
|
|
38211
|
+
}
|
|
38141
38212
|
code = await runInteractive("docker", args, installPath);
|
|
38142
38213
|
if (code !== 0) process.exit(code);
|
|
38143
38214
|
if (flags.json === true) {
|
|
@@ -38270,12 +38341,12 @@ async function serverRegister(flags) {
|
|
|
38270
38341
|
if (!existsSync11(envPath)) {
|
|
38271
38342
|
throw new Error(`Runtime env file not found: ${envPath}`);
|
|
38272
38343
|
}
|
|
38273
|
-
const gitRoot =
|
|
38344
|
+
const gitRoot = resolve7(exec("git rev-parse --show-toplevel", installPath));
|
|
38274
38345
|
if (gitRoot !== installPath) {
|
|
38275
38346
|
throw new Error(`--path must point to the OpenMates Git checkout root (${gitRoot}).`);
|
|
38276
38347
|
}
|
|
38277
38348
|
const existing = loadServerConfig();
|
|
38278
|
-
if (existing?.installPath &&
|
|
38349
|
+
if (existing?.installPath && resolve7(existing.installPath) !== installPath && flags.yes !== true) {
|
|
38279
38350
|
throw new Error(
|
|
38280
38351
|
`Another server is registered at ${existing.installPath}. Rerun with --yes to replace the local CLI registration; no server data will be changed.`
|
|
38281
38352
|
);
|
|
@@ -38325,8 +38396,8 @@ async function serverRegister(flags) {
|
|
|
38325
38396
|
}
|
|
38326
38397
|
}
|
|
38327
38398
|
async function serverInstall(flags) {
|
|
38328
|
-
const installPath = typeof flags.path === "string" ?
|
|
38329
|
-
const sourcePath = typeof flags["source-path"] === "string" ?
|
|
38399
|
+
const installPath = typeof flags.path === "string" ? resolve7(flags.path) : DEFAULT_INSTALL_PATH;
|
|
38400
|
+
const sourcePath = typeof flags["source-path"] === "string" ? resolve7(flags["source-path"]) : null;
|
|
38330
38401
|
const fromSource = flags["from-source"] === true || sourcePath !== null;
|
|
38331
38402
|
const role = getServerRole(flags, null);
|
|
38332
38403
|
const profile = getCoreProfile(flags, null);
|
|
@@ -38351,7 +38422,7 @@ async function serverInstall(flags) {
|
|
|
38351
38422
|
mkdirSync12(installPath, { recursive: true });
|
|
38352
38423
|
ensureRuntimeMetricsDirectory(installPath);
|
|
38353
38424
|
if (typeof flags["env-path"] === "string") {
|
|
38354
|
-
const envSource =
|
|
38425
|
+
const envSource = resolve7(flags["env-path"]);
|
|
38355
38426
|
if (!existsSync11(envSource)) {
|
|
38356
38427
|
throw new Error(`Env file not found: ${envSource}`);
|
|
38357
38428
|
}
|
|
@@ -38429,7 +38500,7 @@ CLI default API: ${cliUrls2.apiUrl}`);
|
|
|
38429
38500
|
}
|
|
38430
38501
|
ensureRuntimeMetricsDirectory(installPath);
|
|
38431
38502
|
if (typeof flags["env-path"] === "string") {
|
|
38432
|
-
const envSource =
|
|
38503
|
+
const envSource = resolve7(flags["env-path"]);
|
|
38433
38504
|
if (!existsSync11(envSource)) {
|
|
38434
38505
|
throw new Error(`Env file not found: ${envSource}`);
|
|
38435
38506
|
}
|
|
@@ -38706,7 +38777,7 @@ async function persistRuntimeResult(installPath, role, output) {
|
|
|
38706
38777
|
return deliveries.flat();
|
|
38707
38778
|
}
|
|
38708
38779
|
async function installRuntimeMonitoringServices(installPath, role) {
|
|
38709
|
-
const executablePath =
|
|
38780
|
+
const executablePath = resolve7(process.argv[1] ?? "/usr/local/bin/openmates");
|
|
38710
38781
|
const plan = planRuntimeMonitoringServices({ role, installPath, executablePath });
|
|
38711
38782
|
const notificationConfig = runtimeNotificationConfig(installPath);
|
|
38712
38783
|
const emailServiceAvailable = notificationConfig.email ? await probeRuntimeEmailService(notificationConfig.email) : false;
|
|
@@ -38793,7 +38864,9 @@ async function autoInstallRuntimeMonitoringServices(installPath, role) {
|
|
|
38793
38864
|
}
|
|
38794
38865
|
function caddyUpdatePlan(installPath, role, config, flags) {
|
|
38795
38866
|
if (flags["caddy-config"] === true) throw new Error("Provide --caddy-config <file>.");
|
|
38796
|
-
const
|
|
38867
|
+
const explicit = typeof flags["caddy-config"] === "string" ? flags["caddy-config"] : void 0;
|
|
38868
|
+
const configPath = detectCaddyConfigPath(explicit) ?? "/etc/caddy/Caddyfile";
|
|
38869
|
+
if (explicit && !existsSync11(configPath)) throw new Error("caddy_explicit_config_missing");
|
|
38797
38870
|
const required2 = role === "core" && getInstallDeploymentMode(installPath, config) === "official_cloud";
|
|
38798
38871
|
if (!existsSync11(configPath) && required2) throw new Error("Managed cloud Caddyfile is missing; update cannot proceed.");
|
|
38799
38872
|
const prior = role === "upload" ? readCaddyUpdateState(join15(installPath, ".openmates", "caddy", `${role}.json`), configPath, null) : void 0;
|
|
@@ -38875,7 +38948,69 @@ async function runCaddyUpdateStep(input) {
|
|
|
38875
38948
|
} catch (error) {
|
|
38876
38949
|
const reason = error instanceof Error && /^caddy_[a-z_:-]+$/.test(error.message) ? error.message : "caddy_update_failed";
|
|
38877
38950
|
writeServerUpdateStatus(input.installPath, input.role, { status: "degraded", step: "caddy-update", caddy: { status: "failed", sanitizedReason: reason } });
|
|
38878
|
-
|
|
38951
|
+
const command = caddyRetryForInstall(input.installPath, input.role, input.flags, reason);
|
|
38952
|
+
throw new Error(`Caddy update failed (${reason}); update is degraded. Updated containers remain running.
|
|
38953
|
+
After resolving the reported problem, run:
|
|
38954
|
+
${command}`);
|
|
38955
|
+
}
|
|
38956
|
+
}
|
|
38957
|
+
function caddyRetryForInstall(installPath, role, flags, reason) {
|
|
38958
|
+
const explicit = typeof flags["caddy-config"] === "string" ? flags["caddy-config"] : void 0;
|
|
38959
|
+
let configPath = explicit ?? "/path/to/active/Caddyfile";
|
|
38960
|
+
try {
|
|
38961
|
+
configPath = detectCaddyConfigPath(explicit) ?? "/etc/caddy/Caddyfile";
|
|
38962
|
+
} catch {
|
|
38963
|
+
}
|
|
38964
|
+
return caddyUpdateRetryCommand({
|
|
38965
|
+
installPath,
|
|
38966
|
+
role,
|
|
38967
|
+
configPath,
|
|
38968
|
+
profile: flags["caddy-profile"] === "official-upload" || reason === "caddy_profile_required_official_upload" ? "official-upload" : void 0
|
|
38969
|
+
});
|
|
38970
|
+
}
|
|
38971
|
+
async function updateCaddyOnly(installPath, role, config, flags) {
|
|
38972
|
+
const release2 = acquireServerUpdateLock(installPath);
|
|
38973
|
+
let result;
|
|
38974
|
+
try {
|
|
38975
|
+
await withEngineeringRuntimeOperation(installPath, "caddy-update", ["caddy"], async () => {
|
|
38976
|
+
result = await updateServerCaddy({ installPath, role, config, flags, mode: getInstallMode(installPath, config), withOverrides: flags["with-overrides"] === true || config?.composeProfile === "full" });
|
|
38977
|
+
});
|
|
38978
|
+
return result;
|
|
38979
|
+
} finally {
|
|
38980
|
+
release2();
|
|
38981
|
+
}
|
|
38982
|
+
}
|
|
38983
|
+
async function updateCaddyAfterCliUpgrade(flags) {
|
|
38984
|
+
let installPath;
|
|
38985
|
+
try {
|
|
38986
|
+
installPath = resolveServerPath(flags);
|
|
38987
|
+
} catch (error) {
|
|
38988
|
+
if (flags.path !== void 0) throw error;
|
|
38989
|
+
return void 0;
|
|
38990
|
+
}
|
|
38991
|
+
const config = loadConfigForInstallPath(installPath);
|
|
38992
|
+
const role = getServerRole(flags, config);
|
|
38993
|
+
let configPath;
|
|
38994
|
+
try {
|
|
38995
|
+
configPath = detectCaddyConfigPath(typeof flags["caddy-config"] === "string" ? flags["caddy-config"] : void 0);
|
|
38996
|
+
} catch {
|
|
38997
|
+
return { status: "pending", reason: "caddy_running_config_requires_explicit_path", retryCommand: caddyUpdateRetryCommand({ installPath, role, configPath: "/path/to/active/Caddyfile" }) };
|
|
38998
|
+
}
|
|
38999
|
+
if (!configPath) return void 0;
|
|
39000
|
+
const retryCommand = caddyUpdateRetryCommand({
|
|
39001
|
+
installPath,
|
|
39002
|
+
role,
|
|
39003
|
+
configPath,
|
|
39004
|
+
profile: flags["caddy-profile"] === "official-upload" ? "official-upload" : void 0
|
|
39005
|
+
});
|
|
39006
|
+
if (flags["dry-run"] === true || !config && typeof flags.path !== "string") {
|
|
39007
|
+
return { status: flags["dry-run"] === true ? "planned" : "pending", retryCommand };
|
|
39008
|
+
}
|
|
39009
|
+
try {
|
|
39010
|
+
return await updateCaddyOnly(installPath, role, config, { ...flags, "caddy-config": configPath });
|
|
39011
|
+
} catch (error) {
|
|
39012
|
+
const reason = error instanceof Error && /^caddy_[a-z_:-]+$/.test(error.message) ? error.message : "caddy_update_failed";
|
|
39013
|
+
return { status: "pending", retryCommand: reason === "caddy_profile_required_official_upload" ? caddyUpdateRetryCommand({ installPath, role, configPath, profile: "official-upload" }) : retryCommand, reason };
|
|
38879
39014
|
}
|
|
38880
39015
|
}
|
|
38881
39016
|
async function serverUpdate(client2, rest, flags) {
|
|
@@ -39494,7 +39629,7 @@ async function serverMonitoring(rest, flags) {
|
|
|
39494
39629
|
const config = loadConfigForInstallPath(installPath);
|
|
39495
39630
|
const role = getServerRole(flags, config);
|
|
39496
39631
|
if (rest[0] === "install-service") {
|
|
39497
|
-
const plan = planRuntimeMonitoringServices({ role, installPath, executablePath:
|
|
39632
|
+
const plan = planRuntimeMonitoringServices({ role, installPath, executablePath: resolve7(process.argv[1] ?? "/usr/local/bin/openmates") });
|
|
39498
39633
|
const files = [
|
|
39499
39634
|
[plan.serviceName, plan.unit],
|
|
39500
39635
|
[plan.timerName, plan.timer],
|
|
@@ -40191,9 +40326,35 @@ async function serverPreflight(flags) {
|
|
|
40191
40326
|
console.log(` Caddy steps: ${caddyPlan.steps.join(" -> ")}`);
|
|
40192
40327
|
}
|
|
40193
40328
|
async function serverCaddy(rest, flags) {
|
|
40329
|
+
if (rest[0] === "update") {
|
|
40330
|
+
if (flags["caddy-config"] === true) throw new Error("Provide --caddy-config <file>.");
|
|
40331
|
+
const installPath = resolveServerPath(flags);
|
|
40332
|
+
const config2 = loadConfigForInstallPath(installPath);
|
|
40333
|
+
const role2 = getServerRole(flags, config2);
|
|
40334
|
+
try {
|
|
40335
|
+
const plan2 = caddyUpdatePlan(installPath, role2, config2, flags);
|
|
40336
|
+
const retryCommand = caddyUpdateRetryCommand({ installPath, role: role2, configPath: plan2.configPath, profile: plan2.profile });
|
|
40337
|
+
if (flags["dry-run"] === true) {
|
|
40338
|
+
if (flags.json === true) printJson({ command: "caddy update", ...plan2, role: role2, path: installPath, mode: getInstallMode(installPath, config2), retryCommand });
|
|
40339
|
+
else console.log(`Caddy release update: ${plan2.status}
|
|
40340
|
+
Run: ${retryCommand}`);
|
|
40341
|
+
return;
|
|
40342
|
+
}
|
|
40343
|
+
const result = plan2.status === "not_installed" ? { status: "not_installed" } : await updateCaddyOnly(installPath, role2, config2, { ...flags, "caddy-config": plan2.configPath });
|
|
40344
|
+
if (flags.json === true) printJson({ command: "caddy update", role: role2, ...result });
|
|
40345
|
+
else console.log(`Caddy: ${result.status}`);
|
|
40346
|
+
} catch (error) {
|
|
40347
|
+
const reason = error instanceof Error && /^caddy_[a-z_:-]+$/.test(error.message) ? error.message : "caddy_update_failed";
|
|
40348
|
+
const retryCommand = caddyRetryForInstall(installPath, role2, flags, reason);
|
|
40349
|
+
throw new Error(`Caddy update failed (${reason}).
|
|
40350
|
+
After resolving the reported problem, run:
|
|
40351
|
+
${retryCommand}`);
|
|
40352
|
+
}
|
|
40353
|
+
return;
|
|
40354
|
+
}
|
|
40194
40355
|
const action = rest[0] ?? "status";
|
|
40195
40356
|
if (!["check", "status", "diff", "apply"].includes(action)) {
|
|
40196
|
-
throw new Error("Usage: openmates server caddy check|status|diff|apply [--role core|upload|preview]");
|
|
40357
|
+
throw new Error("Usage: openmates server caddy check|status|diff|apply|update [--role core|upload|preview]");
|
|
40197
40358
|
}
|
|
40198
40359
|
const config = loadServerConfig();
|
|
40199
40360
|
const role = getServerRole(flags, config);
|
|
@@ -40482,6 +40643,8 @@ Command Options:
|
|
|
40482
40643
|
|
|
40483
40644
|
caddy:
|
|
40484
40645
|
openmates server caddy check|status|diff|apply [--role core|upload|preview] [--config /etc/caddy/Caddyfile]
|
|
40646
|
+
openmates server caddy update [--path <installation>] [--role core|upload|preview] [--caddy-config <file>] [--dry-run]
|
|
40647
|
+
Merge the installed server release's configuration, preserve host edits, validate and reload.
|
|
40485
40648
|
|
|
40486
40649
|
reset:
|
|
40487
40650
|
--delete-user-data-only Only delete database and cache (preserve config)
|
|
@@ -40584,7 +40747,7 @@ async function handleServer(client2, subcommand, rest, flags) {
|
|
|
40584
40747
|
|
|
40585
40748
|
// src/codeRunInput.ts
|
|
40586
40749
|
import { readdir, readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
40587
|
-
import { basename as basename3, relative as relative2, resolve as
|
|
40750
|
+
import { basename as basename3, relative as relative2, resolve as resolve8 } from "path";
|
|
40588
40751
|
var CODE_RUN_MAX_FILES = 50;
|
|
40589
40752
|
var CODE_RUN_MAX_FILE_BYTES = 1e6;
|
|
40590
40753
|
var CODE_RUN_MAX_TOTAL_BYTES = 1e7;
|
|
@@ -40628,7 +40791,7 @@ async function buildCodeRunRequestsFromFlags(flags) {
|
|
|
40628
40791
|
}, buffer.byteLength);
|
|
40629
40792
|
}
|
|
40630
40793
|
for (const filePath of toList(flags.file)) {
|
|
40631
|
-
const absolute =
|
|
40794
|
+
const absolute = resolve8(filePath);
|
|
40632
40795
|
const buffer = await readFile2(absolute);
|
|
40633
40796
|
const sandboxPath = normalizeCodeRunPath(basename3(filePath));
|
|
40634
40797
|
addFile({
|
|
@@ -40640,7 +40803,7 @@ async function buildCodeRunRequestsFromFlags(flags) {
|
|
|
40640
40803
|
}, buffer.byteLength);
|
|
40641
40804
|
}
|
|
40642
40805
|
for (const dirPath of toList(flags.dir)) {
|
|
40643
|
-
const root =
|
|
40806
|
+
const root = resolve8(dirPath);
|
|
40644
40807
|
const dirFiles = await collectDirectoryFiles(root, flags.include, flags.exclude);
|
|
40645
40808
|
for (const absolute of dirFiles) {
|
|
40646
40809
|
const sandboxPath = normalizeCodeRunPath(relative2(root, absolute).replace(/\\/g, "/"));
|
|
@@ -40737,7 +40900,7 @@ async function collectDirectoryFiles(root, include, exclude) {
|
|
|
40737
40900
|
const files = [];
|
|
40738
40901
|
async function walk(directory) {
|
|
40739
40902
|
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
40740
|
-
const absolute =
|
|
40903
|
+
const absolute = resolve8(directory, entry.name);
|
|
40741
40904
|
const rel = relative2(root, absolute).replace(/\\/g, "/");
|
|
40742
40905
|
if (matchesAny(rel, excludes) || matchesAny(entry.name, excludes)) continue;
|
|
40743
40906
|
if (entry.isDirectory()) {
|
|
@@ -84129,7 +84292,7 @@ function buildAssistantFeedbackDecision(rating) {
|
|
|
84129
84292
|
import { createHash as createHash18, randomUUID as randomUUID15 } from "crypto";
|
|
84130
84293
|
import { existsSync as existsSync12, mkdtempSync as mkdtempSync3, readFileSync as readFileSync13, readdirSync as readdirSync6, writeFileSync as writeFileSync8 } from "fs";
|
|
84131
84294
|
import { tmpdir as tmpdir3 } from "os";
|
|
84132
|
-
import { dirname as dirname10, join as join16, resolve as
|
|
84295
|
+
import { dirname as dirname10, join as join16, resolve as resolve9 } from "path";
|
|
84133
84296
|
import { fileURLToPath } from "url";
|
|
84134
84297
|
var DEFAULT_JUDGE_MODEL = "google/gemini-3-flash-preview";
|
|
84135
84298
|
var DEFAULT_PROMPT_BUDGET_MODEL = "google/gemini-3.5-flash";
|
|
@@ -84543,7 +84706,7 @@ async function handleBenchmark(client2, subcommand, rest, flags) {
|
|
|
84543
84706
|
const dryRun = flags["dry-run"] === true;
|
|
84544
84707
|
const output = typeof flags.output === "string" ? flags.output : void 0;
|
|
84545
84708
|
const runId = typeof flags["run-id"] === "string" ? flags["run-id"] : randomUUID15();
|
|
84546
|
-
const imagePath = typeof flags.image === "string" ?
|
|
84709
|
+
const imagePath = typeof flags.image === "string" ? resolve9(flags.image) : defaultImageFixturePath();
|
|
84547
84710
|
if (!dryRun && flags["confirm-spend-credits"] !== true) {
|
|
84548
84711
|
throw new Error(
|
|
84549
84712
|
"Benchmark runs spend real credits from the logged-in account. Rerun with --confirm-spend-credits, or use --dry-run to preview the plan."
|
|
@@ -85355,7 +85518,7 @@ function findProvidersDir() {
|
|
|
85355
85518
|
const candidate = join16(current, "backend", "providers");
|
|
85356
85519
|
if (existsSync12(candidate)) return candidate;
|
|
85357
85520
|
const parentCandidate = join16(current, "..", "..", "backend", "providers");
|
|
85358
|
-
if (existsSync12(parentCandidate)) return
|
|
85521
|
+
if (existsSync12(parentCandidate)) return resolve9(parentCandidate);
|
|
85359
85522
|
const next = dirname10(current);
|
|
85360
85523
|
if (next === current) break;
|
|
85361
85524
|
current = next;
|
|
@@ -89747,8 +89910,8 @@ function watchTuiAuthoring(context, event, jobId) {
|
|
|
89747
89910
|
control.watching = true;
|
|
89748
89911
|
void (async () => {
|
|
89749
89912
|
for (let attempt = 0; attempt < 40 && context.state.chatContextAuthoringControls[event.event_id] === control; attempt++) {
|
|
89750
|
-
await new Promise((
|
|
89751
|
-
const timer = setTimeout(
|
|
89913
|
+
await new Promise((resolve18) => {
|
|
89914
|
+
const timer = setTimeout(resolve18, 3e3);
|
|
89752
89915
|
timer.unref();
|
|
89753
89916
|
});
|
|
89754
89917
|
if (context.state.chatContextAuthoringControls[event.event_id] !== control) return;
|
|
@@ -89801,16 +89964,16 @@ async function openTuiAuthoringExecutor(context, event) {
|
|
|
89801
89964
|
ws,
|
|
89802
89965
|
chatId: event.chat_id,
|
|
89803
89966
|
chatKey: key,
|
|
89804
|
-
requestApproval: (request) => new Promise((
|
|
89967
|
+
requestApproval: (request) => new Promise((resolve18) => {
|
|
89805
89968
|
if (approval) {
|
|
89806
|
-
|
|
89969
|
+
resolve18(false);
|
|
89807
89970
|
return;
|
|
89808
89971
|
}
|
|
89809
|
-
approval =
|
|
89972
|
+
approval = resolve18;
|
|
89810
89973
|
control.approve = () => {
|
|
89811
89974
|
approval = void 0;
|
|
89812
89975
|
control.approve = void 0;
|
|
89813
|
-
|
|
89976
|
+
resolve18(true);
|
|
89814
89977
|
};
|
|
89815
89978
|
const entry = context.state.chatContextAuthoringJobs[event.event_id];
|
|
89816
89979
|
if (entry) entry.status = "needs_write_approval";
|
|
@@ -91034,8 +91197,8 @@ async function runTui(client2, terminal = new TuiTerminal()) {
|
|
|
91034
91197
|
}).catch(() => {
|
|
91035
91198
|
});
|
|
91036
91199
|
}
|
|
91037
|
-
return new Promise((
|
|
91038
|
-
resolveResult =
|
|
91200
|
+
return new Promise((resolve18) => {
|
|
91201
|
+
resolveResult = resolve18;
|
|
91039
91202
|
});
|
|
91040
91203
|
}
|
|
91041
91204
|
async function handleKey(params) {
|
|
@@ -91873,17 +92036,17 @@ function clamp(value, min, max) {
|
|
|
91873
92036
|
import { createHash as createHash21 } from "crypto";
|
|
91874
92037
|
import { spawn as spawn3 } from "child_process";
|
|
91875
92038
|
import { existsSync as existsSync13, readFileSync as readFileSync14, readdirSync as readdirSync7 } from "fs";
|
|
91876
|
-
import { isAbsolute as
|
|
92039
|
+
import { isAbsolute as isAbsolute4, join as join17, resolve as resolve10 } from "path";
|
|
91877
92040
|
import lockfile4 from "proper-lockfile";
|
|
91878
92041
|
function startCodexTaskBridges(roots, snapshots, stateRoot, notice) {
|
|
91879
92042
|
const configPath = join17(stateRoot, "codex-adapter.json");
|
|
91880
92043
|
const children = [];
|
|
91881
92044
|
if (existsSync13(configPath)) {
|
|
91882
92045
|
const config = JSON.parse(readFileSync14(configPath, "utf8"));
|
|
91883
|
-
for (const root of new Set(roots.map((path2) =>
|
|
92046
|
+
for (const root of new Set(roots.map((path2) => resolve10(path2)))) {
|
|
91884
92047
|
const entry = config.repositories?.[root];
|
|
91885
|
-
if (!entry?.enabled || !entry.events_enabled || !entry.runtime || !
|
|
91886
|
-
if (!entry.snapshots?.length || !entry.snapshots.every((path2) => snapshots.includes(
|
|
92048
|
+
if (!entry?.enabled || !entry.events_enabled || !entry.runtime || !isAbsolute4(entry.runtime) || !existsSync13(entry.runtime)) continue;
|
|
92049
|
+
if (!entry.snapshots?.length || !entry.snapshots.every((path2) => snapshots.includes(resolve10(path2)))) continue;
|
|
91887
92050
|
const child = spawn3("python3", [entry.runtime, "serve", "--repository", root], {
|
|
91888
92051
|
cwd: root,
|
|
91889
92052
|
env: { ...process.env, OPENMATES_STATE_DIR: stateRoot },
|
|
@@ -92065,11 +92228,11 @@ import {
|
|
|
92065
92228
|
} from "fs";
|
|
92066
92229
|
import { spawn as spawn7 } from "child_process";
|
|
92067
92230
|
import { createHash as createHash28 } from "crypto";
|
|
92068
|
-
import { extname as extname4, join as join25, resolve as
|
|
92231
|
+
import { extname as extname4, join as join25, resolve as resolve16, relative as relative11 } from "path";
|
|
92069
92232
|
|
|
92070
92233
|
// src/projectSourceRootPolicy.ts
|
|
92071
92234
|
import { existsSync as existsSync15, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
92072
|
-
import { basename as basename4, dirname as dirname11, relative as relative3, resolve as
|
|
92235
|
+
import { basename as basename4, dirname as dirname11, relative as relative3, resolve as resolve11 } from "path";
|
|
92073
92236
|
function canonicalProjectSourceRoot(sourceRoot, options = {}) {
|
|
92074
92237
|
const root = realpathSync2(sourceRoot);
|
|
92075
92238
|
if (!statSync2(root).isDirectory()) throw new Error("Project source root is not a directory");
|
|
@@ -92083,15 +92246,15 @@ function canonicalOpenMatesStateDirectory(stateDirectory = resolveStateDir()) {
|
|
|
92083
92246
|
return canonicalizePotentialPath(stateDirectory);
|
|
92084
92247
|
}
|
|
92085
92248
|
function canonicalizePotentialPath(value) {
|
|
92086
|
-
let existing =
|
|
92249
|
+
let existing = resolve11(value);
|
|
92087
92250
|
const suffix = [];
|
|
92088
92251
|
while (!existsSync15(existing)) {
|
|
92089
92252
|
const parent = dirname11(existing);
|
|
92090
|
-
if (parent === existing) return
|
|
92253
|
+
if (parent === existing) return resolve11(value);
|
|
92091
92254
|
suffix.unshift(basename4(existing));
|
|
92092
92255
|
existing = parent;
|
|
92093
92256
|
}
|
|
92094
|
-
return
|
|
92257
|
+
return resolve11(realpathSync2(existing), ...suffix);
|
|
92095
92258
|
}
|
|
92096
92259
|
function isEqualOrInside(parent, candidate) {
|
|
92097
92260
|
const path2 = relative3(parent, candidate);
|
|
@@ -92119,7 +92282,7 @@ import {
|
|
|
92119
92282
|
unlinkSync,
|
|
92120
92283
|
writeSync
|
|
92121
92284
|
} from "fs";
|
|
92122
|
-
import { dirname as dirname12, isAbsolute as
|
|
92285
|
+
import { dirname as dirname12, isAbsolute as isAbsolute5, join as join19, relative as relative4, resolve as resolve12 } from "path";
|
|
92123
92286
|
var DEFAULT_MAX_IGNORE_FILES = 128;
|
|
92124
92287
|
var DEFAULT_MAX_IGNORE_BYTES = 1024 * 1024;
|
|
92125
92288
|
var MAX_POLICY_ENTRIES = 5e4;
|
|
@@ -92245,7 +92408,7 @@ function collectIgnoreFiles(policyRoot, sourceRoot, limits) {
|
|
|
92245
92408
|
for (const directory of chain.reverse()) add(join19(directory, ".gitignore"));
|
|
92246
92409
|
for (const target of limits.targetPaths) {
|
|
92247
92410
|
const normalized = target === "." ? "" : normalizeSourceRelativePath(target);
|
|
92248
|
-
const absolute = normalized ?
|
|
92411
|
+
const absolute = normalized ? resolve12(sourceRoot, normalized) : sourceRoot;
|
|
92249
92412
|
if (!isInside2(sourceRoot, absolute)) throw new Error("Project policy target escapes its source root");
|
|
92250
92413
|
const targetIsDirectory = existsSync16(absolute) && lstatSync4(absolute).isDirectory();
|
|
92251
92414
|
let directory = targetIsDirectory ? absolute : dirname12(absolute);
|
|
@@ -92285,7 +92448,7 @@ function collectIgnoreFiles(policyRoot, sourceRoot, limits) {
|
|
|
92285
92448
|
return files;
|
|
92286
92449
|
}
|
|
92287
92450
|
function updateStickyPrivatePaths(sourceRoot, additions, stateDirectory) {
|
|
92288
|
-
const stateRoot =
|
|
92451
|
+
const stateRoot = resolve12(stateDirectory, POLICY_STATE_DIRECTORY);
|
|
92289
92452
|
if (isInside2(sourceRoot, stateRoot) || isInside2(stateRoot, sourceRoot)) {
|
|
92290
92453
|
throw new Error("Project path policy state must stay outside the source root");
|
|
92291
92454
|
}
|
|
@@ -92359,7 +92522,7 @@ function preparePrivateDirectory(path2) {
|
|
|
92359
92522
|
if (!statSync3(path2).isDirectory()) throw new Error("Project path policy state is not a directory");
|
|
92360
92523
|
}
|
|
92361
92524
|
function normalizeSourceRelativePath(value) {
|
|
92362
|
-
if (typeof value !== "string" || !value || value.includes("\\") ||
|
|
92525
|
+
if (typeof value !== "string" || !value || value.includes("\\") || isAbsolute5(value) || value.split("/").some((part) => !part || part === "." || part === "..") || [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) {
|
|
92363
92526
|
throw new ProjectPathPolicyError(`Project path is invalid: ${String(value)}`);
|
|
92364
92527
|
}
|
|
92365
92528
|
return value;
|
|
@@ -92367,7 +92530,7 @@ function normalizeSourceRelativePath(value) {
|
|
|
92367
92530
|
function normalizeRelative(root, target) {
|
|
92368
92531
|
const result = relative4(root, target).split("\\").join("/");
|
|
92369
92532
|
if (!result || result === ".") return "";
|
|
92370
|
-
if (result.startsWith("../") || result === ".." ||
|
|
92533
|
+
if (result.startsWith("../") || result === ".." || isAbsolute5(result)) throw new Error("Project policy path escapes its root");
|
|
92371
92534
|
return result;
|
|
92372
92535
|
}
|
|
92373
92536
|
function boundedInteger(value, fallback2, label3) {
|
|
@@ -92376,8 +92539,8 @@ function boundedInteger(value, fallback2, label3) {
|
|
|
92376
92539
|
return result;
|
|
92377
92540
|
}
|
|
92378
92541
|
function isInside2(root, candidate) {
|
|
92379
|
-
const relation = relative4(
|
|
92380
|
-
return relation === "" || !relation.startsWith("..") && !
|
|
92542
|
+
const relation = relative4(resolve12(root), resolve12(candidate));
|
|
92543
|
+
return relation === "" || !relation.startsWith("..") && !isAbsolute5(relation);
|
|
92381
92544
|
}
|
|
92382
92545
|
function sha2562(value) {
|
|
92383
92546
|
return createHash23("sha256").update(value).digest("hex");
|
|
@@ -92410,7 +92573,7 @@ import {
|
|
|
92410
92573
|
writeFileSync as writeFileSync9
|
|
92411
92574
|
} from "fs";
|
|
92412
92575
|
import { tmpdir as tmpdir5 } from "os";
|
|
92413
|
-
import { basename as basename5, dirname as dirname13, isAbsolute as
|
|
92576
|
+
import { basename as basename5, dirname as dirname13, isAbsolute as isAbsolute6, join as join21, relative as relative5, resolve as resolve13 } from "path";
|
|
92414
92577
|
import lockfile6 from "proper-lockfile";
|
|
92415
92578
|
|
|
92416
92579
|
// src/projectFileRisk.ts
|
|
@@ -92770,7 +92933,7 @@ function validateMutation(input) {
|
|
|
92770
92933
|
return { ...parsed, path: validateRelativePath(parsed.path) };
|
|
92771
92934
|
}
|
|
92772
92935
|
function validateRelativePath(value) {
|
|
92773
|
-
if (typeof value !== "string" || value.length === 0 || value.length > 4096 ||
|
|
92936
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 4096 || isAbsolute6(value) || value.includes("\\") || [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127) || value.split("/").some((part) => !part || part === "." || part === "..")) {
|
|
92774
92937
|
throw new RemoteFileMutationError("invalid_path", "Project file path must be a strict root-relative POSIX path");
|
|
92775
92938
|
}
|
|
92776
92939
|
return value;
|
|
@@ -93063,7 +93226,7 @@ function temporaryName() {
|
|
|
93063
93226
|
}
|
|
93064
93227
|
function isInside3(root, candidate) {
|
|
93065
93228
|
const relation = relative5(root, candidate);
|
|
93066
|
-
return relation === "" || !relation.startsWith("..") && !
|
|
93229
|
+
return relation === "" || !relation.startsWith("..") && !isAbsolute6(relation) && resolve13(root, relation) === resolve13(candidate);
|
|
93067
93230
|
}
|
|
93068
93231
|
|
|
93069
93232
|
// src/remoteFileTransfers.ts
|
|
@@ -93340,19 +93503,19 @@ async function executeRemoteFileTransfer(input) {
|
|
|
93340
93503
|
|
|
93341
93504
|
// src/remoteCommandSource.ts
|
|
93342
93505
|
import { existsSync as existsSync21, realpathSync as realpathSync10, statSync as statSync9 } from "fs";
|
|
93343
|
-
import { basename as basename7, dirname as dirname14, relative as relative10, resolve as
|
|
93506
|
+
import { basename as basename7, dirname as dirname14, relative as relative10, resolve as resolve15 } from "path";
|
|
93344
93507
|
|
|
93345
93508
|
// src/remoteCommandRuntime.ts
|
|
93346
93509
|
import { createHash as createHash26, randomUUID as randomUUID21 } from "crypto";
|
|
93347
93510
|
import { spawn as spawn6, spawnSync as spawnSync4 } from "child_process";
|
|
93348
93511
|
import { existsSync as existsSync19, lstatSync as lstatSync9, readdirSync as readdirSync11, realpathSync as realpathSync7, statSync as statSync6 } from "fs";
|
|
93349
|
-
import { isAbsolute as
|
|
93512
|
+
import { isAbsolute as isAbsolute8, join as join22, relative as relative7, resolve as resolve14, sep } from "path";
|
|
93350
93513
|
|
|
93351
93514
|
// src/remoteCommandAppArmor.ts
|
|
93352
93515
|
import { createHash as createHash25 } from "crypto";
|
|
93353
93516
|
import { spawn as spawn5 } from "child_process";
|
|
93354
93517
|
import { lstatSync as lstatSync8, readFileSync as readFileSync17, realpathSync as realpathSync6, statSync as statSync5 } from "fs";
|
|
93355
|
-
import { isAbsolute as
|
|
93518
|
+
import { isAbsolute as isAbsolute7, relative as relative6 } from "path";
|
|
93356
93519
|
var REMOTE_COMMAND_APPARMOR_BROKER = "/usr/libexec/openmates-command-apparmor";
|
|
93357
93520
|
var REMOTE_COMMAND_APPARMOR_EXEC = "/usr/bin/aa-exec";
|
|
93358
93521
|
var REMOTE_COMMAND_BWRAP = "/usr/libexec/openmates-bwrap";
|
|
@@ -93534,7 +93697,7 @@ function validatePolicyGlob(value, context) {
|
|
|
93534
93697
|
return normalized;
|
|
93535
93698
|
}
|
|
93536
93699
|
function validateProjectPath(value, context) {
|
|
93537
|
-
if (typeof value !== "string" || !value || Buffer.byteLength(value) > MAX_POLICY_PATH_BYTES ||
|
|
93700
|
+
if (typeof value !== "string" || !value || Buffer.byteLength(value) > MAX_POLICY_PATH_BYTES || isAbsolute7(value) || value.includes("\\") || value.includes("*") || value.includes("?") || value.split("/").some((part) => !part || part === "." || part === "..") || hasControl2(value)) {
|
|
93538
93701
|
throw new Error(`Invalid AppArmor ${context} path`);
|
|
93539
93702
|
}
|
|
93540
93703
|
return value;
|
|
@@ -93557,7 +93720,7 @@ function brokerIdentifier(value, context, pattern) {
|
|
|
93557
93720
|
}
|
|
93558
93721
|
function isInside4(root, candidate) {
|
|
93559
93722
|
const path2 = relative6(root, candidate);
|
|
93560
|
-
return path2 === "" || !path2.startsWith("..") && !
|
|
93723
|
+
return path2 === "" || !path2.startsWith("..") && !isAbsolute7(path2);
|
|
93561
93724
|
}
|
|
93562
93725
|
function hasControl2(value) {
|
|
93563
93726
|
return [...value].some((character) => {
|
|
@@ -93810,7 +93973,7 @@ var RemoteCommandRuntime = class {
|
|
|
93810
93973
|
}
|
|
93811
93974
|
if (prepared.sandbox_command) {
|
|
93812
93975
|
const command = prepared.sandbox_command;
|
|
93813
|
-
if (!
|
|
93976
|
+
if (!isAbsolute8(command.executable) || command.executable.includes("\0") || !Array.isArray(command.args) || command.args.some((argument) => typeof argument !== "string" || argument.includes("\0"))) {
|
|
93814
93977
|
throw new RemoteCommandError("network_profile_unavailable", "Network transport returned an invalid sandbox bridge command");
|
|
93815
93978
|
}
|
|
93816
93979
|
}
|
|
@@ -94134,7 +94297,7 @@ function prepareSandboxLaunch(preflight, authority, capability, network, appArmo
|
|
|
94134
94297
|
}
|
|
94135
94298
|
}
|
|
94136
94299
|
const appArmorEnvironment = appArmor.sandbox_environment;
|
|
94137
|
-
if (!appArmorEnvironment || Object.keys(appArmorEnvironment).length !== 1 || typeof appArmorEnvironment.LD_PRELOAD !== "string" || !
|
|
94300
|
+
if (!appArmorEnvironment || Object.keys(appArmorEnvironment).length !== 1 || typeof appArmorEnvironment.LD_PRELOAD !== "string" || !isAbsolute8(appArmorEnvironment.LD_PRELOAD) || appArmorEnvironment.LD_PRELOAD.includes("\0")) {
|
|
94138
94301
|
throw new RemoteCommandError("confinement_unavailable", "AppArmor confinement returned an invalid Git config compatibility library");
|
|
94139
94302
|
}
|
|
94140
94303
|
const environment = { ...SAFE_ENVIRONMENT, ...networkEnvironment, ...appArmorEnvironment };
|
|
@@ -94218,7 +94381,7 @@ function validatePolicy2(policy) {
|
|
|
94218
94381
|
if (policy.source_access !== "read_only" && policy.source_access !== "read_write") throw new RemoteCommandError("invalid_request", "Invalid source access");
|
|
94219
94382
|
if (policy.mode === "background" && policy.source_access !== "read_only") throw new RemoteCommandError("invalid_request", "Background commands must use read-only source access");
|
|
94220
94383
|
if (!Number.isSafeInteger(policy.deadline_ms) || policy.deadline_ms < MIN_DEADLINE_MS2 || policy.deadline_ms > MAX_DEADLINE_MS2) throw new RemoteCommandError("invalid_request", "Invalid command deadline");
|
|
94221
|
-
if (
|
|
94384
|
+
if (isAbsolute8(policy.cwd) || policy.cwd.includes("\0") || policy.cwd.split(/[\\/]/).includes("..")) throw new RemoteCommandError("invalid_request", "Command cwd must stay inside the Project");
|
|
94222
94385
|
for (const [name, value] of [["writable_profiles", policy.writable_profiles], ["credential_profiles", policy.credential_profiles]]) {
|
|
94223
94386
|
if (!Array.isArray(value) || value.some((id) => typeof id !== "string" || !/^[a-z][a-z0-9-]{0,63}$/.test(id))) throw new RemoteCommandError("invalid_request", `Invalid ${name}`);
|
|
94224
94387
|
assertUnique2(value, name);
|
|
@@ -94323,7 +94486,7 @@ function assertCapability(capability) {
|
|
|
94323
94486
|
}
|
|
94324
94487
|
function canonicalDirectory(path2) {
|
|
94325
94488
|
const canonical = realpath(path2);
|
|
94326
|
-
if (canonical ===
|
|
94489
|
+
if (canonical === resolve14("/")) throw new RemoteCommandError("invalid_request", "The host filesystem root cannot be mounted as a command resource");
|
|
94327
94490
|
if (!statSync6(canonical).isDirectory()) throw new RemoteCommandError("invalid_request", `Command resource is not a directory: ${path2}`);
|
|
94328
94491
|
return canonical;
|
|
94329
94492
|
}
|
|
@@ -94392,7 +94555,7 @@ function assertUnique2(values, context) {
|
|
|
94392
94555
|
}
|
|
94393
94556
|
function isInside5(root, candidate) {
|
|
94394
94557
|
const path2 = relative7(root, candidate);
|
|
94395
|
-
return path2 === "" || !path2.startsWith("..") && !
|
|
94558
|
+
return path2 === "" || !path2.startsWith("..") && !isAbsolute8(path2);
|
|
94396
94559
|
}
|
|
94397
94560
|
function truncateUtf8(value, maximum) {
|
|
94398
94561
|
const bytes2 = Buffer.from(value);
|
|
@@ -94422,7 +94585,7 @@ import { lookup as dnsLookup } from "dns/promises";
|
|
|
94422
94585
|
import { chmodSync as chmodSync10, mkdtempSync as mkdtempSync4, realpathSync as realpathSync8, rmSync as rmSync9, statSync as statSync7, writeFileSync as writeFileSync10 } from "fs";
|
|
94423
94586
|
import { isIP as isIP2, createConnection, createServer } from "net";
|
|
94424
94587
|
import { tmpdir as tmpdir6 } from "os";
|
|
94425
|
-
import { isAbsolute as
|
|
94588
|
+
import { isAbsolute as isAbsolute9, join as join23, relative as relative8 } from "path";
|
|
94426
94589
|
var DEFAULT_BRIDGE_PORT = 43117;
|
|
94427
94590
|
var MAX_CONNECT_HEADER_BYTES = 8 * 1024;
|
|
94428
94591
|
var CONNECT_HEADER_TIMEOUT_MS = 1e4;
|
|
@@ -94626,7 +94789,7 @@ function createPrivateControlDirectory(preflight, configuredRoots) {
|
|
|
94626
94789
|
const roots = configuredRoots ?? [process.env.XDG_RUNTIME_DIR, tmpdir6()].filter((value) => Boolean(value));
|
|
94627
94790
|
for (const candidate of roots) {
|
|
94628
94791
|
try {
|
|
94629
|
-
if (!
|
|
94792
|
+
if (!isAbsolute9(candidate) || !statSync7(candidate).isDirectory()) continue;
|
|
94630
94793
|
const root = realpathSync8(candidate);
|
|
94631
94794
|
const directory = mkdtempSync4(join23(root, "openmates-command-network-"));
|
|
94632
94795
|
chmodSync10(directory, 448);
|
|
@@ -94663,7 +94826,7 @@ function ipv6Words(address) {
|
|
|
94663
94826
|
}
|
|
94664
94827
|
function isInside6(root, candidate) {
|
|
94665
94828
|
const path2 = relative8(root, candidate);
|
|
94666
|
-
return path2 === "" || !path2.startsWith("..") && !
|
|
94829
|
+
return path2 === "" || !path2.startsWith("..") && !isAbsolute9(path2);
|
|
94667
94830
|
}
|
|
94668
94831
|
function listenUnix(server2, path2) {
|
|
94669
94832
|
return new Promise((resolvePromise, reject) => {
|
|
@@ -94687,7 +94850,7 @@ function capabilityError(message) {
|
|
|
94687
94850
|
// src/remoteCommandResourceGrants.ts
|
|
94688
94851
|
import { createHash as createHash27 } from "crypto";
|
|
94689
94852
|
import { chmodSync as chmodSync11, existsSync as existsSync20, lstatSync as lstatSync10, mkdirSync as mkdirSync17, readFileSync as readFileSync18, realpathSync as realpathSync9, renameSync as renameSync8, statSync as statSync8, writeFileSync as writeFileSync11 } from "fs";
|
|
94690
|
-
import { isAbsolute as
|
|
94853
|
+
import { isAbsolute as isAbsolute10, join as join24, relative as relative9 } from "path";
|
|
94691
94854
|
var STORE_FILE = "remote-command-resource-grants.json";
|
|
94692
94855
|
var ID = /^[a-z][a-z0-9-]{0,63}$/;
|
|
94693
94856
|
var ENV = /^[A-Z_][A-Z0-9_]{0,127}$/;
|
|
@@ -94700,7 +94863,7 @@ function listRemoteCommandResourceGrants(projectId, sourceId) {
|
|
|
94700
94863
|
function enableRemoteCommandWritableGrant(input) {
|
|
94701
94864
|
const definition = input.permissions.resource_profiles.writable.find((item) => item.id === input.profileId);
|
|
94702
94865
|
if (!definition) throw new Error(`Unknown writable profile: ${input.profileId}`);
|
|
94703
|
-
if (!
|
|
94866
|
+
if (!isAbsolute10(input.hostPath)) throw new Error("--host-path must be absolute");
|
|
94704
94867
|
const root = realpathSync9(input.projectRoot);
|
|
94705
94868
|
const hostPath = realpathSync9(input.hostPath);
|
|
94706
94869
|
if (!statSync8(hostPath).isDirectory()) throw new Error("Writable profile host path must be a directory");
|
|
@@ -94813,7 +94976,7 @@ function validateIdentity(projectId, sourceId, profileId) {
|
|
|
94813
94976
|
}
|
|
94814
94977
|
function isInside7(parent, child) {
|
|
94815
94978
|
const value = relative9(parent, child);
|
|
94816
|
-
return value !== "" && !value.startsWith("..") && !
|
|
94979
|
+
return value !== "" && !value.startsWith("..") && !isAbsolute10(value);
|
|
94817
94980
|
}
|
|
94818
94981
|
function pathsOverlap2(left, right) {
|
|
94819
94982
|
return left === right || isInside7(left, right) || isInside7(right, left);
|
|
@@ -95654,14 +95817,14 @@ function canonicalStateDirectory() {
|
|
|
95654
95817
|
const path2 = resolveStateDir();
|
|
95655
95818
|
if (existsSync21(path2)) return realpathSync10(path2);
|
|
95656
95819
|
const tail = [];
|
|
95657
|
-
let parent =
|
|
95820
|
+
let parent = resolve15(path2);
|
|
95658
95821
|
while (!existsSync21(parent)) {
|
|
95659
95822
|
const next = dirname14(parent);
|
|
95660
95823
|
if (next === parent) break;
|
|
95661
95824
|
tail.unshift(basename7(parent));
|
|
95662
95825
|
parent = next;
|
|
95663
95826
|
}
|
|
95664
|
-
return
|
|
95827
|
+
return resolve15(realpathSync10(parent), ...tail);
|
|
95665
95828
|
}
|
|
95666
95829
|
function pathsOverlap3(left, right) {
|
|
95667
95830
|
return left === right || isInsideDirectory(left, right) || isInsideDirectory(right, left);
|
|
@@ -95754,7 +95917,7 @@ function resolveRemoteAccessRoots(pathFlag, cwd = process.cwd()) {
|
|
|
95754
95917
|
}
|
|
95755
95918
|
const roots = [];
|
|
95756
95919
|
for (const value of requested) {
|
|
95757
|
-
const candidate =
|
|
95920
|
+
const candidate = resolve16(cwd, value);
|
|
95758
95921
|
if (!existsSync22(candidate) || !statSync10(candidate).isDirectory()) {
|
|
95759
95922
|
throw new Error(`Remote source path does not exist or is not a directory: ${candidate}`);
|
|
95760
95923
|
}
|
|
@@ -96526,7 +96689,7 @@ function resolveRemoteCachePath(sourceId, homeDirectory) {
|
|
|
96526
96689
|
}
|
|
96527
96690
|
function startRemoteAccessSource(input) {
|
|
96528
96691
|
assertSafeSourceId(input.sourceId);
|
|
96529
|
-
const requestedRootPath =
|
|
96692
|
+
const requestedRootPath = resolve16(input.rootPath);
|
|
96530
96693
|
if (!existsSync22(requestedRootPath) || !statSync10(requestedRootPath).isDirectory()) {
|
|
96531
96694
|
throw new Error(`Remote source path does not exist or is not a directory: ${requestedRootPath}`);
|
|
96532
96695
|
}
|
|
@@ -97046,9 +97209,9 @@ function minimalRgEnvironment() {
|
|
|
97046
97209
|
return env;
|
|
97047
97210
|
}
|
|
97048
97211
|
function isPathInsideRoot(sourceRoot, relativePath2) {
|
|
97049
|
-
const resolvedPath =
|
|
97212
|
+
const resolvedPath = resolve16(sourceRoot, relativePath2);
|
|
97050
97213
|
const relation = relative11(sourceRoot, resolvedPath);
|
|
97051
|
-
return relation === "" || !relation.startsWith("..") && !
|
|
97214
|
+
return relation === "" || !relation.startsWith("..") && !resolve16(relation).startsWith("/..");
|
|
97052
97215
|
}
|
|
97053
97216
|
function isBinaryPath(path2) {
|
|
97054
97217
|
const lowerPath = path2.toLowerCase();
|
|
@@ -97087,7 +97250,7 @@ function hasControlCharacters3(value) {
|
|
|
97087
97250
|
}
|
|
97088
97251
|
function resolveApprovedPath(sourceRoot, relativePath2) {
|
|
97089
97252
|
if (!relativePath2 || relativePath2.includes("\0")) throw new Error("Remote source path is invalid");
|
|
97090
|
-
const lexical =
|
|
97253
|
+
const lexical = resolve16(sourceRoot, relativePath2);
|
|
97091
97254
|
assertInsideRoot(sourceRoot, lexical);
|
|
97092
97255
|
const relation = relative11(sourceRoot, lexical);
|
|
97093
97256
|
let current = sourceRoot;
|
|
@@ -97101,7 +97264,7 @@ function resolveApprovedPath(sourceRoot, relativePath2) {
|
|
|
97101
97264
|
}
|
|
97102
97265
|
function assertInsideRoot(sourceRoot, path2) {
|
|
97103
97266
|
const relation = relative11(sourceRoot, path2);
|
|
97104
|
-
if (relation.startsWith("..") ||
|
|
97267
|
+
if (relation.startsWith("..") || resolve16(sourceRoot, relation) !== resolve16(path2)) {
|
|
97105
97268
|
throw new Error("Remote source path escapes the approved source root");
|
|
97106
97269
|
}
|
|
97107
97270
|
}
|
|
@@ -97229,10 +97392,10 @@ async function ensureRemoteCommandSetup(options, dependencies = {}) {
|
|
|
97229
97392
|
return { installed: true, capability: installed };
|
|
97230
97393
|
}
|
|
97231
97394
|
function inheritedInstaller(executable, args) {
|
|
97232
|
-
return new Promise((
|
|
97395
|
+
return new Promise((resolve18, reject) => {
|
|
97233
97396
|
const child = spawn8(executable, args, { stdio: "inherit" });
|
|
97234
97397
|
child.once("error", reject);
|
|
97235
|
-
child.once("close", (code, signal) =>
|
|
97398
|
+
child.once("close", (code, signal) => resolve18({ code, signal }));
|
|
97236
97399
|
});
|
|
97237
97400
|
}
|
|
97238
97401
|
|
|
@@ -97614,7 +97777,7 @@ import { execFileSync as execFileSync5 } from "child_process";
|
|
|
97614
97777
|
import { createSign, randomUUID as randomUUID22 } from "crypto";
|
|
97615
97778
|
import { chmodSync as chmodSync13, existsSync as existsSync23, mkdirSync as mkdirSync21, readFileSync as readFileSync21 } from "fs";
|
|
97616
97779
|
import { homedir as homedir6 } from "os";
|
|
97617
|
-
import { join as join27, resolve as
|
|
97780
|
+
import { join as join27, resolve as resolve17 } from "path";
|
|
97618
97781
|
var REVOLUT_BUSINESS_CERTIFICATE_DOCS_URL = "https://developer.revolut.com/docs/guides/manage-accounts/get-started/make-your-first-api-request#generate-a-private-and-a-public-certificate";
|
|
97619
97782
|
var REVOLUT_BUSINESS_DEFAULT_SANDBOX_REDIRECT_URI = "https://app.dev.openmates.org/oauth/revolut-business/callback";
|
|
97620
97783
|
var REVOLUT_BUSINESS_DEFAULT_PRODUCTION_REDIRECT_URI = "https://openmates.org/oauth/revolut-business/callback";
|
|
@@ -97695,7 +97858,7 @@ function generateRevolutBusinessClientAssertion(options) {
|
|
|
97695
97858
|
}
|
|
97696
97859
|
function generateRevolutBusinessCertificate(options = {}) {
|
|
97697
97860
|
const environment = options.environment ?? "sandbox";
|
|
97698
|
-
const outputDir =
|
|
97861
|
+
const outputDir = resolve17(options.outputDir ?? defaultRevolutBusinessCertificateDir(environment));
|
|
97699
97862
|
const title = (options.title ?? REVOLUT_BUSINESS_DEFAULT_CERTIFICATE_TITLE).trim();
|
|
97700
97863
|
const redirectUri = (options.redirectUri ?? defaultRevolutBusinessRedirectUri(environment)).trim();
|
|
97701
97864
|
if (!title) throw new Error("Revolut certificate title must not be empty.");
|
|
@@ -97988,7 +98151,7 @@ async function main() {
|
|
|
97988
98151
|
return;
|
|
97989
98152
|
}
|
|
97990
98153
|
if (command === "update" || command === "upgrade") {
|
|
97991
|
-
handleSelfUpdate(command, parsed.flags);
|
|
98154
|
+
await handleSelfUpdate(command, parsed.flags);
|
|
97992
98155
|
return;
|
|
97993
98156
|
}
|
|
97994
98157
|
if (command === "login") {
|
|
@@ -98202,7 +98365,15 @@ function handleSupport(flags) {
|
|
|
98202
98365
|
}
|
|
98203
98366
|
console.log(renderSupportInfo());
|
|
98204
98367
|
}
|
|
98205
|
-
function handleSelfUpdate(command, flags) {
|
|
98368
|
+
async function handleSelfUpdate(command, flags) {
|
|
98369
|
+
if (flags["caddy-config"] === true) throw new Error("Provide --caddy-config <file>.");
|
|
98370
|
+
const reportCaddy = async () => {
|
|
98371
|
+
const caddy = await updateCaddyAfterCliUpgrade(flags);
|
|
98372
|
+
if (caddy) {
|
|
98373
|
+
console.log(`Caddy: ${caddy.status}`);
|
|
98374
|
+
if ("retryCommand" in caddy) console.log(`Run: ${caddy.retryCommand}`);
|
|
98375
|
+
}
|
|
98376
|
+
};
|
|
98206
98377
|
let plan = buildSelfUpdatePlan(flags);
|
|
98207
98378
|
const status = checkSelfUpdateStatus(plan);
|
|
98208
98379
|
if (status.checkError) throw new Error(`Update check failed: ${status.checkError}`);
|
|
@@ -98213,6 +98384,7 @@ function handleSelfUpdate(command, flags) {
|
|
|
98213
98384
|
if (flags.json === true) {
|
|
98214
98385
|
if (!plan.dryRun && shouldInstall) runSelfUpdate(plan, { verbose: flags.verbose === true });
|
|
98215
98386
|
persistSelfUpdateChannel(plan);
|
|
98387
|
+
const caddy = await updateCaddyAfterCliUpgrade(flags);
|
|
98216
98388
|
printJson2({
|
|
98217
98389
|
command,
|
|
98218
98390
|
channel: plan.channel,
|
|
@@ -98224,7 +98396,8 @@ function handleSelfUpdate(command, flags) {
|
|
|
98224
98396
|
package_manager: plan.packageManager,
|
|
98225
98397
|
package: plan.packageSpec,
|
|
98226
98398
|
run: [plan.command, ...plan.args],
|
|
98227
|
-
dry_run: plan.dryRun
|
|
98399
|
+
dry_run: plan.dryRun,
|
|
98400
|
+
...caddy ? { caddy } : {}
|
|
98228
98401
|
});
|
|
98229
98402
|
return;
|
|
98230
98403
|
}
|
|
@@ -98242,22 +98415,26 @@ function handleSelfUpdate(command, flags) {
|
|
|
98242
98415
|
if (plan.dryRun) {
|
|
98243
98416
|
if (status.updateAvailable === false) {
|
|
98244
98417
|
console.log("OpenMates CLI is already up to date.");
|
|
98418
|
+
await reportCaddy();
|
|
98245
98419
|
return;
|
|
98246
98420
|
}
|
|
98247
98421
|
console.log(`Would run: ${[plan.command, ...plan.args].join(" ")}`);
|
|
98422
|
+
await reportCaddy();
|
|
98248
98423
|
return;
|
|
98249
98424
|
}
|
|
98250
98425
|
if (status.updateAvailable === false) {
|
|
98251
98426
|
persistSelfUpdateChannel(plan);
|
|
98252
98427
|
console.log("OpenMates CLI is already up to date.");
|
|
98428
|
+
await reportCaddy();
|
|
98253
98429
|
return;
|
|
98254
98430
|
}
|
|
98255
98431
|
console.log(`Updating OpenMates CLI with ${plan.packageManager}...`);
|
|
98256
98432
|
runSelfUpdate(plan, { verbose: flags.verbose === true });
|
|
98257
98433
|
persistSelfUpdateChannel(plan);
|
|
98258
98434
|
console.log(`Installed OpenMates CLI ${status.latestVersion ?? plan.target}.`);
|
|
98435
|
+
await reportCaddy();
|
|
98259
98436
|
console.log("");
|
|
98260
|
-
console.log("OpenMates is up to date.");
|
|
98437
|
+
console.log("OpenMates CLI is up to date.");
|
|
98261
98438
|
}
|
|
98262
98439
|
function handleCliVersion(flags) {
|
|
98263
98440
|
const planFlags = { ...flags, "dry-run": true };
|
|
@@ -102520,10 +102697,10 @@ Run 'openmates chats show ` + chatId + "' to check if suggestions have been save
|
|
|
102520
102697
|
input: process.stdin,
|
|
102521
102698
|
output: process.stdout
|
|
102522
102699
|
});
|
|
102523
|
-
const answer = await new Promise((
|
|
102700
|
+
const answer = await new Promise((resolve18) => {
|
|
102524
102701
|
iface.question(
|
|
102525
102702
|
`Delete ${resolved.length} chat(s)? This cannot be undone. [y/N] `,
|
|
102526
|
-
|
|
102703
|
+
resolve18
|
|
102527
102704
|
);
|
|
102528
102705
|
});
|
|
102529
102706
|
iface.close();
|
|
@@ -103275,7 +103452,7 @@ async function waitForWorkflowRun(client2, workflowId, initialRun, options = {})
|
|
|
103275
103452
|
clearTimeout(timer);
|
|
103276
103453
|
}
|
|
103277
103454
|
}
|
|
103278
|
-
const pause = () => withinBudget(() => new Promise((
|
|
103455
|
+
const pause = () => withinBudget(() => new Promise((resolve18) => setTimeout(resolve18, Math.min(options.pollIntervalMs ?? 2e3, deadline - Date.now()))));
|
|
103279
103456
|
const refresh = async () => {
|
|
103280
103457
|
run = await withinBudget(() => client2.getWorkflowRun(workflowId, runId));
|
|
103281
103458
|
};
|
|
@@ -104883,7 +105060,7 @@ async function handleCodeRun(client2, flags, apiKey) {
|
|
|
104883
105060
|
}
|
|
104884
105061
|
}
|
|
104885
105062
|
async function streamCodeRunToTerminal(url, jsonMode) {
|
|
104886
|
-
return await new Promise((
|
|
105063
|
+
return await new Promise((resolve18, reject) => {
|
|
104887
105064
|
const ws = new WebSocket3(url);
|
|
104888
105065
|
let lastStatus = {};
|
|
104889
105066
|
ws.on("message", (data) => {
|
|
@@ -104902,7 +105079,7 @@ async function streamCodeRunToTerminal(url, jsonMode) {
|
|
|
104902
105079
|
const status = String(payload.status ?? "");
|
|
104903
105080
|
if (["finished", "failed", "timeout", "cancelled"].includes(status)) {
|
|
104904
105081
|
ws.close();
|
|
104905
|
-
|
|
105082
|
+
resolve18(lastStatus);
|
|
104906
105083
|
}
|
|
104907
105084
|
}
|
|
104908
105085
|
} catch (err) {
|
|
@@ -104912,7 +105089,7 @@ async function streamCodeRunToTerminal(url, jsonMode) {
|
|
|
104912
105089
|
});
|
|
104913
105090
|
ws.on("error", () => reject(new Error("Code Run stream failed.")));
|
|
104914
105091
|
ws.on("close", () => {
|
|
104915
|
-
if (Object.keys(lastStatus).length > 0)
|
|
105092
|
+
if (Object.keys(lastStatus).length > 0) resolve18(lastStatus);
|
|
104916
105093
|
});
|
|
104917
105094
|
});
|
|
104918
105095
|
}
|
|
@@ -104923,7 +105100,7 @@ async function pollCodeRunStatus(client2, statusPath, apiKey, jsonMode) {
|
|
|
104923
105100
|
if (!jsonMode && value) process.stderr.write(`Code Run status: ${value}
|
|
104924
105101
|
`);
|
|
104925
105102
|
if (["finished", "failed", "timeout", "cancelled"].includes(value)) return status;
|
|
104926
|
-
await new Promise((
|
|
105103
|
+
await new Promise((resolve18) => setTimeout(resolve18, 1e3));
|
|
104927
105104
|
}
|
|
104928
105105
|
}
|
|
104929
105106
|
async function suggestAppOrSkill(client2, app, skill, apiKey) {
|
|
@@ -105205,7 +105382,7 @@ async function waitForApplicationPreview(client2, started, flags) {
|
|
|
105205
105382
|
while (Date.now() < deadline) {
|
|
105206
105383
|
const status = String(current.status ?? "");
|
|
105207
105384
|
if (["running", "failed", "timeout", "cancelled", "stopped"].includes(status)) return current;
|
|
105208
|
-
await new Promise((
|
|
105385
|
+
await new Promise((resolve18) => setTimeout(resolve18, 1e3));
|
|
105209
105386
|
current = await client2.getApplicationPreviewStatus(started.session_id);
|
|
105210
105387
|
}
|
|
105211
105388
|
throw new Error(`Application preview did not reach a terminal or running state within ${timeoutSeconds}s`);
|
|
@@ -105810,7 +105987,7 @@ function printMateInfo(mateId, json) {
|
|
|
105810
105987
|
async function confirmOrExit(question) {
|
|
105811
105988
|
const rl = await import("readline");
|
|
105812
105989
|
const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
|
|
105813
|
-
const answer = await new Promise((
|
|
105990
|
+
const answer = await new Promise((resolve18) => iface.question(question, resolve18));
|
|
105814
105991
|
iface.close();
|
|
105815
105992
|
if (answer.trim().toLowerCase() !== "y") {
|
|
105816
105993
|
console.log("Aborted.");
|
|
@@ -105820,7 +105997,7 @@ async function confirmOrExit(question) {
|
|
|
105820
105997
|
async function promptLine(question) {
|
|
105821
105998
|
const rl = await import("readline");
|
|
105822
105999
|
const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
|
|
105823
|
-
const answer = await new Promise((
|
|
106000
|
+
const answer = await new Promise((resolve18) => iface.question(question, resolve18));
|
|
105824
106001
|
iface.close();
|
|
105825
106002
|
return answer.trim();
|
|
105826
106003
|
}
|
|
@@ -105828,7 +106005,7 @@ async function promptSecret(question) {
|
|
|
105828
106005
|
if (!process.stdin.isTTY) {
|
|
105829
106006
|
return promptLine(question);
|
|
105830
106007
|
}
|
|
105831
|
-
return new Promise((
|
|
106008
|
+
return new Promise((resolve18) => {
|
|
105832
106009
|
const stdin4 = process.stdin;
|
|
105833
106010
|
const wasRaw = stdin4.isRaw;
|
|
105834
106011
|
let value = "";
|
|
@@ -105841,7 +106018,7 @@ async function promptSecret(question) {
|
|
|
105841
106018
|
stdin4.off("data", onData);
|
|
105842
106019
|
stdin4.setRawMode(wasRaw);
|
|
105843
106020
|
process.stdout.write("\n");
|
|
105844
|
-
|
|
106021
|
+
resolve18(value);
|
|
105845
106022
|
return;
|
|
105846
106023
|
}
|
|
105847
106024
|
if (char === "") {
|
|
@@ -106281,7 +106458,7 @@ function decodeBase32(input) {
|
|
|
106281
106458
|
}
|
|
106282
106459
|
return Buffer.from(bytes2);
|
|
106283
106460
|
}
|
|
106284
|
-
async function waitForSafeE2ETotpWindow(now = Date.now, sleep4 = (milliseconds) => new Promise((
|
|
106461
|
+
async function waitForSafeE2ETotpWindow(now = Date.now, sleep4 = (milliseconds) => new Promise((resolve18) => setTimeout(resolve18, milliseconds))) {
|
|
106285
106462
|
const millisecondsRemaining = 3e4 - now() % 3e4;
|
|
106286
106463
|
if (millisecondsRemaining < 2e3) {
|
|
106287
106464
|
await sleep4(millisecondsRemaining + 50);
|
|
@@ -109541,6 +109718,10 @@ Options:
|
|
|
109541
109718
|
--channel <dev|stable|main> Save release channel (dev uses npm alpha; stable/main uses latest)
|
|
109542
109719
|
--allow-downgrade Explicitly allow installing an older version
|
|
109543
109720
|
--verbose Stream package-manager output during installation
|
|
109721
|
+
--path <installation> Also update this server's Caddy configuration from its installed release
|
|
109722
|
+
--role <core|upload|preview> Server role for the Caddy update (default: saved role or core)
|
|
109723
|
+
--caddy-config <file> Active host Caddyfile; otherwise detect the running service
|
|
109724
|
+
--caddy-profile <name> Use official-upload for the shared production/development upload host
|
|
109544
109725
|
--json Output the update plan/result as JSON`);
|
|
109545
109726
|
}
|
|
109546
109727
|
function printRemoteAccessHelp() {
|