@rubytech/create-realagent 1.0.842 → 1.0.844
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 +2 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +133 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/skill-builder/SKILL.md +18 -19
- package/payload/platform/plugins/docs/references/plugins-guide.md +11 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +3 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +3 -1
- package/payload/premium-plugins/real-agency/BUNDLE.md +2 -4
- package/payload/server/chunk-H7AEWSE6.js +1569 -0
- package/payload/server/chunk-LU2UG7KB.js +10310 -0
- package/payload/server/chunk-OLP7LZDW.js +10119 -0
- package/payload/server/client-pool-MTXUA5HQ.js +34 -0
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/server.js +3 -3
- package/payload/premium-plugins/real-agency/plugins/real-agency-brochures/PLUGIN.md +0 -31
- package/payload/premium-plugins/real-agency/plugins/real-agency-brochures/skills/property-brochure/SKILL.md +0 -194
- package/payload/premium-plugins/real-agency/plugins/real-agency-brochures/skills/property-brochure/references/template.html +0 -1451
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: admin
|
|
3
|
-
description: "Platform administration plugin. Provides system-status, brand-settings, account-manage, account-update, admin-add, admin-remove, admin-list, admin-update-pin, agent-list, agent-config-read, logs-read, plugin-read, render-component, session-reset, session-resume, file-attach, wifi, adherence-read (attention-weighted adherence ledger), and action-approval tools (action-pending, action-approve, action-reject, action-edit) for managing the Maxy platform."
|
|
3
|
+
description: "Platform administration plugin. Provides system-status, brand-settings, account-manage, account-update, admin-add, admin-remove, admin-list, admin-update-pin, agent-list, agent-config-read, logs-read, plugin-read, store-skill (deterministic write counterpart to plugin-read; persists operator-authored skills as plugin files under the active account), render-component, session-reset, session-resume, file-attach, wifi, adherence-read (attention-weighted adherence ledger), and action-approval tools (action-pending, action-approve, action-reject, action-edit) for managing the Maxy platform."
|
|
4
4
|
tools:
|
|
5
5
|
- system-status
|
|
6
6
|
- brand-settings
|
|
@@ -14,6 +14,7 @@ tools:
|
|
|
14
14
|
- agent-config-read
|
|
15
15
|
- logs-read
|
|
16
16
|
- plugin-read
|
|
17
|
+
- store-skill
|
|
17
18
|
- render-component
|
|
18
19
|
- session-reset
|
|
19
20
|
- session-resume
|
|
@@ -6,7 +6,7 @@ import { z } from "zod";
|
|
|
6
6
|
import { readFile, writeFile } from "node:fs/promises";
|
|
7
7
|
import { resolve, join } from "node:path";
|
|
8
8
|
import { execFileSync } from "node:child_process";
|
|
9
|
-
import { appendFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { appendFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { writeKey, validateKey, hasKey, keyFilePath, deleteKey } from "../../../../lib/anthropic-key/dist/index.js";
|
|
11
11
|
import { writeAdminEntry, removeAdminFromAccount } from "../../../../lib/admins-write/dist/index.js";
|
|
12
12
|
import { deviceUrlBlock } from "../../../../lib/device-url/dist/index.js";
|
|
@@ -1421,6 +1421,138 @@ server.tool("logs-read", "Read recent logs. Stream logs (type=agent-stream/error
|
|
|
1421
1421
|
return { content: [{ type: "text", text: `Failed to read logs: ${err instanceof Error ? err.message : String(err)}` }] };
|
|
1422
1422
|
}
|
|
1423
1423
|
});
|
|
1424
|
+
// Task 918 — operator-authored skills are written to disk as a plugin so the
|
|
1425
|
+
// existing plugin-manifest loader picks them up (parsePluginFrontmatter +
|
|
1426
|
+
// assemblePublicPluginContent + loadEmbeddedPlugins all read from
|
|
1427
|
+
// <PLATFORM_ROOT>/plugins/<dir>/). Canonical = <accountDir>/plugins/<plugin>
|
|
1428
|
+
// survives installer rmSync (data/ excluded); the mirror under
|
|
1429
|
+
// <PLATFORM_ROOT>/plugins/<plugin> is rehydrated at admin session start by
|
|
1430
|
+
// autoDeliverUserPlugins. The agent supplies pluginName/skillName/body —
|
|
1431
|
+
// path is computed by this tool from ACCOUNT_ID. Symmetric write counterpart
|
|
1432
|
+
// to plugin-read (Task 916).
|
|
1433
|
+
server.tool("store-skill", "Save an operator-authored skill on disk as part of an admin-managed plugin. " +
|
|
1434
|
+
"The skill becomes immediately discoverable by the admin agent (and the public agent if publicEmbed=true). " +
|
|
1435
|
+
"Path is computed internally from the active account; the agent supplies content + names only. " +
|
|
1436
|
+
"Re-running for the same skillName overwrites in place (drops orphan reference files).", {
|
|
1437
|
+
pluginName: z.string().describe("Plugin directory name in lowercase kebab-case (e.g. 'beacons-skills'). Must not collide with a shipped plugin name."),
|
|
1438
|
+
skillName: z.string().describe("Skill directory name in lowercase kebab-case (e.g. 'lead-capture')."),
|
|
1439
|
+
description: z.string().describe("One-sentence skill description used in SKILL.md frontmatter and as the trigger hint for the agent."),
|
|
1440
|
+
publicEmbed: z.boolean().describe("True to embed this skill in the public agent's system prompt; false for admin-only."),
|
|
1441
|
+
body: z.string().describe("SKILL.md body content WITHOUT frontmatter. Frontmatter (name, description, publicEmbed) is composed by the tool."),
|
|
1442
|
+
references: z.array(z.object({
|
|
1443
|
+
filename: z.string().describe("Reference filename matching ^[a-z0-9-]+\\.md$ (no path separators)."),
|
|
1444
|
+
content: z.string().describe("Reference file body content."),
|
|
1445
|
+
})).default([]).describe("Optional reference files written under skills/<skillName>/references/."),
|
|
1446
|
+
}, async ({ pluginName, skillName, description, publicEmbed, body, references }) => {
|
|
1447
|
+
const KEBAB_RE = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
1448
|
+
const REF_RE = /^[a-z0-9-]+\.md$/;
|
|
1449
|
+
if (!KEBAB_RE.test(pluginName)) {
|
|
1450
|
+
console.error(`[store-skill] ERROR pluginName=${pluginName} reason=invalid-kebab path=-`);
|
|
1451
|
+
return { content: [{ type: "text", text: `pluginName must be lowercase kebab-case (1-64 chars, no leading/trailing hyphen): "${pluginName}"` }], isError: true };
|
|
1452
|
+
}
|
|
1453
|
+
if (!KEBAB_RE.test(skillName)) {
|
|
1454
|
+
console.error(`[store-skill] ERROR pluginName=${pluginName} skillName=${skillName} reason=invalid-kebab path=-`);
|
|
1455
|
+
return { content: [{ type: "text", text: `skillName must be lowercase kebab-case (1-64 chars, no leading/trailing hyphen): "${skillName}"` }], isError: true };
|
|
1456
|
+
}
|
|
1457
|
+
for (const ref of references) {
|
|
1458
|
+
if (!REF_RE.test(ref.filename)) {
|
|
1459
|
+
console.error(`[store-skill] ERROR pluginName=${pluginName} skillName=${skillName} reason=invalid-ref-filename ref=${ref.filename} path=-`);
|
|
1460
|
+
return { content: [{ type: "text", text: `reference filename must match ^[a-z0-9-]+\\.md$: "${ref.filename}"` }], isError: true };
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
const accountDir = getAccountDir();
|
|
1464
|
+
const canonicalPluginDir = resolve(accountDir, "plugins", pluginName);
|
|
1465
|
+
const mirrorPluginDir = resolve(PLATFORM_ROOT, "plugins", pluginName);
|
|
1466
|
+
const canonicalPluginMd = resolve(canonicalPluginDir, "PLUGIN.md");
|
|
1467
|
+
const mirrorPluginMd = resolve(mirrorPluginDir, "PLUGIN.md");
|
|
1468
|
+
// Collision: mirror dir exists from a shipped plugin (no canonical mirror).
|
|
1469
|
+
// Refuse rather than silently shadow.
|
|
1470
|
+
if (existsSync(mirrorPluginMd) && !existsSync(canonicalPluginMd)) {
|
|
1471
|
+
console.error(`[store-skill] ERROR pluginName=${pluginName} skillName=${skillName} reason=collision-with-shipped path=${mirrorPluginDir}`);
|
|
1472
|
+
return { content: [{ type: "text", text: `pluginName "${pluginName}" collides with a shipped plugin. Choose a different pluginName.` }], isError: true };
|
|
1473
|
+
}
|
|
1474
|
+
const skillDir = resolve(canonicalPluginDir, "skills", skillName);
|
|
1475
|
+
const action = existsSync(resolve(skillDir, "SKILL.md")) ? "overwrite" : "create";
|
|
1476
|
+
try {
|
|
1477
|
+
mkdirSync(canonicalPluginDir, { recursive: true });
|
|
1478
|
+
// Compose PLUGIN.md only on first write. embed=["admin","public"] +
|
|
1479
|
+
// optional=false matches assemblePublicPluginContent / loadEmbeddedPlugins
|
|
1480
|
+
// expectations. metadata is single-line JSON (parsePluginFrontmatter at
|
|
1481
|
+
// plugin-manifest.ts:67 expects single-line) — multi-line silently falls
|
|
1482
|
+
// back to platform={}.
|
|
1483
|
+
if (!existsSync(canonicalPluginMd)) {
|
|
1484
|
+
const pluginMd = `---
|
|
1485
|
+
name: ${pluginName}
|
|
1486
|
+
description: "Operator-authored plugin"
|
|
1487
|
+
tools: []
|
|
1488
|
+
hidden: []
|
|
1489
|
+
requires: []
|
|
1490
|
+
metadata: {"platform":{"embed":["admin","public"],"optional":false}}
|
|
1491
|
+
---
|
|
1492
|
+
|
|
1493
|
+
# ${pluginName}
|
|
1494
|
+
|
|
1495
|
+
Operator-authored plugin. Skills under \`skills/\` were created via the admin skill-builder.
|
|
1496
|
+
`;
|
|
1497
|
+
writeFileSync(canonicalPluginMd, pluginMd);
|
|
1498
|
+
}
|
|
1499
|
+
// Reset skill dir before write so removed reference files don't linger.
|
|
1500
|
+
if (existsSync(skillDir)) {
|
|
1501
|
+
rmSync(skillDir, { recursive: true, force: true });
|
|
1502
|
+
}
|
|
1503
|
+
mkdirSync(skillDir, { recursive: true });
|
|
1504
|
+
// Normalise description — strip newlines and tabs to keep YAML
|
|
1505
|
+
// frontmatter on a single line. parsePluginFrontmatter uses a
|
|
1506
|
+
// single-line regex; an embedded newline (or `\n---\n`) would
|
|
1507
|
+
// otherwise corrupt the frontmatter parse and silently drop body
|
|
1508
|
+
// content from the agent prompt.
|
|
1509
|
+
const singleLineDescription = description.replace(/[\r\n\t]+/g, " ").trim();
|
|
1510
|
+
const escapedDescription = singleLineDescription.replace(/"/g, '\\"');
|
|
1511
|
+
const skillMd = `---
|
|
1512
|
+
name: ${skillName}
|
|
1513
|
+
description: "${escapedDescription}"
|
|
1514
|
+
publicEmbed: ${publicEmbed}
|
|
1515
|
+
---
|
|
1516
|
+
|
|
1517
|
+
${body}
|
|
1518
|
+
`;
|
|
1519
|
+
writeFileSync(resolve(skillDir, "SKILL.md"), skillMd);
|
|
1520
|
+
let refCount = 0;
|
|
1521
|
+
if (references.length > 0) {
|
|
1522
|
+
const refsDir = resolve(skillDir, "references");
|
|
1523
|
+
mkdirSync(refsDir, { recursive: true });
|
|
1524
|
+
for (const ref of references) {
|
|
1525
|
+
writeFileSync(resolve(refsDir, ref.filename), ref.content);
|
|
1526
|
+
refCount++;
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
// Write the `.user-mirror` marker to CANONICAL first — cpSync will
|
|
1530
|
+
// carry it into the platform-side mirror as part of the same recursive
|
|
1531
|
+
// copy. This eliminates the post-cpSync writeFileSync race: if cpSync
|
|
1532
|
+
// succeeds, the marker is already in target; if cpSync fails partway,
|
|
1533
|
+
// canonical's marker is intact and the next autoDeliverUserPlugins
|
|
1534
|
+
// call retries the copy. autoDeliverUserPlugins relies on the marker
|
|
1535
|
+
// arriving with the source tree — never writes its own marker.
|
|
1536
|
+
writeFileSync(resolve(canonicalPluginDir, ".user-mirror"), `pluginName=${pluginName}\nsource=${canonicalPluginDir}\n`);
|
|
1537
|
+
// Mirror to <PLATFORM_ROOT>/plugins/<pluginName>/ so the change is
|
|
1538
|
+
// visible to the loader without a session restart.
|
|
1539
|
+
mkdirSync(mirrorPluginDir, { recursive: true });
|
|
1540
|
+
cpSync(canonicalPluginDir, mirrorPluginDir, { recursive: true, force: true });
|
|
1541
|
+
const bodyBytes = Buffer.byteLength(body, "utf-8");
|
|
1542
|
+
console.log(`[store-skill] write pluginName=${pluginName} skillName=${skillName} publicEmbed=${publicEmbed} path=${canonicalPluginDir} bodyBytes=${bodyBytes} referenceCount=${refCount} action=${action}`);
|
|
1543
|
+
return {
|
|
1544
|
+
content: [{
|
|
1545
|
+
type: "text",
|
|
1546
|
+
text: `Skill "${skillName}" saved to plugin "${pluginName}" (${action}). publicEmbed=${publicEmbed}, references=${refCount}. Active immediately for the admin agent${publicEmbed ? "; surfaces in the public agent on next session start" : ""}.`,
|
|
1547
|
+
}],
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
catch (err) {
|
|
1551
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1552
|
+
console.error(`[store-skill] ERROR pluginName=${pluginName} skillName=${skillName} reason=${msg.slice(0, 120)} path=${canonicalPluginDir}`);
|
|
1553
|
+
return { content: [{ type: "text", text: `Failed to write skill: ${msg}` }], isError: true };
|
|
1554
|
+
}
|
|
1555
|
+
});
|
|
1424
1556
|
server.tool("plugin-read", "Read a plugin definition (PLUGIN.md) or one of its reference files.", {
|
|
1425
1557
|
pluginName: z.string().describe("Name of the plugin directory (e.g. 'sales', 'business-assistant')"),
|
|
1426
1558
|
file: z.string().optional().describe("Specific file to read (e.g. 'references/pricing.md'). Defaults to PLUGIN.md."),
|