@rubytech/create-maxy-code 0.1.184 → 0.1.185
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/dist/__tests__/platform-port-stamp.test.js +4 -0
- package/dist/index.js +1 -0
- package/dist/port-resolution.js +1 -0
- package/package.json +1 -1
- package/payload/platform/config/brand.json +1 -1
- package/payload/platform/package-lock.json +178 -0
- package/payload/platform/plugins/.claude-plugin/marketplace.json +15 -0
- package/payload/platform/plugins/admin/PLUGIN.md +0 -1
- package/payload/platform/plugins/browser/.claude-plugin/plugin.json +17 -0
- package/payload/platform/plugins/browser/PLUGIN.md +44 -0
- package/payload/platform/plugins/browser/mcp/dist/index.d.ts +2 -0
- package/payload/platform/plugins/browser/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/browser/mcp/dist/index.js +61 -0
- package/payload/platform/plugins/browser/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/browser/mcp/dist/lib/cdp-render.d.ts +66 -0
- package/payload/platform/plugins/browser/mcp/dist/lib/cdp-render.d.ts.map +1 -0
- package/payload/platform/plugins/browser/mcp/dist/lib/cdp-render.js +248 -0
- package/payload/platform/plugins/browser/mcp/dist/lib/cdp-render.js.map +1 -0
- package/payload/platform/plugins/browser/mcp/package.json +19 -0
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +3 -0
- package/payload/platform/plugins/docs/references/troubleshooting.md +4 -4
- package/payload/platform/plugins/prompt-optimiser/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/prompt-optimiser/PLUGIN.md +14 -0
- package/payload/platform/plugins/prompt-optimiser/skills/prompt-optimiser/SKILL.md +301 -0
- package/payload/platform/plugins/url-get/.claude-plugin/plugin.json +17 -0
- package/payload/platform/plugins/url-get/PLUGIN.md +86 -0
- package/payload/platform/plugins/url-get/mcp/dist/index.d.ts +9 -0
- package/payload/platform/plugins/url-get/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/url-get/mcp/dist/index.js +53 -0
- package/payload/platform/plugins/url-get/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/url-get/mcp/dist/lib/summarise.d.ts +8 -0
- package/payload/platform/plugins/url-get/mcp/dist/lib/summarise.d.ts.map +1 -0
- package/payload/platform/plugins/url-get/mcp/dist/lib/summarise.js +83 -0
- package/payload/platform/plugins/url-get/mcp/dist/lib/summarise.js.map +1 -0
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts +21 -0
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.d.ts.map +1 -0
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js +147 -0
- package/payload/platform/plugins/url-get/mcp/dist/tools/url-get.js.map +1 -0
- package/payload/platform/plugins/url-get/mcp/package.json +22 -0
- package/payload/platform/scripts/setup-account.sh +0 -6
- package/payload/platform/scripts/vnc.sh +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +8 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +2 -2
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +3 -3
- package/payload/platform/templates/specialists/agents/librarian.md +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +3 -3
- package/payload/platform/templates/specialists/agents/research-assistant.md +3 -3
- package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/index.js +20 -6
- package/payload/premium-plugins/writer-craft/mcp/dist/index.js.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts +14 -0
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js +28 -34
- package/payload/premium-plugins/writer-craft/mcp/dist/tools/voice-retrieve-conditioning.js.map +1 -1
- package/payload/premium-plugins/writer-craft/mcp/scripts/smoke.mjs +43 -8
- package/payload/premium-plugins/writer-craft/mcp/src/index.ts +20 -8
- package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-retrieve-conditioning.ts +51 -12
- package/payload/premium-plugins/writer-craft/skills/voice-mirror/SKILL.md +7 -1
- package/payload/platform/plugins/admin/hooks/__tests__/playwright-file-guard.test.sh +0 -278
- package/payload/platform/plugins/admin/hooks/playwright-file-guard.sh +0 -214
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a JS-heavy page in the device's existing Chromium and return its DOM.
|
|
3
|
+
*
|
|
4
|
+
* The brand's VNC Chromium is launched by platform/scripts/vnc.sh with
|
|
5
|
+
* `--remote-debugging-port=${CDP_PORT}`, so CDP is already listening on
|
|
6
|
+
* 127.0.0.1:<port>. This module attaches to that running browser — it never
|
|
7
|
+
* launches its own — which is why no external browser package ships on device.
|
|
8
|
+
*
|
|
9
|
+
* Lifecycle (HTTP for target create/close, WebSocket for page control):
|
|
10
|
+
*
|
|
11
|
+
* PUT /json/new create a blank target, get its WS URL
|
|
12
|
+
* │
|
|
13
|
+
* ▼
|
|
14
|
+
* ws://…/devtools/page/<id> Page.enable → Page.navigate(url)
|
|
15
|
+
* │ await Page.loadEventFired (load-timeout)
|
|
16
|
+
* ▼
|
|
17
|
+
* Runtime.evaluate outerHTML + body.innerText (returnByValue)
|
|
18
|
+
* │
|
|
19
|
+
* ▼
|
|
20
|
+
* PUT /json/close/<id> always, even on the error paths above
|
|
21
|
+
*
|
|
22
|
+
* `fetch` and `WebSocket` are injected so the unit tests drive every branch
|
|
23
|
+
* without a real browser; production passes the Node 22 globals.
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_LOAD_TIMEOUT_MS = 30_000;
|
|
26
|
+
const DEFAULT_COMMAND_TIMEOUT_MS = 15_000;
|
|
27
|
+
/** Create a blank target via the CDP HTTP surface. Maps every transport
|
|
28
|
+
* failure to a structured outcome rather than throwing. */
|
|
29
|
+
async function createTarget(deps, timeoutMs) {
|
|
30
|
+
const endpoint = `http://${deps.cdpHost}:${deps.cdpPort}/json/new`;
|
|
31
|
+
let res;
|
|
32
|
+
try {
|
|
33
|
+
res = await deps.fetchImpl(endpoint, { method: "PUT", signal: AbortSignal.timeout(timeoutMs) });
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
37
|
+
if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("ENOTFOUND")) {
|
|
38
|
+
return { outcome: "cdp-unreachable", detail: msg };
|
|
39
|
+
}
|
|
40
|
+
return { outcome: "error", detail: msg };
|
|
41
|
+
}
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
const body = await res.text().catch(() => "<unreadable>");
|
|
44
|
+
return { outcome: "error", detail: `CDP /json/new returned ${res.status}: ${body.slice(0, 200)}` };
|
|
45
|
+
}
|
|
46
|
+
let parsed;
|
|
47
|
+
try {
|
|
48
|
+
parsed = (await res.json());
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return { outcome: "error", detail: `CDP /json/new response not JSON: ${err instanceof Error ? err.message : String(err)}` };
|
|
52
|
+
}
|
|
53
|
+
if (!parsed.id || !parsed.webSocketDebuggerUrl) {
|
|
54
|
+
return { outcome: "error", detail: `CDP /json/new missing id/webSocketDebuggerUrl: ${JSON.stringify(parsed).slice(0, 200)}` };
|
|
55
|
+
}
|
|
56
|
+
return { target: { id: parsed.id, webSocketDebuggerUrl: parsed.webSocketDebuggerUrl } };
|
|
57
|
+
}
|
|
58
|
+
/** Best-effort target close. Failure is logged, never surfaced as the render
|
|
59
|
+
* outcome — the DOM was already captured by the time this runs. */
|
|
60
|
+
async function closeTarget(deps, targetId) {
|
|
61
|
+
const endpoint = `http://${deps.cdpHost}:${deps.cdpPort}/json/close/${encodeURIComponent(targetId)}`;
|
|
62
|
+
try {
|
|
63
|
+
await deps.fetchImpl(endpoint, { method: "PUT", signal: AbortSignal.timeout(5_000) });
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
deps.log(`[browser-render] target-close-failed id=${targetId} err=${JSON.stringify(err instanceof Error ? err.message : String(err))}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Drives one CDP WebSocket session: correlates command ids to results and
|
|
70
|
+
* resolves a named event. Kept inside renderPage's closure scope so the
|
|
71
|
+
* socket, pending map, and event waiters share one lifetime. */
|
|
72
|
+
class CdpSession {
|
|
73
|
+
ws;
|
|
74
|
+
nextId = 1;
|
|
75
|
+
pending = new Map();
|
|
76
|
+
eventWaiters = new Map();
|
|
77
|
+
closed = false;
|
|
78
|
+
constructor(ws) {
|
|
79
|
+
this.ws = ws;
|
|
80
|
+
ws.addEventListener("message", (ev) => this.onMessage(ev.data));
|
|
81
|
+
ws.addEventListener("close", () => {
|
|
82
|
+
this.closed = true;
|
|
83
|
+
for (const { reject } of this.pending.values())
|
|
84
|
+
reject(new Error("websocket closed"));
|
|
85
|
+
this.pending.clear();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
onMessage(data) {
|
|
89
|
+
if (typeof data !== "string")
|
|
90
|
+
return;
|
|
91
|
+
let msg;
|
|
92
|
+
try {
|
|
93
|
+
msg = JSON.parse(data);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (typeof msg.id === "number") {
|
|
99
|
+
const waiter = this.pending.get(msg.id);
|
|
100
|
+
if (!waiter)
|
|
101
|
+
return;
|
|
102
|
+
this.pending.delete(msg.id);
|
|
103
|
+
if (msg.error)
|
|
104
|
+
waiter.reject(new Error(msg.error.message ?? "CDP command error"));
|
|
105
|
+
else
|
|
106
|
+
waiter.resolve(msg.result);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (msg.method) {
|
|
110
|
+
const waiter = this.eventWaiters.get(msg.method);
|
|
111
|
+
if (waiter) {
|
|
112
|
+
this.eventWaiters.delete(msg.method);
|
|
113
|
+
waiter(msg.params);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
command(method, params, timeoutMs) {
|
|
118
|
+
if (this.closed)
|
|
119
|
+
return Promise.reject(new Error("websocket closed"));
|
|
120
|
+
const id = this.nextId++;
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
const timer = setTimeout(() => {
|
|
123
|
+
this.pending.delete(id);
|
|
124
|
+
reject(new Error(`CDP ${method} timed out after ${timeoutMs}ms`));
|
|
125
|
+
}, timeoutMs);
|
|
126
|
+
this.pending.set(id, {
|
|
127
|
+
resolve: (v) => { clearTimeout(timer); resolve(v); },
|
|
128
|
+
reject: (e) => { clearTimeout(timer); reject(e); },
|
|
129
|
+
});
|
|
130
|
+
this.ws.send(JSON.stringify({ id, method, params }));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
waitForEvent(method, timeoutMs) {
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const timer = setTimeout(() => {
|
|
136
|
+
this.eventWaiters.delete(method);
|
|
137
|
+
reject(new Error(`event ${method} not received within ${timeoutMs}ms`));
|
|
138
|
+
}, timeoutMs);
|
|
139
|
+
this.eventWaiters.set(method, () => { clearTimeout(timer); resolve(); });
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function openSocket(WebSocketImpl, url, timeoutMs) {
|
|
144
|
+
return new Promise((resolve) => {
|
|
145
|
+
let settled = false;
|
|
146
|
+
let ws;
|
|
147
|
+
try {
|
|
148
|
+
ws = new WebSocketImpl(url);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
resolve({ error: err instanceof Error ? err.message : String(err) });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const timer = setTimeout(() => {
|
|
155
|
+
if (settled)
|
|
156
|
+
return;
|
|
157
|
+
settled = true;
|
|
158
|
+
try {
|
|
159
|
+
ws.close();
|
|
160
|
+
}
|
|
161
|
+
catch { /* ignore */ }
|
|
162
|
+
resolve({ error: `websocket open timed out after ${timeoutMs}ms` });
|
|
163
|
+
}, timeoutMs);
|
|
164
|
+
ws.addEventListener("open", () => {
|
|
165
|
+
if (settled)
|
|
166
|
+
return;
|
|
167
|
+
settled = true;
|
|
168
|
+
clearTimeout(timer);
|
|
169
|
+
resolve({ ws });
|
|
170
|
+
});
|
|
171
|
+
ws.addEventListener("error", (ev) => {
|
|
172
|
+
if (settled)
|
|
173
|
+
return;
|
|
174
|
+
settled = true;
|
|
175
|
+
clearTimeout(timer);
|
|
176
|
+
const detail = ev && typeof ev === "object" && "message" in ev ? String(ev.message) : "websocket error";
|
|
177
|
+
resolve({ error: detail });
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/** Render `url` in the device Chromium and return its rendered DOM text.
|
|
182
|
+
* Always returns a structured RenderResult — never throws, never returns a
|
|
183
|
+
* silent empty page. */
|
|
184
|
+
export async function renderPage(url, opts, deps) {
|
|
185
|
+
const loadTimeoutMs = opts.loadTimeoutMs ?? DEFAULT_LOAD_TIMEOUT_MS;
|
|
186
|
+
const commandTimeoutMs = opts.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
|
|
187
|
+
const fail = (outcome, detail) => {
|
|
188
|
+
deps.log(`[browser-render] url=${url} rendered=false outcome=${outcome} detail=${JSON.stringify(detail)}`);
|
|
189
|
+
return { url, rendered: false, outcome, domBytes: 0, text: "", html: "", detail };
|
|
190
|
+
};
|
|
191
|
+
if (!deps.WebSocketImpl) {
|
|
192
|
+
return fail("websocket-unavailable", "global WebSocket is not available on this runtime (Node < 22.4)");
|
|
193
|
+
}
|
|
194
|
+
if (!deps.cdpPort || Number.isNaN(deps.cdpPort)) {
|
|
195
|
+
return fail("cdp-unreachable", `CDP_PORT not set or invalid (got ${JSON.stringify(deps.cdpPort)})`);
|
|
196
|
+
}
|
|
197
|
+
const created = await createTarget(deps, commandTimeoutMs);
|
|
198
|
+
if ("outcome" in created)
|
|
199
|
+
return fail(created.outcome, created.detail);
|
|
200
|
+
const target = created.target;
|
|
201
|
+
const opened = await openSocket(deps.WebSocketImpl, target.webSocketDebuggerUrl, commandTimeoutMs);
|
|
202
|
+
if ("error" in opened) {
|
|
203
|
+
await closeTarget(deps, target.id);
|
|
204
|
+
return fail("cdp-unreachable", `websocket connect failed: ${opened.error}`);
|
|
205
|
+
}
|
|
206
|
+
const session = new CdpSession(opened.ws);
|
|
207
|
+
try {
|
|
208
|
+
await session.command("Page.enable", {}, commandTimeoutMs);
|
|
209
|
+
const loadPromise = session.waitForEvent("Page.loadEventFired", loadTimeoutMs);
|
|
210
|
+
try {
|
|
211
|
+
await session.command("Page.navigate", { url }, commandTimeoutMs);
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
await closeTarget(deps, target.id);
|
|
215
|
+
return fail("navigate-failed", err instanceof Error ? err.message : String(err));
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
await loadPromise;
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
await closeTarget(deps, target.id);
|
|
222
|
+
return fail("load-timeout", err instanceof Error ? err.message : String(err));
|
|
223
|
+
}
|
|
224
|
+
let html = "";
|
|
225
|
+
let text = "";
|
|
226
|
+
try {
|
|
227
|
+
const htmlRes = (await session.command("Runtime.evaluate", { expression: "document.documentElement.outerHTML", returnByValue: true }, commandTimeoutMs));
|
|
228
|
+
html = typeof htmlRes?.result?.value === "string" ? htmlRes.result.value : "";
|
|
229
|
+
const textRes = (await session.command("Runtime.evaluate", { expression: "document.body && document.body.innerText || ''", returnByValue: true }, commandTimeoutMs));
|
|
230
|
+
text = typeof textRes?.result?.value === "string" ? textRes.result.value : "";
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
await closeTarget(deps, target.id);
|
|
234
|
+
return fail("evaluate-failed", err instanceof Error ? err.message : String(err));
|
|
235
|
+
}
|
|
236
|
+
const domBytes = Buffer.byteLength(html, "utf8");
|
|
237
|
+
deps.log(`[browser-render] url=${url} rendered=true domBytes=${domBytes}`);
|
|
238
|
+
await closeTarget(deps, target.id);
|
|
239
|
+
return { url, rendered: true, outcome: "ok", domBytes, text, html };
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
try {
|
|
243
|
+
opened.ws.close();
|
|
244
|
+
}
|
|
245
|
+
catch { /* ignore */ }
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=cdp-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp-render.js","sourceRoot":"","sources":["../../src/lib/cdp-render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maxy/browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
13
|
+
"zod": "^3.24.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.7.0",
|
|
17
|
+
"@types/node": "^22.0.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -451,7 +451,7 @@ For subagents, the same spawn pushes `--add-dir` for every bundled plugin agents
|
|
|
451
451
|
|
|
452
452
|
A boot gate refuses to start the manager when any admin-allowlisted tool `mcp__<plugin>__*` lacks a registered server. The signal is `boot-failed reason=mcp-allowlist-without-server plugin=<p> tool=<t>` followed by `process.exit(1)`. The remediation is a one-line edit to the named `PLUGIN.md`: add the `mcp:` block. The complementary observability emit `mcp-config-allowlist-coverage admin-tools=A admin-registered=R` (where `A === R`) confirms the invariant per boot.
|
|
453
453
|
|
|
454
|
-
A second boot gate walks every specialist `.md` under `platform/templates/specialists/agents/`, every bundled `<plugin>/agents/` directory, and the per-account `<accountDir>/specialists/agents/` directory, parses each file's `tools:` frontmatter line, and classifies every tool name as one of: CC-native (Read, Bash, …), bridge-namespace (`
|
|
454
|
+
A second boot gate walks every specialist `.md` under `platform/templates/specialists/agents/`, every bundled `<plugin>/agents/` directory, and the per-account `<accountDir>/specialists/agents/` directory, parses each file's `tools:` frontmatter line, and classifies every tool name as one of: CC-native (Read, Bash, …), bridge-namespace (`mcp__plugin_*`, `mcp__graph__*`), a tool the loaded `PLUGIN.md` set actually serves, `unknown-tool-in-plugin` (namespace served but tool name absent), `unknown-plugin-namespace` (namespace served by nothing), `brand-excluded-plugin` (namespace served by nothing on this brand, **but** the brand's `brand.json#plugins.excluded` list names it), or `malformed-name` (not CC-native and not `mcp__<plugin>__<tool>`-shaped). The first three pass. The next two refuse boot with one `boot-failed reason=specialist-tool-drift specialist=<name> tool=<t> drift=<class> path=<…>` line per defect, then `process.exit(1)`. `brand-excluded-plugin` is a structural pass: it lands in a per-specialist strip-list, the manager continues to boot, and at spawn time `pty-spawner` removes those tool names from the `--agent <name>` spawn's `--allowed-tools` argv. The complementary observability emit `specialist-tool-strip specialist=<name> plugin=<p> tools=<csv> reason=brand-excluded` fires one line per stripped (specialist, plugin) pair so an operator who reads `server.log` sees the brand filter doing work without cross-referencing `brand.json` against the template. The startup-self-test line `startup-self-test specialist-tool-drift=ok inspected=<N> stripped-specialists=<M>` confirms the gate ran and how many specialists carry strip-lists.
|
|
455
455
|
|
|
456
456
|
This gate was Task 173. The `brand-excluded` branch closes the recurring crash-restart loop on brands that ship without a plugin the shared `personal-assistant.md` template references (e.g. `realagent-code` excludes `telegram` while the template hard-codes `mcp__telegram__*`). The brand-agnostic template stays a single file; the brand-aware filter expresses what the specialist *may* do on this install while the template expresses what it *can* do across brands. Tool typos and renamed plugins still refuse to boot — only namespaces explicitly named in `plugins.excluded` are demoted to strip-and-warn.
|
|
457
457
|
|
|
@@ -16,6 +16,7 @@ These are part of {{productName}}'s foundation and cannot be disabled:
|
|
|
16
16
|
|--------|-------------|
|
|
17
17
|
| `admin` | Platform management — system status, account settings, logs, session control. Also hosts the cross-cutting `plainly` skill: every text-producing agent (admin, public, every specialist) applies a plain-English precision pass to prose returned to humans, as a prime-directive prerogative. Agent-to-machine payloads (image-generate prompts, memory-write arguments, cypher) pass through verbatim. Enforced mechanically by `.claude/hooks/precision-check.sh`. |
|
|
18
18
|
| `memory` | Graph memory — search, write, reindex, and ingest knowledge |
|
|
19
|
+
| `browser` | Headless browser rendering — `browser-render` runs a JavaScript-heavy page in the device's Chromium and returns its rendered DOM. The JS-rendering leg of retrieval: WebFetch (summary) / `url-get` (verbatim, server-rendered) / `browser-render` (JS-rendered). |
|
|
19
20
|
| `maxy-guide` | User guide and platform documentation (this plugin) |
|
|
20
21
|
| `cloudflare` | Cloudflare Tunnel — remote access via your custom domain |
|
|
21
22
|
| `scheduling` | Calendar and scheduling — events, appointments, recurring triggers. Any activity involving time (date, timestamp, day of week, month, duration) routes through `time-resolve` first. Two read-only tools (`current-datetime`, `time-resolve`) are always available to every public agent regardless of enabled plugins. |
|
|
@@ -23,6 +24,8 @@ These are part of {{productName}}'s foundation and cannot be disabled:
|
|
|
23
24
|
| `tasks` | Task lifecycle — create, update, list, relate, complete |
|
|
24
25
|
| `workflows` | Persistent named workflows — reusable instruction sets |
|
|
25
26
|
| `contacts` | CRM contact management — create, lookup, update, list |
|
|
27
|
+
| `prompt-optimiser` | Prompt optimiser — turns a rough draft or task description into a single finished, copy-pasteable prompt tuned for Opus 4.7 adaptive thinking in the chat app (claude.ai, Mac, iOS) |
|
|
28
|
+
| `url-get` | Faithful page retrieval — fetches a server-rendered page, writes a verbatim markdown copy to an account-scoped reference file (no model in the path, so no copyright refusal), and returns a transformative summary plus the file path. Use instead of WebFetch when a faithful copy is needed (e.g. ingesting your own published writing). |
|
|
26
29
|
|
|
27
30
|
### {{productName}} Plugins (user-selectable)
|
|
28
31
|
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
**Diagnose if it ever recurs:** run `bash platform/scripts/__tests__/first-token-creates-stream-log.test.sh` from the install. Pass = invariant holds; any other exit = the writer-side existence contract is broken and one `[log-tee] missing-on-resolve sessionKey=<8> surface=<…>` line on `server.log` is the operator-visible signal (P0). For the duplicate-file class specifically (the 2026-05-14 recurrence trigger), `bash platform/scripts/log-adherence-check.sh` returns non-zero whenever any sessionKey has more than one `claude-agent-stream-<sk>.log` across account dirs.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## A JavaScript-rendered page comes back empty from WebFetch or `url-get`
|
|
12
12
|
|
|
13
|
-
**Symptom:**
|
|
13
|
+
**Symptom:** A page that needs JavaScript to show its content returns empty or a shell document from `WebFetch` (summary) or `url-get` (verbatim, server-rendered).
|
|
14
14
|
|
|
15
|
-
**Resolution
|
|
15
|
+
**Resolution:** Use the `browser` core plugin's `browser-render` tool. It renders the page in the device's per-brand Chromium over the Chrome DevTools Protocol (the same browser the VNC viewer shows) and returns the rendered HTML plus visible text. It attaches to the already-running Chromium on `127.0.0.1:${CDP_PORT}` — nothing is downloaded or installed mid-session.
|
|
16
16
|
|
|
17
|
-
**Diagnose if it ever recurs:** grep the per-conversation stream log for `[
|
|
17
|
+
**Diagnose if it ever recurs:** grep the per-conversation stream log for `[browser-render]`. `rendered=true domBytes=<n>` is the healthy signal. `rendered=false outcome=cdp-unreachable` means no Chromium is listening on the brand's CDP port — confirm with `curl 127.0.0.1:<cdpPort>/json/version`. Other outcomes (`navigate-failed`, `load-timeout`, `evaluate-failed`) name the failed CDP step.
|
|
18
18
|
|
|
19
19
|
## First user-domain write rejected by `[graph-write-gate] reject reason=no-admin-user`
|
|
20
20
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "prompt-optimiser",
|
|
3
|
+
"description": "Prompt optimiser. Turns a rough draft, vague idea, or task description into a single finished, copy-pasteable prompt tuned for Opus 4.7 adaptive thinking in the chat app (claude.ai, Mac, iOS) — no placeholders, content baked in when supplied or a self-contained ask when not, ending with the literal `Think before answering` closing line. Triggers on requests to write, rewrite, optimise, sharpen, or polish a prompt. Ships one skill: prompt-optimiser.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Rubytech LLC"
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prompt-optimiser
|
|
3
|
+
surface: platform
|
|
4
|
+
description: "Prompt optimiser. Turns a rough draft, vague idea, or task description into a single finished, copy-pasteable prompt tuned for Opus 4.7 adaptive thinking in the chat app (claude.ai, Mac, iOS) — no placeholders, content baked in when supplied or a self-contained ask when not, ending with the literal `Think before answering` closing line. Triggers on requests to write, rewrite, optimise, sharpen, or polish a prompt. Ships one skill: prompt-optimiser."
|
|
5
|
+
skills:
|
|
6
|
+
- skills/prompt-optimiser/SKILL.md
|
|
7
|
+
metadata: {"platform":{"always":true,"embed":["admin"],"pluginKey":"prompt-optimiser"}}
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Prompt Optimiser
|
|
11
|
+
|
|
12
|
+
Core skill plugin. Provides the `prompt-optimiser` skill: given any rough prompt, half-formed idea, or task description, it returns a single high-quality prompt designed to run inside the chat app on Opus 4.7 with adaptive thinking — not the API.
|
|
13
|
+
|
|
14
|
+
The output is always one fenced code block, final and free of template placeholders: content is baked in when the operator supplied it, or the prompt is written self-contained with an explicit "ask me for X" close when only a task class was described. Every produced prompt ends with the literal closing line that nudges Opus 4.7 toward maximum reasoning.
|