@rubytech/create-realagent 1.0.869 → 1.0.871

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 (35) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/mcp/dist/__tests__/public-hostname.test.js +83 -91
  3. package/payload/platform/plugins/admin/mcp/dist/__tests__/public-hostname.test.js.map +1 -1
  4. package/payload/platform/plugins/admin/mcp/dist/index.js +7 -10
  5. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  6. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.d.ts +5 -11
  7. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.d.ts.map +1 -1
  8. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.js +66 -47
  9. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.js.map +1 -1
  10. package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +2 -2
  11. package/payload/platform/plugins/docs/references/internals.md +1 -1
  12. package/payload/platform/scripts/__tests__/admin-persist-audit.test.ts +182 -0
  13. package/payload/platform/scripts/admin-persist-audit.ts +43 -17
  14. package/payload/server/chunk-5U36PKG4.js +11326 -0
  15. package/payload/server/chunk-NDEQBCVI.js +1160 -0
  16. package/payload/server/client-pool-XAEDMS5D.js +34 -0
  17. package/payload/server/maxy-edge.js +2 -2
  18. package/payload/server/public/assets/{Checkbox-B9hff9s8.js → Checkbox-CDffo5el.js} +1 -1
  19. package/payload/server/public/assets/{admin-Cpi6L_g7.js → admin-BSdV45P5.js} +2 -2
  20. package/payload/server/public/assets/data-vFVtOwuC.js +1 -0
  21. package/payload/server/public/assets/{graph-labels-ChinGFwI.js → graph-labels-C-KsUF_B.js} +1 -1
  22. package/payload/server/public/assets/graph-q802cxLY.js +1 -0
  23. package/payload/server/public/assets/{jsx-runtime-CVA1ZrPS.css → jsx-runtime-C1hGBzVx.css} +1 -1
  24. package/payload/server/public/assets/{page-OVrxtgOZ.js → page-B5b7tyz-.js} +1 -1
  25. package/payload/server/public/assets/{page-DqPf65sS.js → page-DsW7P98i.js} +1 -1
  26. package/payload/server/public/assets/{public-CJN5KAiK.js → public-BkNXx-3G.js} +1 -1
  27. package/payload/server/public/assets/{useVoiceRecorder-DyVx7e7a.js → useVoiceRecorder-DCVSlfUk.js} +1 -1
  28. package/payload/server/public/data.html +5 -5
  29. package/payload/server/public/graph.html +6 -6
  30. package/payload/server/public/index.html +8 -8
  31. package/payload/server/public/public.html +5 -5
  32. package/payload/server/server.js +38 -18
  33. package/payload/server/public/assets/data-Da6iYRW1.js +0 -1
  34. package/payload/server/public/assets/graph-BHq-JYwV.js +0 -1
  35. /package/payload/server/public/assets/{jsx-runtime-nxP_2eNo.js → jsx-runtime-DFrHsKhm.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent",
3
- "version": "1.0.869",
3
+ "version": "1.0.871",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent": "./dist/index.js"
@@ -1,106 +1,98 @@
1
- // Task 970public-hostname deterministic resolver.
2
- //
3
- // Locks in the contract for `resolvePublicHostname` (the helper backing the
4
- // new `public-hostname` MCP tool). The tool exists so an agent following
5
- // publish-site never has to guess the property name on `CloudflareHostname`
6
- // nodes (the Task 970 root cause: `RETURN h.hostname` instead of
7
- // `h.hostnameValue`, returning `[]` and exhausting the turn budget).
8
- //
9
- // Tests stub a session-shaped object and assert exact cypher text, params,
10
- // and return shape — no driver, no neo4j-driver dependency at test time.
11
- import { describe, it, expect, vi } from "vitest";
12
- import { resolvePublicHostname, } from "../lib/public-hostname.js";
13
- function assertMiss(r) {
14
- if (r.hostname !== null)
15
- throw new Error("expected miss, got hit");
1
+ // Task 971filesystem-only resolver tests (4th recurrence of
2
+ // llm-framing-deterministic). Each test seeds a temp configDir on disk and
3
+ // asserts the chosen hostname, source, and isApex flag — no driver, no graph.
4
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
5
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
8
+ import { resolvePublicHostname } from "../lib/public-hostname.js";
9
+ function writeConfigYml(configDir, body) {
10
+ mkdirSync(join(configDir, "cloudflared"), { recursive: true });
11
+ writeFileSync(join(configDir, "cloudflared", "config.yml"), body);
16
12
  }
17
- function record(fields) {
18
- return { get: (k) => fields[k] };
19
- }
20
- function mockSession(results) {
21
- let i = 0;
22
- const run = vi.fn((_cypher, _params) => {
23
- if (i >= results.length)
24
- throw new Error(`unexpected session.run call #${i + 1}`);
25
- return Promise.resolve(results[i++]);
26
- });
27
- const close = vi.fn(() => Promise.resolve());
28
- return { run, close };
13
+ function writeAliasDomains(configDir, list) {
14
+ writeFileSync(join(configDir, "alias-domains.json"), JSON.stringify(list));
29
15
  }
30
16
  describe("resolvePublicHostname", () => {
31
- it("returns hostname/isApex/tunnelId on hit, after one cypher call against CloudflareHostname", async () => {
32
- const session = mockSession([
33
- {
34
- records: [
35
- record({ hostname: "test.maxy.bot", isApex: false, tunnelId: "tun-abc" }),
36
- ],
37
- },
38
- ]);
39
- const r = await resolvePublicHostname(session, "acc-1");
40
- expect(r).toEqual({
41
- hostname: "test.maxy.bot",
42
- isApex: false,
43
- tunnelId: "tun-abc",
17
+ let configDir;
18
+ beforeEach(() => {
19
+ configDir = mkdtempSync(join(tmpdir(), "public-hostname-test-"));
20
+ });
21
+ afterEach(() => {
22
+ rmSync(configDir, { recursive: true, force: true });
23
+ });
24
+ it("returns the single ingress hostname from cloudflared/config.yml", () => {
25
+ writeConfigYml(configDir, [
26
+ "tunnel: abc-123",
27
+ "ingress:",
28
+ " - hostname: realagent.app",
29
+ " service: http://localhost:3000",
30
+ " - service: http_status:404",
31
+ "",
32
+ ].join("\n"));
33
+ expect(resolvePublicHostname(configDir)).toEqual({
34
+ hostname: "realagent.app",
35
+ isApex: true,
36
+ source: "cloudflared-config.yml",
44
37
  });
45
- expect(session.run).toHaveBeenCalledTimes(1);
46
- const [cypher, params] = session.run.mock.calls[0];
47
- expect(cypher).toContain("CloudflareHostname");
48
- expect(cypher).toContain("h.hostnameValue");
49
- expect(cypher).toContain("h.isApex");
50
- expect(cypher).toContain("h.tunnelId");
51
- expect(cypher).toContain("ORDER BY h.isApex DESC");
52
- expect(cypher).toContain("LIMIT 1");
53
- expect(params).toEqual({ accountId: "acc-1" });
54
38
  });
55
- it("returns reason=no-hostname when hostname missing but a tunnel exists", async () => {
56
- const session = mockSession([
57
- { records: [] },
58
- { records: [record({ n: 1 })] },
59
- ]);
60
- const r = await resolvePublicHostname(session, "acc-1");
39
+ it("prefers apex over subdomain when both appear in config.yml", () => {
40
+ writeConfigYml(configDir, [
41
+ "ingress:",
42
+ " - hostname: public.realagent.app",
43
+ " service: http://localhost:3000",
44
+ " - hostname: realagent.app",
45
+ " service: http://localhost:3000",
46
+ "",
47
+ ].join("\n"));
48
+ const r = resolvePublicHostname(configDir);
61
49
  expect(r).toEqual({
62
- hostname: null,
63
- isApex: null,
64
- tunnelId: null,
65
- reason: "no-hostname",
50
+ hostname: "realagent.app",
51
+ isApex: true,
52
+ source: "cloudflared-config.yml",
66
53
  });
67
- expect(session.run).toHaveBeenCalledTimes(2);
68
- const [tunnelCypher] = session.run.mock.calls[1];
69
- expect(tunnelCypher).toContain("CloudflareTunnel");
70
54
  });
71
- it("returns reason=no-tunnel when neither hostname nor tunnel exists", async () => {
72
- const session = mockSession([
73
- { records: [] },
74
- { records: [record({ n: 0 })] },
75
- ]);
76
- const r = await resolvePublicHostname(session, "acc-1");
77
- expect(r).toEqual({
55
+ it("filters localhost and *.local entries from config.yml ingress", () => {
56
+ writeConfigYml(configDir, [
57
+ "ingress:",
58
+ " - hostname: localhost",
59
+ " service: http://127.0.0.1:7474",
60
+ " - hostname: maxy.local",
61
+ " service: http://127.0.0.1:7475",
62
+ " - hostname: realagent.app",
63
+ " service: http://localhost:3000",
64
+ "",
65
+ ].join("\n"));
66
+ expect(resolvePublicHostname(configDir).hostname).toBe("realagent.app");
67
+ });
68
+ it("treats www.<apex> as apex via prefix-strip tiebreak", () => {
69
+ writeConfigYml(configDir, [
70
+ "ingress:",
71
+ " - hostname: foo.realagent.app",
72
+ " service: http://localhost:3000",
73
+ " - hostname: www.realagent.app",
74
+ " service: http://localhost:3000",
75
+ "",
76
+ ].join("\n"));
77
+ const r = resolvePublicHostname(configDir);
78
+ expect(r.hostname).toBe("www.realagent.app");
79
+ expect(r.isApex).toBe(true);
80
+ });
81
+ it("falls back to alias-domains.json when config.yml is absent", () => {
82
+ writeAliasDomains(configDir, ["realagent.app"]);
83
+ expect(resolvePublicHostname(configDir)).toEqual({
84
+ hostname: "realagent.app",
85
+ isApex: true,
86
+ source: "alias-domains.json",
87
+ });
88
+ });
89
+ it("returns reason=no-tunnel when neither file is populated", () => {
90
+ expect(resolvePublicHostname(configDir)).toEqual({
78
91
  hostname: null,
79
92
  isApex: null,
80
- tunnelId: null,
93
+ source: null,
81
94
  reason: "no-tunnel",
82
95
  });
83
96
  });
84
- it("handles Neo4j Integer return for the tunnel count", async () => {
85
- // neo4j-driver returns count() as an Integer object with low/high fields
86
- // and a toNumber() method. The resolver must unwrap it.
87
- const integerLike = { low: 3, high: 0, toNumber: () => 3 };
88
- const session = mockSession([
89
- { records: [] },
90
- { records: [record({ n: integerLike })] },
91
- ]);
92
- const r = await resolvePublicHostname(session, "acc-1");
93
- assertMiss(r);
94
- expect(r.reason).toBe("no-hostname");
95
- });
96
- it("scopes the query to accountId — no cross-account leakage", async () => {
97
- const session = mockSession([
98
- { records: [] },
99
- { records: [record({ n: 0 })] },
100
- ]);
101
- await resolvePublicHostname(session, "acc-X");
102
- expect(session.run.mock.calls[0][1]).toEqual({ accountId: "acc-X" });
103
- expect(session.run.mock.calls[1][1]).toEqual({ accountId: "acc-X" });
104
- });
105
97
  });
106
98
  //# sourceMappingURL=public-hostname.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-hostname.test.js","sourceRoot":"","sources":["../../src/__tests__/public-hostname.test.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,iEAAiE;AACjE,qEAAqE;AACrE,EAAE;AACF,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EACL,qBAAqB,GAGtB,MAAM,2BAA2B,CAAC;AAEnC,SAAS,UAAU,CAAC,CAAuB;IACzC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,MAAM,CAAC,MAA+B;IAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,OAAmE;IACtF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,OAAe,EAAE,OAAgC,EAAE,EAAE;QACtE,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AACxB,CAAC;AAED,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;QACzG,MAAM,OAAO,GAAG,WAAW,CAAC;YAC1B;gBACE,OAAO,EAAE;oBACP,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;iBAC1E;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAChB,QAAQ,EAAE,eAAe;YACzB,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,OAAO,GAAG,WAAW,CAAC;YAC1B,EAAE,OAAO,EAAE,EAAE,EAAE;YACf,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAChB,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,aAAa;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,OAAO,GAAG,WAAW,CAAC;YAC1B,EAAE,OAAO,EAAE,EAAE,EAAE;YACf,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAChB,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,yEAAyE;QACzE,wDAAwD;QACxD,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,WAAW,CAAC;YAC1B,EAAE,OAAO,EAAE,EAAE,EAAE;YACf,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE;SAC1C,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,UAAU,CAAC,CAAC,CAAC,CAAC;QACd,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,OAAO,GAAG,WAAW,CAAC;YAC1B,EAAE,OAAO,EAAE,EAAE,EAAE;YACf,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"public-hostname.test.js","sourceRoot":"","sources":["../../src/__tests__/public-hostname.test.ts"],"names":[],"mappings":"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"}
@@ -403,27 +403,24 @@ server.tool("system-status", "Check health of all Maxy platform services: Neo4j,
403
403
  .join("\n");
404
404
  return { content: [{ type: "text", text: formatted }] };
405
405
  });
406
- server.tool("public-hostname", "Resolve this account's canonical public hostname from the CloudflareHostname graph. Returns a single deterministic answer; never guess the property name on hostname nodes (Task 970 — the third recurrence of `RETURN h.hostname` instead of `h.hostnameValue` exhausting the agent's turn budget). Use this immediately after publish-site to construct the full URL.", {}, async () => {
406
+ server.tool("public-hostname", "Resolve this account's canonical public hostname. Reads cloudflared ingress + alias-domains.json the same files the platform server trusts to route. Returns a single deterministic answer; use this immediately after publish-site to construct the full URL.", {}, async () => {
407
407
  const TAG = "[admin:public-hostname]";
408
- const session = getSession();
409
408
  try {
410
- const result = await resolvePublicHostname(session, ACCOUNT_ID);
409
+ const result = resolvePublicHostname(CONFIG_DIR);
411
410
  if (result.hostname !== null) {
412
- console.error(`${TAG} resolved accountId=${ACCOUNT_ID} hostname=${result.hostname} isApex=${result.isApex}`);
411
+ console.error(`${TAG} resolved accountId=${ACCOUNT_ID} hostname=${result.hostname} source=${result.source}`);
413
412
  const body = `hostname: ${result.hostname}\n` +
414
413
  `isApex: ${result.isApex}\n` +
415
- `tunnelId: ${result.tunnelId}\n` +
414
+ `source: ${result.source}\n` +
416
415
  `usage: paste \`https://${result.hostname}<path-slug>\` to the operator — the <path-slug> comes from publish-site.`;
417
416
  return { content: [{ type: "text", text: body }] };
418
417
  }
419
- console.error(`${TAG} empty accountId=${ACCOUNT_ID} reason=${result.reason}`);
420
- const remediation = result.reason === "no-tunnel"
421
- ? "No Cloudflare tunnel is configured for this account. Run the cloudflare setup-tunnel skill before publishing externally."
422
- : "A Cloudflare tunnel exists but no public hostname is bound to it. Run the cloudflare setup-hostname skill before publishing externally.";
418
+ console.error(`${TAG} empty accountId=${ACCOUNT_ID} reason=${result.reason} files-checked=cloudflared-config.yml,alias-domains.json`);
423
419
  return {
424
420
  content: [{
425
421
  type: "text",
426
- text: `hostname: (none)\nreason: ${result.reason}\n${remediation}`,
422
+ text: `hostname: (none)\nreason: ${result.reason}\n` +
423
+ `No Cloudflare tunnel is configured for this account. Run the cloudflare setup-tunnel skill before publishing externally.`,
427
424
  }],
428
425
  };
429
426
  }