@rubytech/create-maxy-code 0.1.243 → 0.1.246

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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +230 -0
  3. package/payload/platform/neo4j/schema.cypher +0 -5
  4. package/payload/platform/plugins/admin/mcp/dist/index.js +3 -4
  5. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  6. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +19 -22
  7. package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +38 -72
  8. package/payload/platform/plugins/cloudflare/.claude-plugin/plugin.json +1 -1
  9. package/payload/platform/plugins/cloudflare/PLUGIN.md +10 -7
  10. package/payload/platform/plugins/cloudflare/references/api.md +166 -0
  11. package/payload/platform/plugins/cloudflare/references/d1-data-capture.md +157 -0
  12. package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +6 -6
  13. package/payload/platform/plugins/cloudflare/references/hosting-sites.md +66 -0
  14. package/payload/platform/plugins/cloudflare/references/manual-setup.md +5 -3
  15. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +72 -0
  16. package/payload/platform/plugins/docs/references/cloudflare.md +4 -4
  17. package/payload/platform/plugins/docs/references/deployment.md +1 -1
  18. package/payload/platform/plugins/docs/references/internals.md +3 -6
  19. package/payload/platform/plugins/memory/PLUGIN.md +2 -2
  20. package/payload/platform/scripts/setup-account.sh +16 -8
  21. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  22. package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -32
  23. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  24. package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts +12 -0
  25. package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts.map +1 -1
  26. package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js +1 -1
  27. package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js.map +1 -1
  28. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +7 -33
  29. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  30. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +150 -132
  31. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  32. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +2 -1
  33. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +39 -6
  35. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  36. package/payload/platform/templates/agents/public/IDENTITY.md +9 -62
  37. package/payload/platform/templates/specialists/agents/personal-assistant.md +2 -2
  38. package/payload/server/{chunk-ZY6W3UA2.js → chunk-JMEX5NRX.js} +1 -22
  39. package/payload/server/maxy-edge.js +1 -1
  40. package/payload/server/server.js +7 -21
  41. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +0 -55
  42. package/payload/platform/templates/agents/public/SOUL.md +0 -19
  43. package/payload/platform/templates/agents/public/config.json +0 -9
@@ -3627,13 +3627,11 @@ function estimateTokens(text) {
3627
3627
  }
3628
3628
  function resolveAgentConfig(accountDir, agentName) {
3629
3629
  let model = null;
3630
- let plugins = null;
3631
3630
  let status = null;
3632
3631
  let displayName = null;
3633
3632
  let image = null;
3634
3633
  let imageShape = null;
3635
3634
  let showAgentName = false;
3636
- let liveMemory = false;
3637
3635
  let knowledgeKeywords = null;
3638
3636
  let accessMode = "open";
3639
3637
  const MAX_KNOWLEDGE_KEYWORDS = 5;
@@ -3647,7 +3645,6 @@ function resolveAgentConfig(accountDir, agentName) {
3647
3645
  parsed = {};
3648
3646
  }
3649
3647
  model = typeof parsed.model === "string" ? parsed.model : null;
3650
- plugins = Array.isArray(parsed.plugins) ? parsed.plugins : null;
3651
3648
  status = typeof parsed.status === "string" ? parsed.status : null;
3652
3649
  displayName = typeof parsed.displayName === "string" ? parsed.displayName : null;
3653
3650
  image = typeof parsed.image === "string" ? parsed.image : null;
@@ -3665,22 +3662,6 @@ function resolveAgentConfig(accountDir, agentName) {
3665
3662
  if (typeof parsed.accessMode === "string" && ["gated", "paid"].includes(parsed.accessMode)) {
3666
3663
  accessMode = parsed.accessMode;
3667
3664
  }
3668
- if (typeof parsed.liveMemory === "boolean") {
3669
- liveMemory = parsed.liveMemory;
3670
- } else if (typeof parsed.liveMemory === "string") {
3671
- const lower = parsed.liveMemory.toLowerCase();
3672
- if (lower === "true") {
3673
- liveMemory = true;
3674
- console.warn(`[agent-config] ${agentName}: liveMemory is string "true" \u2014 coercing to boolean. Fix the config to use a boolean value.`);
3675
- } else if (lower === "false") {
3676
- liveMemory = false;
3677
- console.warn(`[agent-config] ${agentName}: liveMemory is string "false" \u2014 coercing to boolean. Fix the config to use a boolean value.`);
3678
- } else {
3679
- throw new Error(`[agent-config] ${agentName}: liveMemory has invalid string value "${parsed.liveMemory}" \u2014 expected boolean or "true"/"false"`);
3680
- }
3681
- } else if (parsed.liveMemory !== void 0 && parsed.liveMemory !== null) {
3682
- throw new Error(`[agent-config] ${agentName}: liveMemory has invalid type ${typeof parsed.liveMemory} \u2014 expected boolean or "true"/"false"`);
3683
- }
3684
3665
  if (Array.isArray(parsed.knowledgeKeywords) && parsed.knowledgeKeywords.length > 0) {
3685
3666
  const filtered = parsed.knowledgeKeywords.filter((k) => typeof k === "string" && k.trim()).map((k) => k.replace(/,/g, "").trim().toLowerCase()).filter(Boolean);
3686
3667
  if (filtered.length > MAX_KNOWLEDGE_KEYWORDS) {
@@ -3725,7 +3706,7 @@ function resolveAgentConfig(accountDir, agentName) {
3725
3706
  total: identityTokens + soulTokens + knowledgeTokens
3726
3707
  };
3727
3708
  }
3728
- return { model, plugins, status, displayName, image, imageShape, showAgentName, knowledge, knowledgeBaked, liveMemory, knowledgeKeywords, budget, accessMode };
3709
+ return { model, status, displayName, image, imageShape, showAgentName, knowledge, knowledgeBaked, knowledgeKeywords, budget, accessMode };
3729
3710
  }
3730
3711
  function getDefaultAccountId() {
3731
3712
  return resolveAccount()?.accountId ?? null;
@@ -5347,7 +5328,6 @@ async function projectAgent(accountId, accountDir, slug) {
5347
5328
  SET a.displayName = $displayName,
5348
5329
  a.status = $status,
5349
5330
  a.model = $model,
5350
- a.liveMemory = $liveMemory,
5351
5331
  a.knowledgeKeywords = $knowledgeKeywords,
5352
5332
  a.role = 'agent',
5353
5333
  a.updatedAt = datetime()
@@ -5358,7 +5338,6 @@ async function projectAgent(accountId, accountDir, slug) {
5358
5338
  displayName: config.displayName ?? slug,
5359
5339
  status: config.status ?? "unknown",
5360
5340
  model: config.model ?? "",
5361
- liveMemory: config.liveMemory ?? false,
5362
5341
  knowledgeKeywords: config.knowledgeKeywords ?? []
5363
5342
  }
5364
5343
  );
@@ -14,7 +14,7 @@ import {
14
14
  sanitizeClientCorrId,
15
15
  vncLog,
16
16
  websockifyLog
17
- } from "./chunk-ZY6W3UA2.js";
17
+ } from "./chunk-JMEX5NRX.js";
18
18
  import "./chunk-PFF6I7KP.js";
19
19
 
20
20
  // server/edge.ts
@@ -91,7 +91,7 @@ import {
91
91
  vncLog,
92
92
  walkPremiumBundles,
93
93
  writeAdminUserAndPerson
94
- } from "./chunk-ZY6W3UA2.js";
94
+ } from "./chunk-JMEX5NRX.js";
95
95
  import {
96
96
  __commonJS,
97
97
  __toESM
@@ -4169,7 +4169,6 @@ async function managerSpawn(opts) {
4169
4169
  channel: opts.channel,
4170
4170
  accountId: opts.accountId,
4171
4171
  agentSlug: opts.agentSlug,
4172
- liveMemory: opts.liveMemory,
4173
4172
  attachmentDir: opts.attachmentDir,
4174
4173
  aboutOwner: opts.aboutOwner,
4175
4174
  dormantPlugins: opts.dormantPlugins,
@@ -4490,15 +4489,15 @@ function publicIdleMs() {
4490
4489
  return Number(process.env.CHANNEL_PTY_IDLE_MS ?? String(30 * 6e4));
4491
4490
  }
4492
4491
  var index = /* @__PURE__ */ new Map();
4493
- function indexKey(accountId, agentSlug, senderId, liveMemory, sliceToken = "") {
4492
+ function indexKey(accountId, agentSlug, senderId, sliceToken = "") {
4494
4493
  const slice = sliceToken && sliceToken.length > 0 ? sliceToken : "open";
4495
- return `${accountId}:${agentSlug}:${liveMemory ? "lm1" : "lm0"}:${slice}:${senderId}`;
4494
+ return `${accountId}:${agentSlug}:${slice}:${senderId}`;
4496
4495
  }
4497
4496
  async function ensureEntry(input) {
4498
4497
  startReaper();
4499
4498
  const sliceTokenValue = input.sliceToken ?? "";
4500
4499
  const personIdValue = input.personId ?? null;
4501
- const key = indexKey(input.accountId, input.agentSlug, input.senderId, input.liveMemory, sliceTokenValue);
4500
+ const key = indexKey(input.accountId, input.agentSlug, input.senderId, sliceTokenValue);
4502
4501
  const existing = index.get(key);
4503
4502
  const tag = tagFor(input.channel);
4504
4503
  if (existing) {
@@ -4521,7 +4520,6 @@ async function ensureEntry(input) {
4521
4520
  channel: input.channel,
4522
4521
  accountId: input.accountId,
4523
4522
  agentSlug: input.agentSlug,
4524
- liveMemory: input.liveMemory,
4525
4523
  attachmentDir,
4526
4524
  sliceToken: sliceTokenValue.length > 0 ? sliceTokenValue : void 0,
4527
4525
  personId: personIdValue ?? void 0
@@ -4547,7 +4545,6 @@ async function ensureEntry(input) {
4547
4545
  pendingTurnText: "",
4548
4546
  followerAbort: null,
4549
4547
  followerRunning: false,
4550
- liveMemory: input.liveMemory,
4551
4548
  sliceToken: sliceTokenValue,
4552
4549
  personId: personIdValue
4553
4550
  };
@@ -4586,14 +4583,13 @@ async function writeInput(entry, text) {
4586
4583
  dispatchFor: "exit"
4587
4584
  });
4588
4585
  }
4589
- index.delete(indexKey(entry.accountId, entry.agentSlug, entry.senderId, entry.liveMemory, entry.sliceToken));
4586
+ index.delete(indexKey(entry.accountId, entry.agentSlug, entry.senderId, entry.sliceToken));
4590
4587
  const respawned = await ensureEntry({
4591
4588
  accountId: entry.accountId,
4592
4589
  senderId: entry.senderId,
4593
4590
  role: entry.role,
4594
4591
  channel: entry.channel,
4595
4592
  agentSlug: entry.agentSlug,
4596
- liveMemory: entry.liveMemory,
4597
4593
  sliceToken: entry.sliceToken.length > 0 ? entry.sliceToken : void 0,
4598
4594
  personId: entry.personId
4599
4595
  });
@@ -4633,7 +4629,6 @@ async function dispatchOnce(input) {
4633
4629
  role: input.role,
4634
4630
  channel: input.channel,
4635
4631
  agentSlug: input.agentSlug,
4636
- liveMemory: input.liveMemory,
4637
4632
  sliceToken: input.sliceToken,
4638
4633
  personId: input.personId
4639
4634
  });
@@ -4835,11 +4830,10 @@ app2.post("/", async (c) => {
4835
4830
  }
4836
4831
  attachmentCount = stored.length;
4837
4832
  if (stored.length > 0) {
4838
- const lines = stored.map((s) => `- ${s.path} (${s.mime}, ${s.sizeBytes} bytes, original name: ${s.name})`).join("\n");
4833
+ const names = stored.map((s) => s.name).join(", ");
4839
4834
  uploadNote = `
4840
4835
 
4841
- [The user uploaded ${stored.length} file(s). Use the Read tool to view the contents:
4842
- ${lines}]`;
4836
+ [The user uploaded ${stored.length} file(s): ${names}. You cannot open uploaded files in this session \u2014 ask the visitor to describe or paste the relevant content.]`;
4843
4837
  }
4844
4838
  } else {
4845
4839
  requestFormat = "json";
@@ -4884,11 +4878,9 @@ ${lines}]`;
4884
4878
  if (!agentSlug) {
4885
4879
  return c.json({ error: "No default agent configured" }, 500);
4886
4880
  }
4887
- let liveMemory = false;
4888
4881
  let accessMode = "open";
4889
4882
  try {
4890
4883
  const config = resolveAgentConfig(account.accountDir, agentSlug);
4891
- liveMemory = config.liveMemory;
4892
4884
  accessMode = config.accessMode;
4893
4885
  } catch (err) {
4894
4886
  const m = err instanceof Error ? err.message : String(err);
@@ -4929,7 +4921,6 @@ ${lines}]`;
4929
4921
  role: "public",
4930
4922
  channel: "webchat",
4931
4923
  agentSlug,
4932
- liveMemory,
4933
4924
  sliceToken,
4934
4925
  personId,
4935
4926
  text: fullMessage,
@@ -14532,7 +14523,6 @@ async function dispatchToClaude(input) {
14532
14523
  role: input.role,
14533
14524
  channel: "whatsapp",
14534
14525
  agentSlug: input.agentSlug,
14535
- liveMemory: input.liveMemory,
14536
14526
  text: input.text,
14537
14527
  timeoutMs: whatsappTurnTimeoutMs()
14538
14528
  });
@@ -15657,10 +15647,8 @@ init({
15657
15647
  if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {
15658
15648
  try {
15659
15649
  let agentSlugForBridge;
15660
- let liveMemoryForBridge;
15661
15650
  if (msg.agentType === "admin") {
15662
15651
  agentSlugForBridge = "admin";
15663
- liveMemoryForBridge = true;
15664
15652
  } else {
15665
15653
  const resolved = bootAccount ? resolvePublicAgent(bootAccount.accountDir, { accountId: msg.accountId, groupJid: msg.groupJid }) : null;
15666
15654
  if (!resolved) {
@@ -15668,7 +15656,6 @@ init({
15668
15656
  return;
15669
15657
  }
15670
15658
  agentSlugForBridge = resolved.slug;
15671
- liveMemoryForBridge = bootAccount ? resolveAgentConfig(bootAccount.accountDir, resolved.slug).liveMemory : false;
15672
15659
  }
15673
15660
  startReaper2();
15674
15661
  await dispatchToClaude({
@@ -15676,7 +15663,6 @@ init({
15676
15663
  senderId: msg.senderPhone,
15677
15664
  role: msg.agentType,
15678
15665
  agentSlug: agentSlugForBridge,
15679
- liveMemory: liveMemoryForBridge,
15680
15666
  text: msg.text,
15681
15667
  reply: msg.reply
15682
15668
  });
@@ -1,55 +0,0 @@
1
- ---
2
- name: setup-tunnel
3
- description: Cloudflare Tunnel setup, diagnosis, and reset — the agent drives cloudflared directly via Bash, following the manual runbook step by step, and proves success with an external HTTP 200.
4
- ---
5
-
6
- # Cloudflare operations
7
-
8
- Every Cloudflare task — setup, diagnosis, reset, DNS edit — is driven by the agent invoking `cloudflared` directly via the Bash tool, following the numbered steps in `references/manual-setup.md`. There are no Cloudflare MCP tools; the plugin registers none. There is no shell-script wrapper, no state machine, no orchestrator. The PTY surface streams `cloudflared` stdout and stderr verbatim into chat, and the operator's own browser handles the OAuth click. The agent's job is to pick the right step from the runbook, collect the inputs it needs, run the command in Bash, relay the literal output, and verify the outcome with an external `curl`.
9
-
10
- ## Outcome contract — what "done" means
11
-
12
- A Cloudflare setup is done when, and only when, `curl -I https://<hostname>` issued from outside the local network returns `HTTP/2 200` (or `HTTP/1.1 200 OK`) and the response is surfaced verbatim in chat. No state file, no `result=ok` phase line, no "service is active" claim substitutes for the live HTTP response. If the curl returns anything other than 200, the setup is not done — diagnose with `cloudflared tunnel info <tunnelId>` and `systemctl --user status ${BRAND}-cloudflared.service` and recover per `references/manual-setup.md`.
13
-
14
- ## Inputs
15
-
16
- Four inputs come from the operator in chat: the admin FQDN, optional public FQDN, optional apex FQDN, and the admin password. `BRAND` is derived from disk — never hardcoded — with `BRAND=$(jq -r .hostname ~/.<configDir>/brand.json)`. The same install can host different brands on different ports; `brand.json.hostname` is the only authoritative source.
17
-
18
- ## Execution
19
-
20
- The agent reads `references/manual-setup.md` and executes its steps with Bash. Every `cloudflared` invocation's stdout and stderr are relayed into chat verbatim — the operator sees the same output the agent does. The OAuth URL printed by `cloudflared tunnel login` is linkified by the native PTY; the operator clicks it in their own browser. The agent does not spawn a browser, automate the Cloudflare consent page, or drive the dashboard via Playwright or Chrome DevTools.
21
-
22
- Mutations the agent performs from the runbook (each one only after reading the relevant step):
23
-
24
- - `cloudflared tunnel login` — emits the OAuth URL; cert lands at `~/.cloudflared/cert.pem` after the operator authorises.
25
- - `cloudflared tunnel --origincert <cert> create <name>` — produces `<tunnelId>.json` credentials.
26
- - Write `~/.${BRAND}/cloudflared/config.yml` (ingress block per the runbook).
27
- - `cloudflared tunnel --origincert <cert> route dns <tunnelId> <hostname>` — one call per non-apex hostname.
28
- - For non-admin hostnames not starting with `public.`, append to `~/.${BRAND}/alias-domains.json` so `isPublicHost()` treats them as public.
29
- - Install + start the `${BRAND}-cloudflared.service` user unit (`systemctl --user daemon-reload && systemctl --user enable --now ${BRAND}-cloudflared.service`).
30
-
31
- After the service is up, the agent runs `curl -I https://<admin-hostname>` and pastes the response. The setup-done claim only fires when a `200` line appears in that response.
32
-
33
- ## Apex hostnames
34
-
35
- The CLI cannot route apex records (e.g. `maxy.chat`). When an apex is supplied, the agent quotes the `ACTION REQUIRED` block from `references/manual-setup.md` verbatim — the operator edits the apex CNAME in the Cloudflare dashboard. The Cloudflare API and SDK are banned ([[feedback_cf_api_total_eradication]]); dashboard click is the only path.
36
-
37
- ## Reset
38
-
39
- When local Cloudflare state is corrupt or the operator wants to start from a known-good cert, follow `references/reset-guide.md`. The agent issues the relevant `cloudflared tunnel delete` and `rm -rf ~/.${BRAND}/cloudflared/` commands in Bash, then re-runs the setup steps above.
40
-
41
- ## Dashboard guidance
42
-
43
- For operations only the Cloudflare dashboard can do (sign in, switch accounts, add a site, edit an apex CNAME, verify zone nameservers, delete stale CNAMEs, create URL Rewrite Rules), quote the relevant click-path from `references/dashboard-guide.md` verbatim. The operator follows it in their browser. The agent does not drive the dashboard programmatically.
44
-
45
- ## Tool discipline — binding
46
-
47
- When the operator's request touches Cloudflare, the agent's permitted actions are:
48
-
49
- - Invoke `cloudflared` via Bash, following the numbered steps in `references/manual-setup.md`.
50
- - Write `config.yml` and `alias-domains.json` per the runbook.
51
- - Install and start the brand's cloudflared user service.
52
- - Quote `references/manual-setup.md`, `references/reset-guide.md`, or `references/dashboard-guide.md` verbatim when guidance is needed.
53
- - Verify reachability via `curl -I https://<hostname>` and surface the response.
54
-
55
- The agent does not call any Cloudflare API or SDK. The agent does not drive the dashboard via Playwright or Chrome DevTools. The agent does not synthesise `cloudflared` flag combinations from web search or training — every command comes from the runbook. When a step fails, the agent reports the exact `cloudflared` output, names the recovery step from `references/reset-guide.md`, and stops. Improvisation — "let me try a different flag" or "let me check the dashboard myself" — is the behaviour this rule exists to prevent.
@@ -1,19 +0,0 @@
1
- # Soul
2
-
3
- ## Personality
4
-
5
- Helpful, precise, warm without being effusive. Speaks for a real business to a real visitor. Not a marketing voice, not a chatbot, not a simulated friend. Treats the visitor's time as the most valuable thing in the conversation.
6
-
7
- Comfortable saying "I don't know" when the answer isn't in the knowledge provided. Honest about what is on offer and what isn't. Never invents detail to fill a gap.
8
-
9
- ## Tone
10
-
11
- Plain language. British English. Plain hyphens, straight quotes, three periods. No emoji. No filler ("just", "simply", "let me", "I'll check"). No narration of internal process ("searching", "looking that up").
12
-
13
- Short answers when the question is short. Longer answers when the visitor genuinely needs the detail: a comparison, a process, a decision. Never padded.
14
-
15
- Direct without being abrupt. The visitor asked for help; help them, and stop when help is delivered.
16
-
17
- ## Greeting
18
-
19
- Open by naming the business and what is on offer. Make it clear in the same breath that the visitor is talking to AI. Natural, not bolted on. Invite the question the visitor came to ask.
@@ -1,9 +0,0 @@
1
- {
2
- "slug": "public",
3
- "displayName": "Public Agent",
4
- "model": "claude-haiku-4-5",
5
- "plugins": ["sales"],
6
- "status": "active",
7
- "liveMemory": false,
8
- "knowledgeKeywords": []
9
- }