@rubytech/create-realagent-code 0.1.248 → 0.1.250
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/plugins/admin/PLUGIN.md +1 -1
- package/payload/platform/plugins/admin/hooks/__tests__/session-end-retrospective.test.sh +3 -3
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +20 -10
- package/payload/platform/plugins/docs/PLUGIN.md +2 -2
- package/payload/platform/plugins/docs/references/admin-session.md +7 -67
- package/payload/platform/plugins/docs/references/admin-ui.md +7 -3
- package/payload/platform/plugins/docs/references/deployment.md +1 -1
- package/payload/platform/plugins/docs/references/internals.md +8 -2
- package/payload/platform/plugins/docs/references/platform.md +3 -3
- package/payload/platform/scripts/check-no-legacy-spawn-route.mjs +37 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +87 -21
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +8 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +14 -4
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/server/{chunk-UEIA5YUG.js → chunk-BE7O7KZ5.js} +4 -0
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +160 -126
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +0 -601
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +0 -441
package/payload/server/server.js
CHANGED
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
getUserNameForSession,
|
|
53
53
|
getUserTimezone,
|
|
54
54
|
httpLog,
|
|
55
|
+
isActiveAgentSlug,
|
|
55
56
|
isPasswordValid,
|
|
56
57
|
isRemoteAuthConfigured,
|
|
57
58
|
linkConversationTranscript,
|
|
@@ -92,7 +93,7 @@ import {
|
|
|
92
93
|
vncLog,
|
|
93
94
|
walkPremiumBundles,
|
|
94
95
|
writeAdminUserAndPerson
|
|
95
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-BE7O7KZ5.js";
|
|
96
97
|
import {
|
|
97
98
|
__commonJS,
|
|
98
99
|
__toESM
|
|
@@ -4201,7 +4202,7 @@ async function managerSpawn(opts) {
|
|
|
4201
4202
|
);
|
|
4202
4203
|
return { error: "claude-auth-dead", status: 503 };
|
|
4203
4204
|
}
|
|
4204
|
-
const res = await fetch(`${managerBase()}/spawn`, {
|
|
4205
|
+
const res = await fetch(`${managerBase()}/public-spawn`, {
|
|
4205
4206
|
method: "POST",
|
|
4206
4207
|
headers: { "content-type": "application/json" },
|
|
4207
4208
|
body: JSON.stringify({
|
|
@@ -4216,7 +4217,8 @@ async function managerSpawn(opts) {
|
|
|
4216
4217
|
activePlugins: opts.activePlugins,
|
|
4217
4218
|
specialistDomains: opts.specialistDomains,
|
|
4218
4219
|
sliceToken: opts.sliceToken,
|
|
4219
|
-
personId: opts.personId
|
|
4220
|
+
personId: opts.personId,
|
|
4221
|
+
name: opts.name
|
|
4220
4222
|
})
|
|
4221
4223
|
}).catch((err) => ({ __throw: err instanceof Error ? err.message : String(err) }));
|
|
4222
4224
|
if ("__throw" in res) {
|
|
@@ -4226,6 +4228,32 @@ async function managerSpawn(opts) {
|
|
|
4226
4228
|
if (!r.ok) return { error: `manager-status-${r.status}`, status: r.status };
|
|
4227
4229
|
return await r.json();
|
|
4228
4230
|
}
|
|
4231
|
+
async function managerRcSpawn(opts) {
|
|
4232
|
+
const auth = await ensureAuth();
|
|
4233
|
+
if (auth.status === "dead" || auth.status === "missing") {
|
|
4234
|
+
console.log(`[channel-pty-bridge] rc-spawn-refused reason=auth-${auth.status} ${opts.logContext}`);
|
|
4235
|
+
return { error: "claude-auth-dead", status: 503 };
|
|
4236
|
+
}
|
|
4237
|
+
const res = await fetch(`${managerBase()}/rc-spawn`, {
|
|
4238
|
+
method: "POST",
|
|
4239
|
+
headers: { "content-type": "application/json" },
|
|
4240
|
+
body: JSON.stringify({
|
|
4241
|
+
sessionId: opts.sessionId,
|
|
4242
|
+
name: opts.name,
|
|
4243
|
+
initialMessage: opts.initialMessage,
|
|
4244
|
+
closeAfterTurn: opts.closeAfterTurn,
|
|
4245
|
+
sliceToken: opts.sliceToken,
|
|
4246
|
+
personId: opts.personId
|
|
4247
|
+
})
|
|
4248
|
+
}).catch((err) => ({ __throw: err instanceof Error ? err.message : String(err) }));
|
|
4249
|
+
if ("__throw" in res) {
|
|
4250
|
+
return { error: res.__throw, status: 0 };
|
|
4251
|
+
}
|
|
4252
|
+
const r = res;
|
|
4253
|
+
if (!r.ok) return { error: `manager-status-${r.status}`, status: r.status };
|
|
4254
|
+
const out = await r.json();
|
|
4255
|
+
return { sessionId: out.sessionId ?? opts.sessionId, pid: out.spawnedPid ?? null };
|
|
4256
|
+
}
|
|
4229
4257
|
async function managerWriteInput(sessionId, text) {
|
|
4230
4258
|
const res = await fetch(`${managerBase()}/${sessionId}/input`, {
|
|
4231
4259
|
method: "POST",
|
|
@@ -4247,7 +4275,19 @@ function managerLogFollowUrl(sessionId) {
|
|
|
4247
4275
|
return `${managerBase()}/${sessionId}/log?follow=1`;
|
|
4248
4276
|
}
|
|
4249
4277
|
|
|
4278
|
+
// app/lib/channel-pty-bridge/admin-session-id.ts
|
|
4279
|
+
import { createHash } from "crypto";
|
|
4280
|
+
function adminSessionIdFor(accountId, senderId) {
|
|
4281
|
+
const b = createHash("sha256").update(`${accountId}:admin:${senderId}`).digest().subarray(0, 16);
|
|
4282
|
+
const v = Buffer.from(b);
|
|
4283
|
+
v[6] = v[6] & 15 | 64;
|
|
4284
|
+
v[8] = v[8] & 63 | 128;
|
|
4285
|
+
const h = v.toString("hex");
|
|
4286
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
4287
|
+
}
|
|
4288
|
+
|
|
4250
4289
|
// app/lib/channel-pty-bridge/public-session-end-review.ts
|
|
4290
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
4251
4291
|
var TAG14 = "[public-session-review]";
|
|
4252
4292
|
var CONSUMED_CAP = 500;
|
|
4253
4293
|
var consumed = /* @__PURE__ */ new Set();
|
|
@@ -4335,30 +4375,20 @@ function composeInitialMessage(input) {
|
|
|
4335
4375
|
].join("\n");
|
|
4336
4376
|
}
|
|
4337
4377
|
async function dispatchReviewer(input, initialMessage) {
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
sliceToken: input.sliceToken,
|
|
4351
|
-
personId: input.personId ?? void 0
|
|
4352
|
-
})
|
|
4353
|
-
});
|
|
4354
|
-
if (!res.ok) {
|
|
4355
|
-
return { ok: false, reason: `spawn-status-${res.status}` };
|
|
4356
|
-
}
|
|
4357
|
-
const body = await res.json();
|
|
4358
|
-
return { ok: true, managerSessionId: body.sessionId ?? "unknown" };
|
|
4359
|
-
} catch (err) {
|
|
4360
|
-
return { ok: false, reason: `spawn-threw-${err instanceof Error ? err.message : String(err)}` };
|
|
4378
|
+
const sessionId = randomUUID4();
|
|
4379
|
+
console.log(`${TAG14} route target=rc-spawn sessionId=${sessionId.slice(0, 8)} sourceSession=${input.sessionId.slice(0, 8)}`);
|
|
4380
|
+
const spawned = await managerRcSpawn({
|
|
4381
|
+
sessionId,
|
|
4382
|
+
initialMessage,
|
|
4383
|
+
closeAfterTurn: true,
|
|
4384
|
+
sliceToken: input.sliceToken,
|
|
4385
|
+
personId: input.personId ?? void 0,
|
|
4386
|
+
logContext: `public-session-end sourceSession=${input.sessionId.slice(0, 8)}`
|
|
4387
|
+
});
|
|
4388
|
+
if ("error" in spawned) {
|
|
4389
|
+
return { ok: false, reason: `rc-spawn-${spawned.status}-${spawned.error}` };
|
|
4361
4390
|
}
|
|
4391
|
+
return { ok: true, managerSessionId: spawned.sessionId };
|
|
4362
4392
|
}
|
|
4363
4393
|
async function firePublicSessionEndReview(input) {
|
|
4364
4394
|
const sliceShort = input.sliceToken.slice(0, 8);
|
|
@@ -4527,7 +4557,7 @@ function tagFor(channel) {
|
|
|
4527
4557
|
return `[${channel}-adaptor]`;
|
|
4528
4558
|
}
|
|
4529
4559
|
function publicIdleMs() {
|
|
4530
|
-
return Number(process.env.CHANNEL_PTY_IDLE_MS ?? String(
|
|
4560
|
+
return Number(process.env.CHANNEL_PTY_IDLE_MS ?? String(5 * 6e4));
|
|
4531
4561
|
}
|
|
4532
4562
|
var index = /* @__PURE__ */ new Map();
|
|
4533
4563
|
function indexKey(accountId, agentSlug, senderId, sliceToken = "") {
|
|
@@ -4538,6 +4568,7 @@ async function ensureEntry(input) {
|
|
|
4538
4568
|
startReaper();
|
|
4539
4569
|
const sliceTokenValue = input.sliceToken ?? "";
|
|
4540
4570
|
const personIdValue = input.personId ?? null;
|
|
4571
|
+
const nameValue = input.name ?? null;
|
|
4541
4572
|
const key = indexKey(input.accountId, input.agentSlug, input.senderId, sliceTokenValue);
|
|
4542
4573
|
const existing = index.get(key);
|
|
4543
4574
|
const tag = tagFor(input.channel);
|
|
@@ -4554,17 +4585,30 @@ async function ensureEntry(input) {
|
|
|
4554
4585
|
}
|
|
4555
4586
|
return existing;
|
|
4556
4587
|
}
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
role
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4588
|
+
let spawned;
|
|
4589
|
+
if (input.role === "admin") {
|
|
4590
|
+
const adminSessionId = adminSessionIdFor(input.accountId, input.senderId);
|
|
4591
|
+
console.error(`${tag} route role=admin target=rc-spawn senderId=${input.senderId}`);
|
|
4592
|
+
spawned = await managerRcSpawn({
|
|
4593
|
+
sessionId: adminSessionId,
|
|
4594
|
+
name: nameValue ?? void 0,
|
|
4595
|
+
logContext: `channel=${input.channel} senderId=${input.senderId}`
|
|
4596
|
+
});
|
|
4597
|
+
} else {
|
|
4598
|
+
console.error(`${tag} route role=${input.role} target=public-spawn senderId=${input.senderId}`);
|
|
4599
|
+
const attachmentDir = resolve4(ATTACHMENTS_ROOT, "public", input.senderId);
|
|
4600
|
+
spawned = await managerSpawn({
|
|
4601
|
+
senderId: input.senderId,
|
|
4602
|
+
role: input.role,
|
|
4603
|
+
channel: input.channel,
|
|
4604
|
+
accountId: input.accountId,
|
|
4605
|
+
agentSlug: input.agentSlug,
|
|
4606
|
+
attachmentDir,
|
|
4607
|
+
sliceToken: sliceTokenValue.length > 0 ? sliceTokenValue : void 0,
|
|
4608
|
+
personId: personIdValue ?? void 0,
|
|
4609
|
+
name: nameValue ?? void 0
|
|
4610
|
+
});
|
|
4611
|
+
}
|
|
4568
4612
|
if ("error" in spawned) {
|
|
4569
4613
|
if (spawned.error !== "claude-auth-dead") {
|
|
4570
4614
|
console.error(
|
|
@@ -4587,7 +4631,8 @@ async function ensureEntry(input) {
|
|
|
4587
4631
|
followerAbort: null,
|
|
4588
4632
|
followerRunning: false,
|
|
4589
4633
|
sliceToken: sliceTokenValue,
|
|
4590
|
-
personId: personIdValue
|
|
4634
|
+
personId: personIdValue,
|
|
4635
|
+
name: nameValue
|
|
4591
4636
|
};
|
|
4592
4637
|
entry.followerAbort = startFollower({
|
|
4593
4638
|
entry,
|
|
@@ -4632,7 +4677,8 @@ async function writeInput(entry, text) {
|
|
|
4632
4677
|
channel: entry.channel,
|
|
4633
4678
|
agentSlug: entry.agentSlug,
|
|
4634
4679
|
sliceToken: entry.sliceToken.length > 0 ? entry.sliceToken : void 0,
|
|
4635
|
-
personId: entry.personId
|
|
4680
|
+
personId: entry.personId,
|
|
4681
|
+
name: entry.name
|
|
4636
4682
|
});
|
|
4637
4683
|
if (!respawned) return false;
|
|
4638
4684
|
for (const cb of entry.subscribers) respawned.subscribers.add(cb);
|
|
@@ -4671,7 +4717,8 @@ async function dispatchOnce(input) {
|
|
|
4671
4717
|
channel: input.channel,
|
|
4672
4718
|
agentSlug: input.agentSlug,
|
|
4673
4719
|
sliceToken: input.sliceToken,
|
|
4674
|
-
personId: input.personId
|
|
4720
|
+
personId: input.personId,
|
|
4721
|
+
name: input.name
|
|
4675
4722
|
});
|
|
4676
4723
|
if (!entry) return { error: "spawn-failed" };
|
|
4677
4724
|
entry.lastInboundAt = Date.now();
|
|
@@ -4774,10 +4821,10 @@ function handlePublicSessionExit(sessionId) {
|
|
|
4774
4821
|
}
|
|
4775
4822
|
|
|
4776
4823
|
// app/lib/access-session-store.ts
|
|
4777
|
-
import { randomUUID as
|
|
4824
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
4778
4825
|
var sessions = /* @__PURE__ */ new Map();
|
|
4779
4826
|
function createAccessSession(input) {
|
|
4780
|
-
const sessionId =
|
|
4827
|
+
const sessionId = randomUUID5();
|
|
4781
4828
|
const session = {
|
|
4782
4829
|
...input,
|
|
4783
4830
|
sessionId,
|
|
@@ -4800,6 +4847,16 @@ function evictAccessSessionsByGrant(grantId) {
|
|
|
4800
4847
|
return dropped;
|
|
4801
4848
|
}
|
|
4802
4849
|
|
|
4850
|
+
// app/lib/public-session-title.ts
|
|
4851
|
+
function composePublicSessionTitle(input) {
|
|
4852
|
+
const sid = input.senderId.slice(0, 8);
|
|
4853
|
+
const ts = input.spawnedAt.toISOString().slice(0, 16).replace("T", " ");
|
|
4854
|
+
const segments = ["Web", sid];
|
|
4855
|
+
if (input.personId) segments.push(input.personId);
|
|
4856
|
+
segments.push(ts);
|
|
4857
|
+
return segments.join(" \xB7 ");
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4803
4860
|
// server/routes/chat.ts
|
|
4804
4861
|
var WEBCHAT_TAG = "[webchat-adaptor]";
|
|
4805
4862
|
var SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
@@ -4921,7 +4978,7 @@ app2.post("/", async (c) => {
|
|
|
4921
4978
|
let agentSlug;
|
|
4922
4979
|
let resolveSource;
|
|
4923
4980
|
if (requestedSlug) {
|
|
4924
|
-
const active = validateAgentSlug(requestedSlug) &&
|
|
4981
|
+
const active = validateAgentSlug(requestedSlug) && isActiveAgentSlug(account.accountDir, requestedSlug);
|
|
4925
4982
|
agentSlug = active ? requestedSlug : null;
|
|
4926
4983
|
resolveSource = active ? "slug" : "none";
|
|
4927
4984
|
} else {
|
|
@@ -4969,6 +5026,11 @@ app2.post("/", async (c) => {
|
|
|
4969
5026
|
const readable = new ReadableStream({
|
|
4970
5027
|
async start(controller) {
|
|
4971
5028
|
try {
|
|
5029
|
+
const publicTitle = composePublicSessionTitle({
|
|
5030
|
+
senderId: session_key,
|
|
5031
|
+
personId,
|
|
5032
|
+
spawnedAt: /* @__PURE__ */ new Date()
|
|
5033
|
+
});
|
|
4972
5034
|
const result = await dispatchOnce({
|
|
4973
5035
|
accountId: account.accountId,
|
|
4974
5036
|
senderId: session_key,
|
|
@@ -4977,6 +5039,7 @@ app2.post("/", async (c) => {
|
|
|
4977
5039
|
agentSlug,
|
|
4978
5040
|
sliceToken,
|
|
4979
5041
|
personId,
|
|
5042
|
+
name: publicTitle,
|
|
4980
5043
|
text: fullMessage,
|
|
4981
5044
|
timeoutMs: webchatTurnTimeoutMs()
|
|
4982
5045
|
});
|
|
@@ -5028,7 +5091,7 @@ import { readFile, stat as stat2 } from "fs/promises";
|
|
|
5028
5091
|
import { realpathSync as realpathSync2, readdirSync as readdirSync2, readFileSync as readFileSync6, existsSync as existsSync4 } from "fs";
|
|
5029
5092
|
|
|
5030
5093
|
// app/lib/whatsapp/login.ts
|
|
5031
|
-
import { randomUUID as
|
|
5094
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
5032
5095
|
var TAG15 = "[whatsapp:login]";
|
|
5033
5096
|
var ACTIVE_LOGIN_TTL_MS = 3 * 6e4;
|
|
5034
5097
|
var activeLogins = /* @__PURE__ */ new Map();
|
|
@@ -5167,7 +5230,7 @@ async function startLogin(opts) {
|
|
|
5167
5230
|
const login = {
|
|
5168
5231
|
accountId,
|
|
5169
5232
|
authDir,
|
|
5170
|
-
id:
|
|
5233
|
+
id: randomUUID6(),
|
|
5171
5234
|
sock,
|
|
5172
5235
|
startedAt: Date.now(),
|
|
5173
5236
|
connected: false
|
|
@@ -6169,7 +6232,7 @@ var whatsapp_default = app3;
|
|
|
6169
6232
|
// server/routes/onboarding.ts
|
|
6170
6233
|
import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync2 } from "child_process";
|
|
6171
6234
|
import { openSync, closeSync, writeFileSync as writeFileSync5, writeSync, existsSync as existsSync6, readFileSync as readFileSync8, unlinkSync } from "fs";
|
|
6172
|
-
import { createHash, randomUUID as
|
|
6235
|
+
import { createHash as createHash2, randomUUID as randomUUID7 } from "crypto";
|
|
6173
6236
|
|
|
6174
6237
|
// ../lib/admins-write/src/index.ts
|
|
6175
6238
|
import { existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync4, renameSync, mkdirSync as mkdirSync2, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
|
|
@@ -6317,7 +6380,7 @@ function checkAdminAuthInvariant(input) {
|
|
|
6317
6380
|
|
|
6318
6381
|
// server/routes/onboarding.ts
|
|
6319
6382
|
function hashPin(pin) {
|
|
6320
|
-
return
|
|
6383
|
+
return createHash2("sha256").update(pin).digest("hex");
|
|
6321
6384
|
}
|
|
6322
6385
|
function readUsersFile() {
|
|
6323
6386
|
if (!existsSync6(USERS_FILE)) return null;
|
|
@@ -6445,7 +6508,7 @@ app4.post("/set-pin", async (c) => {
|
|
|
6445
6508
|
const hash = hashPin(body.pin);
|
|
6446
6509
|
const account = resolveAccount();
|
|
6447
6510
|
const existingOwnerUserId = account?.config.admins?.find((a) => a.role === "owner")?.userId;
|
|
6448
|
-
const userId = existingOwnerUserId ??
|
|
6511
|
+
const userId = existingOwnerUserId ?? randomUUID7();
|
|
6449
6512
|
if (existingOwnerUserId) {
|
|
6450
6513
|
console.log(`[set-pin] reusing existing owner userId=${userId.slice(0, 8)}\u2026 (change-PIN preserves identity)`);
|
|
6451
6514
|
} else {
|
|
@@ -6716,14 +6779,14 @@ app5.post("/", async (c) => {
|
|
|
6716
6779
|
var client_error_default = app5;
|
|
6717
6780
|
|
|
6718
6781
|
// server/routes/admin/session.ts
|
|
6719
|
-
import { randomUUID as
|
|
6782
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
6720
6783
|
|
|
6721
6784
|
// app/lib/admin-identity/pin-validator.ts
|
|
6722
|
-
import { createHash as
|
|
6785
|
+
import { createHash as createHash3 } from "crypto";
|
|
6723
6786
|
import { existsSync as existsSync8, readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
6724
6787
|
import { join as join8 } from "path";
|
|
6725
6788
|
function hashPin2(pin) {
|
|
6726
|
-
return
|
|
6789
|
+
return createHash3("sha256").update(pin).digest("hex");
|
|
6727
6790
|
}
|
|
6728
6791
|
function readUsersFile2(usersFilePath) {
|
|
6729
6792
|
if (!existsSync8(usersFilePath)) return null;
|
|
@@ -6790,7 +6853,7 @@ async function resolveUserIdentity(accountId, userId) {
|
|
|
6790
6853
|
async function createAdminSession(accountId, thinkingView, userId, userName, role, avatar) {
|
|
6791
6854
|
const account = resolveAccount();
|
|
6792
6855
|
const effectiveThinkingView = thinkingView ?? account?.config.thinkingView ?? "default";
|
|
6793
|
-
const signedSessionToken =
|
|
6856
|
+
const signedSessionToken = randomUUID8();
|
|
6794
6857
|
const cacheKey = fingerprintSessionKey(signedSessionToken);
|
|
6795
6858
|
registerSession(cacheKey, "admin", accountId, void 0, userId, userName, role);
|
|
6796
6859
|
if (userId) setWantsPriorConversation(cacheKey);
|
|
@@ -8283,7 +8346,6 @@ function managerBase3() {
|
|
|
8283
8346
|
return `http://127.0.0.1:${port2}`;
|
|
8284
8347
|
}
|
|
8285
8348
|
var app12 = new Hono();
|
|
8286
|
-
var UUID_PATTERN = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
8287
8349
|
async function performSpawnWithInitialMessage(args) {
|
|
8288
8350
|
const ownerStart = Date.now();
|
|
8289
8351
|
const aboutOwner = await resolveOwnerProfileBlock(args.senderId, args.userId);
|
|
@@ -8323,7 +8385,7 @@ async function performSpawnWithInitialMessage(args) {
|
|
|
8323
8385
|
});
|
|
8324
8386
|
console.log(`${TAG18} forward-spawn-start managerBase=${managerBase3()} bytes=${upstreamPayload.length} hidden=${args.hidden} specialist=${args.specialist ?? "none"}`);
|
|
8325
8387
|
const forwardStart = Date.now();
|
|
8326
|
-
const upstream = await fetch(`${managerBase3()}/spawn`, {
|
|
8388
|
+
const upstream = await fetch(`${managerBase3()}/public-spawn`, {
|
|
8327
8389
|
method: "POST",
|
|
8328
8390
|
headers: { "content-type": "application/json" },
|
|
8329
8391
|
body: upstreamPayload
|
|
@@ -8360,16 +8422,7 @@ function mintTranscriptEdge(sessionId, claudeSessionId, accountId) {
|
|
|
8360
8422
|
if (!sessionId || !claudeSessionId) return;
|
|
8361
8423
|
void linkConversationTranscript(sessionId, claudeSessionId, accountId);
|
|
8362
8424
|
}
|
|
8363
|
-
|
|
8364
|
-
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
8365
|
-
const isLoopback = remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1";
|
|
8366
|
-
const hasForwardedFor = !!c.req.header("x-forwarded-for");
|
|
8367
|
-
if (isLoopback && !hasForwardedFor && c.req.method === "POST" && c.req.path === "/api/admin/claude-sessions") {
|
|
8368
|
-
return next();
|
|
8369
|
-
}
|
|
8370
|
-
return requireAdminSession(c, next);
|
|
8371
|
-
};
|
|
8372
|
-
app12.use("*", requireAdminSessionUnlessLoopbackSpawn);
|
|
8425
|
+
app12.use("*", requireAdminSession);
|
|
8373
8426
|
app12.post("/", async (c) => {
|
|
8374
8427
|
const routeStart = Date.now();
|
|
8375
8428
|
const cacheKey = c.get("cacheKey") ?? "";
|
|
@@ -8380,46 +8433,18 @@ app12.post("/", async (c) => {
|
|
|
8380
8433
|
}
|
|
8381
8434
|
const refusal = await refuseIfClaudeAuthDead(c, "spawn", null);
|
|
8382
8435
|
if (refusal) return refusal;
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
authSurface = "cookie";
|
|
8388
|
-
senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
8389
|
-
if (!senderId) {
|
|
8390
|
-
console.error(`${TAG18} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
|
|
8391
|
-
return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
8392
|
-
}
|
|
8393
|
-
userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
8394
|
-
} else {
|
|
8395
|
-
authSurface = "loopback";
|
|
8396
|
-
if (typeof body.adminSessionId !== "string" || !UUID_PATTERN.test(body.adminSessionId)) {
|
|
8397
|
-
return c.json({ error: "admin-session-id-required" }, 400);
|
|
8398
|
-
}
|
|
8399
|
-
const lookupSessionId = body.adminSessionId;
|
|
8400
|
-
const operatorMeta = await fetch(
|
|
8401
|
-
`${managerBase3()}/${encodeURIComponent(lookupSessionId)}/meta`
|
|
8402
|
-
).then((r) => r.ok ? r.json() : null).catch((err) => {
|
|
8403
|
-
console.error(`${TAG18} fetch-failed op=operator-meta-lookup message=${err instanceof Error ? err.message : String(err)}`);
|
|
8404
|
-
return null;
|
|
8405
|
-
});
|
|
8406
|
-
const metaSenderId = operatorMeta && typeof operatorMeta.senderId === "string" && operatorMeta.senderId.length > 0 ? operatorMeta.senderId : null;
|
|
8407
|
-
const bodyAccountId = typeof body.accountId === "string" && UUID_PATTERN.test(body.accountId) ? body.accountId : null;
|
|
8408
|
-
const operatorSenderId = metaSenderId ?? bodyAccountId;
|
|
8409
|
-
if (!operatorSenderId) {
|
|
8410
|
-
console.error(`${TAG18} reject reason=no-sender-id adminSessionId=${lookupSessionId.slice(0, 8)} metaSenderId=${metaSenderId ? "present" : "absent"} bodyAccountId=${bodyAccountId ? "present" : "absent"}`);
|
|
8411
|
-
return c.json({ error: "admin-session-not-found" }, 404);
|
|
8412
|
-
}
|
|
8413
|
-
console.log(`${TAG18} loopback-sender-resolved source=${metaSenderId ? "meta" : "body-accountId"} accountId=${operatorSenderId.slice(0, 8)}`);
|
|
8414
|
-
senderId = operatorSenderId;
|
|
8415
|
-
userId = void 0;
|
|
8436
|
+
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
8437
|
+
if (!senderId) {
|
|
8438
|
+
console.error(`${TAG18} reject reason=no-account-id cacheKey-prefix=${cacheKey.slice(0, 8)}`);
|
|
8439
|
+
return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
8416
8440
|
}
|
|
8441
|
+
const userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
8417
8442
|
const channel = typeof body.channel === "string" ? body.channel : "browser";
|
|
8418
8443
|
const initialMessage = typeof body.initialMessage === "string" && body.initialMessage.trim() ? body.initialMessage : null;
|
|
8419
8444
|
const permissionMode = typeof body.permissionMode === "string" ? body.permissionMode : void 0;
|
|
8420
8445
|
const specialist = typeof body.specialist === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(body.specialist) ? body.specialist : void 0;
|
|
8421
8446
|
const model = typeof body.model === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(body.model) ? body.model : void 0;
|
|
8422
|
-
console.log(`${TAG18} spawn-request-in surface
|
|
8447
|
+
console.log(`${TAG18} spawn-request-in surface=cookie accountId=${senderId.slice(0, 8)} userId=${userId ? userId.slice(0, 8) : "absent"} channel=${channel} permissionMode=${permissionMode ?? "default"} specialist=${specialist ?? "none"} model=${model ?? "default"} initialMessage=${initialMessage ? "yes" : "no"}`);
|
|
8423
8448
|
const conversationNodeId = cacheKey ? getSessionIdForSession(cacheKey) : void 0;
|
|
8424
8449
|
const { response, claudeSessionId } = await performSpawnWithInitialMessage({
|
|
8425
8450
|
senderId,
|
|
@@ -8438,7 +8463,7 @@ app12.post("/", async (c) => {
|
|
|
8438
8463
|
claudeSessionId,
|
|
8439
8464
|
senderId
|
|
8440
8465
|
);
|
|
8441
|
-
console.log(`${TAG18} route-done surface
|
|
8466
|
+
console.log(`${TAG18} route-done surface=cookie status=${response.status} route-ms=${Date.now() - routeStart}`);
|
|
8442
8467
|
return response;
|
|
8443
8468
|
});
|
|
8444
8469
|
var claude_sessions_default = app12;
|
|
@@ -9770,7 +9795,7 @@ function applyBacklinkBoost(hits) {
|
|
|
9770
9795
|
}
|
|
9771
9796
|
|
|
9772
9797
|
// ../lib/graph-search/src/dedup.ts
|
|
9773
|
-
import { createHash as
|
|
9798
|
+
import { createHash as createHash4 } from "crypto";
|
|
9774
9799
|
var DEFAULT_LAYERS = [
|
|
9775
9800
|
"nodeId",
|
|
9776
9801
|
"slug",
|
|
@@ -9797,7 +9822,7 @@ function readContentHash(props) {
|
|
|
9797
9822
|
const content = props["content"];
|
|
9798
9823
|
const source = typeof compiled === "string" && compiled.length > 0 ? compiled : typeof content === "string" && content.length > 0 ? content : null;
|
|
9799
9824
|
if (source === null) return null;
|
|
9800
|
-
return
|
|
9825
|
+
return createHash4("sha256").update(source).digest("hex").slice(0, 16);
|
|
9801
9826
|
}
|
|
9802
9827
|
function dedup(hits, layers = DEFAULT_LAYERS) {
|
|
9803
9828
|
const sorted = [...hits].sort((a, b) => b.score - a.score);
|
|
@@ -12542,6 +12567,7 @@ app27.get("/", async (c) => {
|
|
|
12542
12567
|
var health_default2 = app27;
|
|
12543
12568
|
|
|
12544
12569
|
// server/routes/admin/linkedin-ingest.ts
|
|
12570
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
12545
12571
|
var TAG20 = "[linkedin-ingest-route]";
|
|
12546
12572
|
var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
12547
12573
|
var ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
@@ -12584,11 +12610,14 @@ function buildInitialMessage(env) {
|
|
|
12584
12610
|
"sourceUrl=" + env.pageUrl,
|
|
12585
12611
|
"capturedAt=" + env.capturedAt
|
|
12586
12612
|
].join(" \xB7 ");
|
|
12613
|
+
const delegation = "Dispatch `database-operator` via the Task tool to carry out the ingestion described below \u2014 it owns every graph write. Do not call memory-write, memory-update, or any graph tool directly.";
|
|
12587
12614
|
if (env.kind === "profile" && env.profile) {
|
|
12588
12615
|
const p = env.profile;
|
|
12589
12616
|
return [
|
|
12590
12617
|
header,
|
|
12591
12618
|
"",
|
|
12619
|
+
delegation,
|
|
12620
|
+
"",
|
|
12592
12621
|
"Surface: LinkedIn profile. Run the document-ingest skill in document mode against the body below, anchored to a Person subject for this profile.",
|
|
12593
12622
|
"",
|
|
12594
12623
|
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
@@ -12617,6 +12646,8 @@ function buildInitialMessage(env) {
|
|
|
12617
12646
|
return [
|
|
12618
12647
|
header,
|
|
12619
12648
|
"",
|
|
12649
|
+
delegation,
|
|
12650
|
+
"",
|
|
12620
12651
|
"Surface: LinkedIn DM thread. Run the document-ingest skill in document mode against the transcript below.",
|
|
12621
12652
|
"",
|
|
12622
12653
|
"Conservative-extraction rules apply (see Task 234 spec):",
|
|
@@ -12656,39 +12687,30 @@ app28.post("/", requireAdminSession, async (c) => {
|
|
|
12656
12687
|
console.error(TAG20 + " rejected status=500 reason=admin-account-not-resolved");
|
|
12657
12688
|
return c.json({ ok: false, error: "admin-account-not-resolved" }, 500);
|
|
12658
12689
|
}
|
|
12659
|
-
const userId = getUserIdForSession(cacheKey) ?? void 0;
|
|
12660
12690
|
const payloadBytes = JSON.stringify(envelope).length;
|
|
12661
12691
|
console.log(
|
|
12662
12692
|
TAG20 + " received kind=" + envelope.kind + " account=" + senderId.slice(0, 8) + " pageUrl=" + envelope.pageUrl + " dispatchId=" + envelope.dispatchId + " payloadBytes=" + payloadBytes
|
|
12663
12693
|
);
|
|
12664
12694
|
const initialMessage = buildInitialMessage(envelope);
|
|
12665
12695
|
const spawnStart = Date.now();
|
|
12666
|
-
const
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
channel: "linkedin-extension",
|
|
12671
|
-
permissionMode: void 0,
|
|
12672
|
-
hidden: true,
|
|
12673
|
-
specialist: "database-operator",
|
|
12674
|
-
model: void 0,
|
|
12696
|
+
const sessionId = randomUUID9();
|
|
12697
|
+
console.log(TAG20 + " route target=rc-spawn dispatchId=" + envelope.dispatchId + " sessionId=" + sessionId.slice(0, 8));
|
|
12698
|
+
const spawned = await managerRcSpawn({
|
|
12699
|
+
sessionId,
|
|
12675
12700
|
initialMessage,
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
// `producedByTaskId` via work-create instead. Leave undefined.
|
|
12679
|
-
conversationNodeId: void 0
|
|
12701
|
+
closeAfterTurn: true,
|
|
12702
|
+
logContext: "linkedin-ingest dispatchId=" + envelope.dispatchId
|
|
12680
12703
|
});
|
|
12681
|
-
if (
|
|
12682
|
-
const detail = await response.text().catch(() => "");
|
|
12704
|
+
if ("error" in spawned) {
|
|
12683
12705
|
console.error(
|
|
12684
|
-
TAG20 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" +
|
|
12706
|
+
TAG20 + " dispatch-failed dispatchId=" + envelope.dispatchId + " status=" + spawned.status + " ms=" + (Date.now() - spawnStart) + " message=" + spawned.error
|
|
12685
12707
|
);
|
|
12686
|
-
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus:
|
|
12708
|
+
return c.json({ ok: false, error: "dispatch-failed", upstreamStatus: spawned.status, detail: spawned.error }, 502);
|
|
12687
12709
|
}
|
|
12688
12710
|
console.log(
|
|
12689
|
-
TAG20 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" +
|
|
12711
|
+
TAG20 + " dispatched dispatchId=" + envelope.dispatchId + " taskId=" + spawned.sessionId + " ms=" + (Date.now() - spawnStart)
|
|
12690
12712
|
);
|
|
12691
|
-
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId:
|
|
12713
|
+
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: spawned.sessionId }, 202);
|
|
12692
12714
|
});
|
|
12693
12715
|
var linkedin_ingest_default = app28;
|
|
12694
12716
|
|
|
@@ -13056,7 +13078,7 @@ var admin_default = app34;
|
|
|
13056
13078
|
import neo4j4 from "neo4j-driver";
|
|
13057
13079
|
import { readFileSync as readFileSync17 } from "fs";
|
|
13058
13080
|
import { resolve as resolve19 } from "path";
|
|
13059
|
-
import { randomUUID as
|
|
13081
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
13060
13082
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve19(process.cwd(), "..");
|
|
13061
13083
|
var driver = null;
|
|
13062
13084
|
function readPassword() {
|
|
@@ -13239,7 +13261,7 @@ async function consumeMagicTokenAndActivate(grantId) {
|
|
|
13239
13261
|
}
|
|
13240
13262
|
}
|
|
13241
13263
|
async function generateNewMagicToken(grantId) {
|
|
13242
|
-
const token =
|
|
13264
|
+
const token = randomUUID10();
|
|
13243
13265
|
const session = getSession3();
|
|
13244
13266
|
try {
|
|
13245
13267
|
const result = await session.run(
|
|
@@ -14280,6 +14302,10 @@ app42.post("/", async (c) => {
|
|
|
14280
14302
|
if (!validateAgentSlug(body.agent)) {
|
|
14281
14303
|
return c.json({ error: "Invalid agent name" }, 400);
|
|
14282
14304
|
}
|
|
14305
|
+
if (!account || !isActiveAgentSlug(account.accountDir, body.agent)) {
|
|
14306
|
+
console.error(`[session] op=reject agent=${body.agent} reason=not-active`);
|
|
14307
|
+
return c.json({ error: "no-agent-for-address" }, 404);
|
|
14308
|
+
}
|
|
14283
14309
|
agentSlug = body.agent;
|
|
14284
14310
|
} else {
|
|
14285
14311
|
agentSlug = account ? resolveDefaultAgentSlug(account.accountDir) : null;
|
|
@@ -14691,7 +14717,7 @@ function broadcastAdminShutdown(reason) {
|
|
|
14691
14717
|
}
|
|
14692
14718
|
|
|
14693
14719
|
// ../lib/entitlement/src/index.ts
|
|
14694
|
-
import { createPublicKey, createHash as
|
|
14720
|
+
import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
|
|
14695
14721
|
import { existsSync as existsSync22, readFileSync as readFileSync21, statSync as statSync9 } from "fs";
|
|
14696
14722
|
import { resolve as resolve24 } from "path";
|
|
14697
14723
|
|
|
@@ -14762,7 +14788,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
14762
14788
|
reason: "pubkey-missing"
|
|
14763
14789
|
});
|
|
14764
14790
|
}
|
|
14765
|
-
const pubkeyHash =
|
|
14791
|
+
const pubkeyHash = createHash5("sha256").update(pubkeyPem).digest("hex");
|
|
14766
14792
|
if (pubkeyHash !== PUBKEY_SHA256) {
|
|
14767
14793
|
return logResolved(anonymousFallback("pubkey-tamper"), {
|
|
14768
14794
|
reason: "pubkey-tamper"
|
|
@@ -15491,6 +15517,9 @@ function brandedPublicHtml(agentSlug) {
|
|
|
15491
15517
|
function escapeHtml(s) {
|
|
15492
15518
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
15493
15519
|
}
|
|
15520
|
+
function agentUnavailableHtml() {
|
|
15521
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">Agent unavailable</h1><p>This agent isn't available right now. If you reached this page from a saved link, the agent may have been turned off.</p></body></html>`;
|
|
15522
|
+
}
|
|
15494
15523
|
app43.get("/", (c) => {
|
|
15495
15524
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
15496
15525
|
if (isPublicHost(host)) {
|
|
@@ -15587,6 +15616,11 @@ app43.get("/data", (c) => {
|
|
|
15587
15616
|
app43.get("/:slug", async (c, next) => {
|
|
15588
15617
|
const slug = c.req.param("slug");
|
|
15589
15618
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
15619
|
+
const account = resolveAccount();
|
|
15620
|
+
if (!account || !validateAgentSlug(slug) || !isActiveAgentSlug(account.accountDir, slug)) {
|
|
15621
|
+
console.error(`[public-catchall] op=reject path=/${slug} slug=${slug} reason=not-reachable`);
|
|
15622
|
+
return c.html(agentUnavailableHtml(), 404);
|
|
15623
|
+
}
|
|
15590
15624
|
const branding = loadBrandingCache(slug);
|
|
15591
15625
|
console.error(`[public-catchall] served path=/${slug} slug=${slug} branding=${branding ? "hit" : "miss"}`);
|
|
15592
15626
|
return c.html(brandedPublicHtml(slug));
|