@rubytech/create-maxy 1.0.885 → 1.0.887
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/package.json +1 -1
- package/payload/platform/neo4j/schema.cypher +7 -0
- package/payload/platform/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +8 -0
- package/payload/platform/scripts/__tests__/first-token-creates-stream-log.test.sh +37 -0
- package/payload/platform/scripts/__tests__/logs-read-prefix.sh +51 -0
- package/payload/platform/scripts/check-no-conversation-id-leaks.mjs +165 -0
- package/payload/platform/scripts/conversation-id-allowlist.txt +151 -0
- package/payload/platform/scripts/logs-read.sh +24 -4
- package/payload/platform/scripts/seed-neo4j.sh +46 -0
- package/payload/server/chunk-IFMZ5I3E.js +1460 -0
- package/payload/server/chunk-MOAY7KG2.js +11667 -0
- package/payload/server/client-pool-M6NS5G2U.js +34 -0
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/server.js +61 -19
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_evictAllForTest,
|
|
3
|
+
_poolSnapshotForTest,
|
|
4
|
+
acquireClient,
|
|
5
|
+
acquireOneShotClient,
|
|
6
|
+
evictClient,
|
|
7
|
+
getActiveClient,
|
|
8
|
+
interruptClient,
|
|
9
|
+
pushUserMessage,
|
|
10
|
+
pushUserToolResult,
|
|
11
|
+
recordCachedTokens,
|
|
12
|
+
recordCrash,
|
|
13
|
+
setInflight,
|
|
14
|
+
startIdleEvictTick,
|
|
15
|
+
stopIdleEvictTick
|
|
16
|
+
} from "./chunk-IFMZ5I3E.js";
|
|
17
|
+
import "./chunk-DOIAYD3J.js";
|
|
18
|
+
import "./chunk-JSBRDJBE.js";
|
|
19
|
+
export {
|
|
20
|
+
_evictAllForTest,
|
|
21
|
+
_poolSnapshotForTest,
|
|
22
|
+
acquireClient,
|
|
23
|
+
acquireOneShotClient,
|
|
24
|
+
evictClient,
|
|
25
|
+
getActiveClient,
|
|
26
|
+
interruptClient,
|
|
27
|
+
pushUserMessage,
|
|
28
|
+
pushUserToolResult,
|
|
29
|
+
recordCachedTokens,
|
|
30
|
+
recordCrash,
|
|
31
|
+
setInflight,
|
|
32
|
+
startIdleEvictTick,
|
|
33
|
+
stopIdleEvictTick
|
|
34
|
+
};
|
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
streamActionEvents,
|
|
17
17
|
vncLog,
|
|
18
18
|
websockifyLog
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-MOAY7KG2.js";
|
|
20
20
|
import {
|
|
21
21
|
LOG_DIR,
|
|
22
22
|
WEBSOCKIFY_PORT
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-IFMZ5I3E.js";
|
|
24
24
|
import "./chunk-ECAQVMRA.js";
|
|
25
25
|
import "./chunk-DOIAYD3J.js";
|
|
26
26
|
import "./chunk-JSBRDJBE.js";
|
package/payload/server/server.js
CHANGED
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
vncLog,
|
|
77
77
|
waitForExit,
|
|
78
78
|
writeChromiumWrapper
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-MOAY7KG2.js";
|
|
80
80
|
import {
|
|
81
81
|
CDP_PORT,
|
|
82
82
|
COMMERCIAL_MODE,
|
|
@@ -91,6 +91,7 @@ import {
|
|
|
91
91
|
completeGrantSetup,
|
|
92
92
|
consumeWantsPriorConversation,
|
|
93
93
|
emitMissingOnResolve,
|
|
94
|
+
fingerprintSessionKey,
|
|
94
95
|
getAccountIdForSession,
|
|
95
96
|
getActiveClient,
|
|
96
97
|
getAgentNameForSession,
|
|
@@ -116,7 +117,7 @@ import {
|
|
|
116
117
|
sigtermFlushStreamLogs,
|
|
117
118
|
unregisterSession,
|
|
118
119
|
validateSession
|
|
119
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-IFMZ5I3E.js";
|
|
120
121
|
import {
|
|
121
122
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|
|
122
123
|
appendCloudflareSteps,
|
|
@@ -7017,7 +7018,8 @@ async function resolveUserIdentity(accountId, userId) {
|
|
|
7017
7018
|
async function createAdminSession(accountId, thinkingView, userId, userName, role, avatar) {
|
|
7018
7019
|
const account = resolveAccount();
|
|
7019
7020
|
const effectiveThinkingView = thinkingView ?? account?.config.thinkingView ?? "default";
|
|
7020
|
-
const
|
|
7021
|
+
const signedSessionToken = userId ? mintAdminSessionToken({ accountId, userId }) : crypto.randomUUID();
|
|
7022
|
+
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
7021
7023
|
registerSession(cacheKey, "admin", accountId, void 0, userId, userName, role);
|
|
7022
7024
|
if (userId) setWantsPriorConversation(cacheKey);
|
|
7023
7025
|
let onboardingComplete = true;
|
|
@@ -7053,7 +7055,7 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
7053
7055
|
console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} admin session created: userId=${userId ?? "\u2013"} userName=${userName ?? "\u2013"} accountId=${accountId} conversationId=${initialConversationId ?? "unbound"} cacheKey=${cacheKey.slice(0, 8)}`);
|
|
7054
7056
|
console.log(`[admin-session] role=${role ?? "null"} cacheKey=${cacheKey.slice(0, 8)} phase=create eager-ensured=${initialConversationId ? "true" : "false"}`);
|
|
7055
7057
|
return {
|
|
7056
|
-
session_key:
|
|
7058
|
+
session_key: signedSessionToken,
|
|
7057
7059
|
agent_id: "admin",
|
|
7058
7060
|
userId,
|
|
7059
7061
|
userName,
|
|
@@ -7067,8 +7069,12 @@ async function createAdminSession(accountId, thinkingView, userId, userName, rol
|
|
|
7067
7069
|
}
|
|
7068
7070
|
var app10 = new Hono();
|
|
7069
7071
|
app10.get("/", async (c) => {
|
|
7070
|
-
const
|
|
7071
|
-
if (!
|
|
7072
|
+
const signedSessionToken = c.req.query("session_key");
|
|
7073
|
+
if (!signedSessionToken) {
|
|
7074
|
+
return c.json({ error: "Invalid or expired admin session" }, 401);
|
|
7075
|
+
}
|
|
7076
|
+
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
7077
|
+
if (!validateSession(cacheKey, "admin", signedSessionToken).ok) {
|
|
7072
7078
|
return c.json({ error: "Invalid or expired admin session" }, 401);
|
|
7073
7079
|
}
|
|
7074
7080
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -7104,7 +7110,7 @@ app10.get("/", async (c) => {
|
|
|
7104
7110
|
}
|
|
7105
7111
|
}
|
|
7106
7112
|
return c.json({
|
|
7107
|
-
session_key:
|
|
7113
|
+
session_key: signedSessionToken,
|
|
7108
7114
|
agent_id: "admin",
|
|
7109
7115
|
userId: restoredUserId,
|
|
7110
7116
|
userName: restoredUserName,
|
|
@@ -7474,7 +7480,7 @@ var app11 = new Hono();
|
|
|
7474
7480
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7475
7481
|
const session_key = c.var.cacheKey;
|
|
7476
7482
|
try {
|
|
7477
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7483
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-M6NS5G2U.js");
|
|
7478
7484
|
await interruptClient2(session_key);
|
|
7479
7485
|
return c.json({ ok: true });
|
|
7480
7486
|
} catch (err) {
|
|
@@ -8633,13 +8639,14 @@ app18.post("/new", requireAdminSession, async (c) => {
|
|
|
8633
8639
|
if (!accountId || !userId) {
|
|
8634
8640
|
return c.json({ error: "Session missing account or user context" }, 400);
|
|
8635
8641
|
}
|
|
8636
|
-
const
|
|
8642
|
+
const newSignedSessionToken = crypto2.randomUUID();
|
|
8643
|
+
const newCacheKey = fingerprintSessionKey(newSignedSessionToken);
|
|
8637
8644
|
const userName = getUserNameForSession(oldCacheKey);
|
|
8638
8645
|
registerSession(newCacheKey, "admin", accountId, void 0, userId, userName);
|
|
8639
8646
|
const previousConversationId = clearSessionHistory(oldCacheKey);
|
|
8640
8647
|
unregisterSession(oldCacheKey);
|
|
8641
8648
|
console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} session reset for new conversation: oldCacheKey=${oldCacheKey.slice(0, 8)}\u2026 newCacheKey=${newCacheKey.slice(0, 8)}\u2026 previousConversationId=${previousConversationId?.slice(0, 8) ?? "none"}\u2026 newConversationId=deferred`);
|
|
8642
|
-
return c.json({ session_key:
|
|
8649
|
+
return c.json({ session_key: newSignedSessionToken, conversationId: null });
|
|
8643
8650
|
});
|
|
8644
8651
|
app18.post("/switch", requireAdminSession, async (c) => {
|
|
8645
8652
|
const cacheKey = c.var.cacheKey;
|
|
@@ -8649,11 +8656,12 @@ app18.post("/switch", requireAdminSession, async (c) => {
|
|
|
8649
8656
|
return c.json({ error: "Session missing account or user context" }, 400);
|
|
8650
8657
|
}
|
|
8651
8658
|
const body = await c.req.json().catch(() => ({}));
|
|
8652
|
-
const
|
|
8653
|
-
if (!
|
|
8659
|
+
const targetSignedSessionToken = typeof body.target_session_key === "string" ? body.target_session_key : "";
|
|
8660
|
+
if (!targetSignedSessionToken) {
|
|
8654
8661
|
return c.json({ error: "target_session_key required" }, 400);
|
|
8655
8662
|
}
|
|
8656
|
-
const
|
|
8663
|
+
const targetCacheKey = fingerprintSessionKey(targetSignedSessionToken);
|
|
8664
|
+
const targetCheck = validateSession(targetCacheKey, "admin", targetSignedSessionToken);
|
|
8657
8665
|
if (!targetCheck.ok) {
|
|
8658
8666
|
console.error(`[session-switch] reject reason=${targetCheck.reason} from=${cacheKey.slice(0, 8)} target=${targetCacheKey.slice(0, 8)}`);
|
|
8659
8667
|
return c.json({ error: "Target session not registered or wrong agent type", code: targetCheck.reason }, 404);
|
|
@@ -8666,7 +8674,7 @@ app18.post("/switch", requireAdminSession, async (c) => {
|
|
|
8666
8674
|
}
|
|
8667
8675
|
const targetConversationId = getConversationIdForSession(targetCacheKey) ?? null;
|
|
8668
8676
|
console.log(`[session-switch] from=${cacheKey.slice(0, 8)} to=${targetCacheKey.slice(0, 8)} targetConvId=${targetConversationId?.slice(0, 8) ?? "none"} accountId=${accountId.slice(0, 8)}`);
|
|
8669
|
-
return c.json({ session_key:
|
|
8677
|
+
return c.json({ session_key: targetSignedSessionToken, conversationId: targetConversationId });
|
|
8670
8678
|
});
|
|
8671
8679
|
app18.delete("/:id", requireAdminSession, async (c) => {
|
|
8672
8680
|
const conversationId = c.req.param("id");
|
|
@@ -8685,13 +8693,14 @@ app18.delete("/:id", requireAdminSession, async (c) => {
|
|
|
8685
8693
|
});
|
|
8686
8694
|
app18.post("/:id/resume", async (c) => {
|
|
8687
8695
|
const conversationId = c.req.param("id");
|
|
8688
|
-
const
|
|
8689
|
-
if (!
|
|
8696
|
+
const signedSessionToken = c.req.query("session_key") ?? "";
|
|
8697
|
+
if (!signedSessionToken) {
|
|
8690
8698
|
console.error(`[session] middleware-reject status=400 code=session-missing reason="session_key required" path=${c.req.path}`);
|
|
8691
8699
|
return c.json({ error: "session_key required", code: "session-missing" }, 400);
|
|
8692
8700
|
}
|
|
8701
|
+
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
8693
8702
|
let bridged = false;
|
|
8694
|
-
let result = validateSession(cacheKey, "admin");
|
|
8703
|
+
let result = validateSession(cacheKey, "admin", signedSessionToken);
|
|
8695
8704
|
if (!result.ok) {
|
|
8696
8705
|
if (result.reason === "session-not-registered") {
|
|
8697
8706
|
const bridge = await tryCookieBridgeForConversation(c, cacheKey, conversationId);
|
|
@@ -8704,7 +8713,7 @@ app18.post("/:id/resume", async (c) => {
|
|
|
8704
8713
|
return c.json({ error: "Invalid or expired admin session", code: "session-not-registered" }, 401);
|
|
8705
8714
|
}
|
|
8706
8715
|
bridged = true;
|
|
8707
|
-
result = validateSession(cacheKey, "admin");
|
|
8716
|
+
result = validateSession(cacheKey, "admin", signedSessionToken);
|
|
8708
8717
|
if (!result.ok) {
|
|
8709
8718
|
const tail = cacheKey.slice(0, 8);
|
|
8710
8719
|
console.error(`[session] middleware-reject status=401 code=session-not-registered reason="post-bridge re-validate failed" path=${c.req.path} cacheKey=${tail}\u2026`);
|
|
@@ -12881,10 +12890,42 @@ async function verifyUserProfileConstraint() {
|
|
|
12881
12890
|
await session.close();
|
|
12882
12891
|
}
|
|
12883
12892
|
}
|
|
12893
|
+
async function verifySessionKeyAdherence() {
|
|
12894
|
+
const session = getSession();
|
|
12895
|
+
try {
|
|
12896
|
+
const convResult = await session.run(
|
|
12897
|
+
`MATCH (c:Conversation) WHERE c.sessionKey IS NULL RETURN count(c) AS n`
|
|
12898
|
+
);
|
|
12899
|
+
const convNull = convResult.records[0]?.get("n")?.toNumber?.() ?? 0;
|
|
12900
|
+
console.error(
|
|
12901
|
+
`[migration-1007] adherence-check label=Conversation rows-with-null-sessionkey=${convNull}`
|
|
12902
|
+
);
|
|
12903
|
+
const msgResult = await session.run(
|
|
12904
|
+
`MATCH (m:Message) WHERE m.sessionKey IS NULL RETURN count(m) AS n`
|
|
12905
|
+
);
|
|
12906
|
+
const msgNull = msgResult.records[0]?.get("n")?.toNumber?.() ?? 0;
|
|
12907
|
+
console.error(
|
|
12908
|
+
`[migration-1007] adherence-check label=Message rows-with-null-sessionkey=${msgNull}`
|
|
12909
|
+
);
|
|
12910
|
+
if (convNull > 0 || msgNull > 0) {
|
|
12911
|
+
console.error(
|
|
12912
|
+
`[migration-1007] adherence-check P0=true reason=null-sessionkey-on-boot \u2014 re-run seed-neo4j.sh`
|
|
12913
|
+
);
|
|
12914
|
+
}
|
|
12915
|
+
} catch (err) {
|
|
12916
|
+
console.error(
|
|
12917
|
+
`[migration-1007] adherence-check verify failed: ${err instanceof Error ? err.message : String(err)}`
|
|
12918
|
+
);
|
|
12919
|
+
} finally {
|
|
12920
|
+
await session.close();
|
|
12921
|
+
}
|
|
12922
|
+
}
|
|
12884
12923
|
function startGraphHealthTimer() {
|
|
12885
12924
|
if (timer) return;
|
|
12886
12925
|
verifyUserProfileConstraint().catch(() => {
|
|
12887
12926
|
});
|
|
12927
|
+
verifySessionKeyAdherence().catch(() => {
|
|
12928
|
+
});
|
|
12888
12929
|
runGraphHealthTick().catch(() => {
|
|
12889
12930
|
});
|
|
12890
12931
|
timer = setInterval(() => {
|
|
@@ -13213,7 +13254,8 @@ app39.post("/api/remote-auth/set-password", async (c) => {
|
|
|
13213
13254
|
} catch {
|
|
13214
13255
|
return c.json({ error: "Invalid request" }, 400);
|
|
13215
13256
|
}
|
|
13216
|
-
|
|
13257
|
+
const cacheKey = body.session_key ? fingerprintSessionKey(body.session_key) : "";
|
|
13258
|
+
if (!cacheKey || !validateSession(cacheKey, "admin", body.session_key).ok) {
|
|
13217
13259
|
return c.json({ error: "Unauthorized" }, 401);
|
|
13218
13260
|
}
|
|
13219
13261
|
if (!body.password) {
|