@rubytech/create-realagent 1.0.617 → 1.0.618
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 -0
- package/payload/platform/plugins/admin/hooks/webfetch-preflight.mjs +363 -0
- package/payload/platform/plugins/admin/skills/stream-log-review/SKILL.md +4 -1
- package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js +135 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts +17 -10
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +65 -25
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
- package/payload/platform/plugins/cloudflare/references/setup-guide.md +2 -2
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +4 -2
- package/payload/platform/plugins/docs/references/cloudflare.md +8 -8
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -0
- package/payload/platform/scripts/seed-neo4j.sh +12 -0
- package/payload/platform/templates/agents/admin/IDENTITY.md +2 -0
- package/payload/platform/templates/specialists/agents/personal-assistant.md +5 -5
- package/payload/server/public/assets/{admin-Df1liz4Y.js → admin-D7LRdkYB.js} +30 -30
- package/payload/server/public/index.html +1 -1
- package/payload/server/server.js +87 -23
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Real Agent</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/admin-
|
|
8
|
+
<script type="module" crossorigin src="/assets/admin-D7LRdkYB.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-Be6NvmcD.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-rov5CBGT.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-OB_Gtr0e.js">
|
package/payload/server/server.js
CHANGED
|
@@ -6211,14 +6211,22 @@ function purgeOldLogs(logDir, prefix) {
|
|
|
6211
6211
|
}
|
|
6212
6212
|
}
|
|
6213
6213
|
function teeProcStderrToStreamLog(proc, streamLog) {
|
|
6214
|
+
const pid = proc.pid;
|
|
6214
6215
|
if (!proc.stderr) {
|
|
6215
|
-
streamLog.write(`[${isoTs()}] [subproc-stderr-skip] reason=no-stderr
|
|
6216
|
+
streamLog.write(`[${isoTs()}] [subproc-stderr-skip] reason=no-stderr pid=${pid}
|
|
6216
6217
|
`);
|
|
6217
6218
|
return;
|
|
6218
6219
|
}
|
|
6220
|
+
if (!streamLog.destroyed && !streamLog.writableEnded) {
|
|
6221
|
+
streamLog.write(`[${isoTs()}] [subproc-stderr-tee-attached] pid=${pid}
|
|
6222
|
+
`);
|
|
6223
|
+
}
|
|
6219
6224
|
const utf8 = new StringDecoder("utf8");
|
|
6220
6225
|
let buffer = "";
|
|
6226
|
+
let bytesSeen = 0;
|
|
6227
|
+
let linesEmitted = 0;
|
|
6221
6228
|
proc.stderr.on("data", (chunk) => {
|
|
6229
|
+
bytesSeen += typeof chunk === "string" ? Buffer.byteLength(chunk, "utf8") : chunk.length;
|
|
6222
6230
|
const text = typeof chunk === "string" ? chunk : utf8.write(chunk);
|
|
6223
6231
|
buffer += text;
|
|
6224
6232
|
let idx;
|
|
@@ -6229,12 +6237,18 @@ function teeProcStderrToStreamLog(proc, streamLog) {
|
|
|
6229
6237
|
if (streamLog.destroyed || streamLog.writableEnded) continue;
|
|
6230
6238
|
streamLog.write(`[${isoTs()}] [subproc-stderr] ${line}
|
|
6231
6239
|
`);
|
|
6240
|
+
linesEmitted++;
|
|
6232
6241
|
}
|
|
6233
6242
|
});
|
|
6234
6243
|
proc.stderr.on("end", () => {
|
|
6235
6244
|
const tail = (buffer + utf8.end()).trim();
|
|
6236
6245
|
if (tail.length > 0 && !streamLog.destroyed && !streamLog.writableEnded) {
|
|
6237
6246
|
streamLog.write(`[${isoTs()}] [subproc-stderr] ${tail}
|
|
6247
|
+
`);
|
|
6248
|
+
linesEmitted++;
|
|
6249
|
+
}
|
|
6250
|
+
if (!streamLog.destroyed && !streamLog.writableEnded) {
|
|
6251
|
+
streamLog.write(`[${isoTs()}] [subproc-stderr-tee-detached] pid=${pid} bytes=${bytesSeen} lines=${linesEmitted}
|
|
6238
6252
|
`);
|
|
6239
6253
|
}
|
|
6240
6254
|
buffer = "";
|
|
@@ -8284,10 +8298,11 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
8284
8298
|
env: {
|
|
8285
8299
|
...process.env,
|
|
8286
8300
|
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
8287
|
-
ACCOUNT_DIR: accountDir
|
|
8288
|
-
// Task
|
|
8289
|
-
//
|
|
8290
|
-
|
|
8301
|
+
ACCOUNT_DIR: accountDir
|
|
8302
|
+
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
8303
|
+
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
8304
|
+
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
8305
|
+
// line below records the source-of-silence explicitly.
|
|
8291
8306
|
}
|
|
8292
8307
|
});
|
|
8293
8308
|
const stderrLog = agentLogStream("claude-agent-compaction-stderr", accountDir, conversationId);
|
|
@@ -8298,6 +8313,8 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
8298
8313
|
streamLog.on("error", () => {
|
|
8299
8314
|
});
|
|
8300
8315
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
8316
|
+
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
8317
|
+
`);
|
|
8301
8318
|
streamLog.write(`[${isoTs()}] [compaction-start] resumeSessionId=${resumeSessionId}
|
|
8302
8319
|
`);
|
|
8303
8320
|
proc.on("error", (err) => {
|
|
@@ -9171,11 +9188,11 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9171
9188
|
env: {
|
|
9172
9189
|
...process.env,
|
|
9173
9190
|
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
9174
|
-
ACCOUNT_DIR: accountDir
|
|
9175
|
-
// Task
|
|
9176
|
-
//
|
|
9177
|
-
//
|
|
9178
|
-
|
|
9191
|
+
ACCOUNT_DIR: accountDir
|
|
9192
|
+
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
9193
|
+
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
9194
|
+
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
9195
|
+
// line below records the source-of-silence explicitly.
|
|
9179
9196
|
}
|
|
9180
9197
|
});
|
|
9181
9198
|
const stderrLog = agentLogStream("claude-agent-stderr", accountDir, spawnConvId);
|
|
@@ -9186,6 +9203,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9186
9203
|
streamLog.on("error", () => {
|
|
9187
9204
|
});
|
|
9188
9205
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
9206
|
+
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
9207
|
+
`);
|
|
9189
9208
|
if (sessionKey) {
|
|
9190
9209
|
const prev = activeProcesses.get(sessionKey);
|
|
9191
9210
|
if (prev) {
|
|
@@ -9513,10 +9532,11 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9513
9532
|
env: {
|
|
9514
9533
|
...process.env,
|
|
9515
9534
|
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
9516
|
-
ACCOUNT_DIR: accountDir
|
|
9517
|
-
// Task
|
|
9518
|
-
//
|
|
9519
|
-
|
|
9535
|
+
ACCOUNT_DIR: accountDir
|
|
9536
|
+
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
9537
|
+
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
9538
|
+
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
9539
|
+
// line below records the source-of-silence explicitly.
|
|
9520
9540
|
}
|
|
9521
9541
|
});
|
|
9522
9542
|
const stderrLog = agentLogStream("claude-agent-stderr", accountDir, managedConvId);
|
|
@@ -9524,6 +9544,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9524
9544
|
});
|
|
9525
9545
|
proc.stderr?.pipe(stderrLog);
|
|
9526
9546
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
9547
|
+
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
9548
|
+
`);
|
|
9527
9549
|
if (sessionKey) {
|
|
9528
9550
|
const prev = activeProcesses.get(sessionKey);
|
|
9529
9551
|
if (prev) {
|
|
@@ -10480,6 +10502,26 @@ function defaultRules() {
|
|
|
10480
10502
|
scope: "session",
|
|
10481
10503
|
suggestedAction: "A tool call has been pending for 30 seconds without a result. Read the adjacent [tool-wait-diag] and [tool-wait-proc] lines in the conversation's stream log to determine whether the network remained healthy, the subprocess held active sockets, and the HTTP request reached the wire. If diag shows a healthy network but the subprocess has no [subproc-stderr] UNDICI/HTTP activity during the wait window, the tool's internal pipeline is stalled \u2014 do not retry the same request against the same target without a change in approach."
|
|
10482
10504
|
},
|
|
10505
|
+
{
|
|
10506
|
+
// Task 536: detect agents ignoring the WEBFETCH_CANNOT_READ_JS_SPA
|
|
10507
|
+
// structured failure. A single SPA short-circuit per conversation is
|
|
10508
|
+
// expected — the hook is doing its job. Two or more in the same
|
|
10509
|
+
// conversation within 5 minutes means either (a) the agent retried
|
|
10510
|
+
// WebFetch on the same SPA URL despite the directive, or (b) the
|
|
10511
|
+
// owner is asking about multiple SPA URLs in one session and the
|
|
10512
|
+
// pattern needs surfacing as a recurring class. Both signal that the
|
|
10513
|
+
// IDENTITY.md "Tool Failure Discipline" guidance is not landing in the
|
|
10514
|
+
// prompt — revise the copy rather than add mechanical enforcement.
|
|
10515
|
+
id: "webfetch-spa-short-circuit-recurring",
|
|
10516
|
+
name: "WebFetch JS-SPA short-circuit fired repeatedly in conversation",
|
|
10517
|
+
type: "repeated-error",
|
|
10518
|
+
logSource: "system",
|
|
10519
|
+
pattern: "WEBFETCH_CANNOT_READ_JS_SPA",
|
|
10520
|
+
thresholdCount: 2,
|
|
10521
|
+
thresholdWindowMinutes: 5,
|
|
10522
|
+
scope: "session",
|
|
10523
|
+
suggestedAction: "The WebFetch SPA preflight has fired more than once in this conversation. Either the agent is ignoring the loud-failure directive (retrying WebFetch after seeing WEBFETCH_CANNOT_READ_JS_SPA), or multiple SPA URLs are being asked about. Read the conversation's stream log for the [tool-use] / [tool-result] sequence around each occurrence \u2014 if the agent dispatched WebFetch on the same URL or substituted Playwright silently, revisit the IDENTITY.md `Tool Failure Discipline` paragraph that names structured-error handling."
|
|
10524
|
+
},
|
|
10483
10525
|
{
|
|
10484
10526
|
// Task 533: surface every Cloudflare-plugin refusal. The plugin emits
|
|
10485
10527
|
// exactly one [cloudflare:refuse] line per refusal with a structured
|
|
@@ -31172,18 +31214,23 @@ async function GET9(request) {
|
|
|
31172
31214
|
const accountLogDir2 = account ? resolve19(account.accountDir, "logs") : null;
|
|
31173
31215
|
if (fileParam) {
|
|
31174
31216
|
const safe = basename5(fileParam);
|
|
31217
|
+
const searched = [];
|
|
31175
31218
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31176
31219
|
if (!dir) continue;
|
|
31177
31220
|
const filePath = resolve19(dir, safe);
|
|
31221
|
+
searched.push(filePath);
|
|
31178
31222
|
try {
|
|
31179
31223
|
const content = readFileSync20(filePath, "utf-8");
|
|
31180
31224
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31181
31225
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
31182
31226
|
return new Response(content, { headers });
|
|
31183
|
-
} catch {
|
|
31227
|
+
} catch (err) {
|
|
31228
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
31229
|
+
console.debug(`[admin/logs] miss dir=${dir} name=${safe} reason=${reason}`);
|
|
31184
31230
|
}
|
|
31185
31231
|
}
|
|
31186
|
-
|
|
31232
|
+
console.warn(`[admin/logs] not-found name=${safe} searched=[${searched.join(",")}]`);
|
|
31233
|
+
return Response.json({ error: `File not found: ${safe}`, code: "NOT_FOUND" }, { status: 404 });
|
|
31187
31234
|
}
|
|
31188
31235
|
if (typeParam) {
|
|
31189
31236
|
const prefixMap = {
|
|
@@ -31195,24 +31242,37 @@ async function GET9(request) {
|
|
|
31195
31242
|
};
|
|
31196
31243
|
const prefix = prefixMap[typeParam];
|
|
31197
31244
|
if (!prefix) {
|
|
31198
|
-
|
|
31245
|
+
console.warn(`[admin/logs] rejected reason=unknown-type type=${typeParam}`);
|
|
31246
|
+
return Response.json(
|
|
31247
|
+
{ error: `Unknown type: ${typeParam}. Valid: stream, error, session, sse, public`, code: "UNKNOWN_TYPE" },
|
|
31248
|
+
{ status: 400 }
|
|
31249
|
+
);
|
|
31199
31250
|
}
|
|
31200
31251
|
if (!conversationIdParam) {
|
|
31201
|
-
|
|
31252
|
+
console.warn(`[admin/logs] rejected type=${typeParam} reason=no-conversationId`);
|
|
31253
|
+
return Response.json(
|
|
31254
|
+
{ error: `type=${typeParam} requires conversationId (per-conversation log files, no daily fallback)`, code: "CONVERSATION_ID_REQUIRED" },
|
|
31255
|
+
{ status: 400 }
|
|
31256
|
+
);
|
|
31202
31257
|
}
|
|
31203
31258
|
const fileName = `${prefix}-${conversationIdParam}.log`;
|
|
31259
|
+
const searched = [];
|
|
31204
31260
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31205
31261
|
if (!dir) continue;
|
|
31206
31262
|
const filePath = resolve19(dir, fileName);
|
|
31263
|
+
searched.push(filePath);
|
|
31207
31264
|
try {
|
|
31208
31265
|
const content = readFileSync20(filePath, "utf-8");
|
|
31209
31266
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
31210
31267
|
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
31211
31268
|
return new Response(content, { headers });
|
|
31212
|
-
} catch {
|
|
31269
|
+
} catch (err) {
|
|
31270
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
31271
|
+
console.debug(`[admin/logs] miss dir=${dir} name=${fileName} reason=${reason}`);
|
|
31213
31272
|
}
|
|
31214
31273
|
}
|
|
31215
|
-
|
|
31274
|
+
console.warn(`[admin/logs] not-found name=${fileName} searched=[${searched.join(",")}]`);
|
|
31275
|
+
return Response.json({ error: `Log not found: ${fileName}`, code: "NOT_FOUND" }, { status: 404 });
|
|
31216
31276
|
}
|
|
31217
31277
|
const seen = /* @__PURE__ */ new Set();
|
|
31218
31278
|
const logs = {};
|
|
@@ -31221,7 +31281,9 @@ async function GET9(request) {
|
|
|
31221
31281
|
let files;
|
|
31222
31282
|
try {
|
|
31223
31283
|
files = readdirSync5(dir).filter((f) => f.endsWith(".log"));
|
|
31224
|
-
} catch {
|
|
31284
|
+
} catch (err) {
|
|
31285
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
31286
|
+
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
31225
31287
|
continue;
|
|
31226
31288
|
}
|
|
31227
31289
|
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync7(resolve19(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
@@ -31230,8 +31292,10 @@ async function GET9(request) {
|
|
|
31230
31292
|
const content = readFileSync20(resolve19(dir, name));
|
|
31231
31293
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
31232
31294
|
logs[name] = tail.trim() || "(empty)";
|
|
31233
|
-
} catch {
|
|
31234
|
-
|
|
31295
|
+
} catch (err) {
|
|
31296
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
31297
|
+
console.debug(`[admin/logs] read-fail name=${name} reason=${reason}`);
|
|
31298
|
+
logs[name] = `(unreadable: ${reason})`;
|
|
31235
31299
|
}
|
|
31236
31300
|
});
|
|
31237
31301
|
}
|