@rubytech/create-realagent 1.0.647 → 1.0.648
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/index.js +11 -1
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +1 -11
- package/payload/platform/plugins/cloudflare/PLUGIN.md +3 -2
- package/payload/platform/plugins/cloudflare/scripts/_cdp-authorize.mjs +274 -0
- package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.sh +69 -0
- package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +401 -0
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +73 -3
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +4 -2
- package/payload/platform/plugins/docs/references/cloudflare.md +1 -0
- package/payload/server/public/assets/{admin-ITLuG4BN.js → admin-uiqCo17I.js} +3 -3
- package/payload/server/public/index.html +1 -1
- package/payload/server/server.js +169 -1
package/payload/server/server.js
CHANGED
|
@@ -18136,6 +18136,19 @@ function broadcastAdminShutdown(reason) {
|
|
|
18136
18136
|
}
|
|
18137
18137
|
activeAdminSSEControllers.clear();
|
|
18138
18138
|
}
|
|
18139
|
+
function broadcastToConversation(conversationId, event) {
|
|
18140
|
+
const encoder = new TextEncoder();
|
|
18141
|
+
const frame = encoder.encode(`data: ${JSON.stringify(event)}
|
|
18142
|
+
|
|
18143
|
+
`);
|
|
18144
|
+
for (const entry of activeAdminSSEControllers) {
|
|
18145
|
+
if (entry.conversationId !== conversationId) continue;
|
|
18146
|
+
try {
|
|
18147
|
+
entry.controller.enqueue(frame);
|
|
18148
|
+
} catch {
|
|
18149
|
+
}
|
|
18150
|
+
}
|
|
18151
|
+
}
|
|
18139
18152
|
|
|
18140
18153
|
// server/routes/admin/chat.ts
|
|
18141
18154
|
function isComponentDone(parsed) {
|
|
@@ -19412,6 +19425,130 @@ ${e.message}`, timedOut: false });
|
|
|
19412
19425
|
});
|
|
19413
19426
|
}
|
|
19414
19427
|
var app23 = new Hono2();
|
|
19428
|
+
var DOMAINS_TIMEOUT_MS = 40 * 1e3;
|
|
19429
|
+
function runListScript(scriptPath, args, streamLogPath, log) {
|
|
19430
|
+
return new Promise((resolveP) => {
|
|
19431
|
+
const child = childProcess.spawn(scriptPath, args, {
|
|
19432
|
+
env: { ...process.env, STREAM_LOG_PATH: streamLogPath },
|
|
19433
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
19434
|
+
});
|
|
19435
|
+
log(`phase=script-spawn pid=${child.pid ?? "unknown"} args="${args.join(" ")}"`);
|
|
19436
|
+
let stdout = "";
|
|
19437
|
+
let stderr = "";
|
|
19438
|
+
let timedOut = false;
|
|
19439
|
+
const killer = setTimeout(() => {
|
|
19440
|
+
timedOut = true;
|
|
19441
|
+
try {
|
|
19442
|
+
child.kill("SIGTERM");
|
|
19443
|
+
} catch {
|
|
19444
|
+
}
|
|
19445
|
+
}, DOMAINS_TIMEOUT_MS);
|
|
19446
|
+
child.stdout?.on("data", (chunk) => {
|
|
19447
|
+
stdout += chunk.toString("utf-8");
|
|
19448
|
+
});
|
|
19449
|
+
child.stderr?.on("data", (chunk) => {
|
|
19450
|
+
stderr += chunk.toString("utf-8");
|
|
19451
|
+
});
|
|
19452
|
+
child.on("error", (e) => {
|
|
19453
|
+
clearTimeout(killer);
|
|
19454
|
+
resolveP({ code: null, signal: null, stdout, stderr: `${stderr}
|
|
19455
|
+
${e.message}`, timedOut: false });
|
|
19456
|
+
});
|
|
19457
|
+
child.on("exit", (code, signal) => {
|
|
19458
|
+
clearTimeout(killer);
|
|
19459
|
+
log(`phase=script-exit code=${code ?? "null"} signal=${signal ?? "null"} timedOut=${timedOut}`);
|
|
19460
|
+
resolveP({ code, signal, stdout, stderr, timedOut });
|
|
19461
|
+
});
|
|
19462
|
+
});
|
|
19463
|
+
}
|
|
19464
|
+
function fieldFromReason(reason) {
|
|
19465
|
+
switch (reason) {
|
|
19466
|
+
case "not-signed-in":
|
|
19467
|
+
return "dashboard";
|
|
19468
|
+
case "cdp-unreachable":
|
|
19469
|
+
case "target-create-failed":
|
|
19470
|
+
case "ws-connect-failed":
|
|
19471
|
+
case "navigate-failed":
|
|
19472
|
+
case "runtime-error":
|
|
19473
|
+
case "table-wait-timeout":
|
|
19474
|
+
case "entry-missing":
|
|
19475
|
+
case "wrapper-timeout":
|
|
19476
|
+
default:
|
|
19477
|
+
return "script";
|
|
19478
|
+
}
|
|
19479
|
+
}
|
|
19480
|
+
app23.get("/domains", requireAdminSession, async (c) => {
|
|
19481
|
+
const started = Date.now();
|
|
19482
|
+
const sessionKey = c.var.sessionKey;
|
|
19483
|
+
let correlationId;
|
|
19484
|
+
let sessionKeyTail;
|
|
19485
|
+
let streamLogPath;
|
|
19486
|
+
function tag() {
|
|
19487
|
+
if (!correlationId) return "";
|
|
19488
|
+
return ` conversationId=${correlationId} session_key=${sessionKeyTail ?? "unknown"}`;
|
|
19489
|
+
}
|
|
19490
|
+
function log(line) {
|
|
19491
|
+
console.log(`[cloudflare-domains] ${line}${tag()}`);
|
|
19492
|
+
}
|
|
19493
|
+
function logErr(line) {
|
|
19494
|
+
console.error(`[cloudflare-domains] ${line}${tag()}`);
|
|
19495
|
+
}
|
|
19496
|
+
function err(field, message, output) {
|
|
19497
|
+
logErr(`phase=error field=${field} reason="${message.slice(0, 160).replace(/"/g, "'")}"`);
|
|
19498
|
+
const body = {
|
|
19499
|
+
ok: false,
|
|
19500
|
+
field,
|
|
19501
|
+
message,
|
|
19502
|
+
output,
|
|
19503
|
+
correlationId,
|
|
19504
|
+
streamLogPath
|
|
19505
|
+
};
|
|
19506
|
+
return c.json(body, 200);
|
|
19507
|
+
}
|
|
19508
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
19509
|
+
correlationId = getConversationIdForSession(sessionKey);
|
|
19510
|
+
sessionKeyTail = sessionKey.slice(-8);
|
|
19511
|
+
if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
|
|
19512
|
+
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
19513
|
+
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
19514
|
+
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
19515
|
+
const brand = loadBrandInfo();
|
|
19516
|
+
const scriptPath = resolve25(homedir4(), "list-cf-domains.sh");
|
|
19517
|
+
const result = await runListScript(scriptPath, [brand.hostname], streamLogPath, log);
|
|
19518
|
+
const combined = `${result.stdout}${result.stderr ? `
|
|
19519
|
+
---
|
|
19520
|
+
${result.stderr}` : ""}`;
|
|
19521
|
+
if (result.code !== 0) {
|
|
19522
|
+
const reasonMatch = result.stderr.match(/reason=([a-z0-9-]+)/);
|
|
19523
|
+
const reason = reasonMatch ? reasonMatch[1] : void 0;
|
|
19524
|
+
const field = fieldFromReason(reason);
|
|
19525
|
+
const message = reason ? `Domain discovery failed: ${reason}` : result.timedOut ? `Domain discovery timed out after ${DOMAINS_TIMEOUT_MS / 1e3}s` : `Domain discovery exited with code ${result.code ?? "null"}${result.signal ? ` (signal ${result.signal})` : ""}`;
|
|
19526
|
+
return err(field, message, combined);
|
|
19527
|
+
}
|
|
19528
|
+
let domains;
|
|
19529
|
+
try {
|
|
19530
|
+
const parsed = JSON.parse(result.stdout.trim());
|
|
19531
|
+
if (!Array.isArray(parsed) || !parsed.every((d) => typeof d === "string")) {
|
|
19532
|
+
throw new Error("response is not string[]");
|
|
19533
|
+
}
|
|
19534
|
+
domains = parsed;
|
|
19535
|
+
} catch (e) {
|
|
19536
|
+
return err(
|
|
19537
|
+
"script",
|
|
19538
|
+
`Domain discovery returned malformed output: ${e instanceof Error ? e.message : String(e)}`,
|
|
19539
|
+
combined
|
|
19540
|
+
);
|
|
19541
|
+
}
|
|
19542
|
+
const success = {
|
|
19543
|
+
ok: true,
|
|
19544
|
+
domains,
|
|
19545
|
+
correlationId,
|
|
19546
|
+
streamLogPath
|
|
19547
|
+
};
|
|
19548
|
+
const total = Date.now() - started;
|
|
19549
|
+
log(`phase=response-sent total_ms=${total} count=${domains.length}`);
|
|
19550
|
+
return c.json(success, 200);
|
|
19551
|
+
});
|
|
19415
19552
|
app23.post("/setup", requireAdminSession, async (c) => {
|
|
19416
19553
|
const started = Date.now();
|
|
19417
19554
|
const sessionKey = c.var.sessionKey;
|
|
@@ -19480,11 +19617,42 @@ app23.post("/setup", requireAdminSession, async (c) => {
|
|
|
19480
19617
|
}
|
|
19481
19618
|
streamLogPath = streamLogPathFor(accountId, correlationId).streamLogPath;
|
|
19482
19619
|
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
19620
|
+
let tailer = null;
|
|
19621
|
+
try {
|
|
19622
|
+
tailer = startScriptStreamTailer({
|
|
19623
|
+
path: streamLogPath,
|
|
19624
|
+
onEvent: (event) => {
|
|
19625
|
+
if (correlationId) broadcastToConversation(correlationId, event);
|
|
19626
|
+
},
|
|
19627
|
+
onError: (e) => {
|
|
19628
|
+
logErr(`phase=tailer-error message="${e.message.slice(0, 160).replace(/"/g, "'")}"`);
|
|
19629
|
+
}
|
|
19630
|
+
});
|
|
19631
|
+
log(`phase=tailer-started`);
|
|
19632
|
+
} catch (e) {
|
|
19633
|
+
logErr(`phase=tailer-start-failed detail="${e instanceof Error ? e.message : String(e)}"`);
|
|
19634
|
+
tailer = null;
|
|
19635
|
+
}
|
|
19483
19636
|
const scriptPath = resolve25(homedir4(), "setup-tunnel.sh");
|
|
19484
19637
|
const args = [brand.hostname, String(port2), adminFqdn];
|
|
19485
19638
|
if (publicFqdn) args.push(publicFqdn);
|
|
19486
19639
|
if (apex) args.push(apex);
|
|
19487
|
-
|
|
19640
|
+
let result = null;
|
|
19641
|
+
try {
|
|
19642
|
+
result = await runScript(scriptPath, args, streamLogPath, log);
|
|
19643
|
+
} finally {
|
|
19644
|
+
if (tailer) {
|
|
19645
|
+
try {
|
|
19646
|
+
await tailer.stop();
|
|
19647
|
+
log(`phase=tailer-stopped`);
|
|
19648
|
+
} catch (e) {
|
|
19649
|
+
logErr(`phase=tailer-stop-failed detail="${e instanceof Error ? e.message : String(e)}"`);
|
|
19650
|
+
}
|
|
19651
|
+
}
|
|
19652
|
+
}
|
|
19653
|
+
if (!result) {
|
|
19654
|
+
return err("script", "Script spawn failed before producing a result");
|
|
19655
|
+
}
|
|
19488
19656
|
const combined = `${result.stdout}${result.stderr ? `
|
|
19489
19657
|
---
|
|
19490
19658
|
${result.stderr}` : ""}`;
|