@rubytech/create-maxy 1.0.461 → 1.0.463

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/index.js CHANGED
@@ -567,6 +567,10 @@ function deployPayload() {
567
567
  cpSync(liveAccountsDir, persistentAccountsDir, { recursive: true, force: true });
568
568
  console.log(" Backed up account data.");
569
569
  }
570
+ // Stop the running service before wiping directories (upgrade path).
571
+ // The server holds open files in platform/ — rmSync fails with ENOTEMPTY if it's running.
572
+ const svcName = BRAND.serviceName.replace(".service", "");
573
+ spawnSync("systemctl", ["--user", "stop", svcName], { stdio: "pipe" });
570
574
  // Wipe old platform/maxy/premium-plugins to prevent stale files
571
575
  // The UI server directory in the payload is always named "maxy" regardless of brand
572
576
  for (const dir of ["platform", "maxy", "premium-plugins", "docs", ".claude"]) {
@@ -598,9 +602,6 @@ function deployPayload() {
598
602
  }
599
603
  function buildPlatform() {
600
604
  log("8", TOTAL, "Installing dependencies and building...");
601
- // Stop the running service before rebuilding (upgrade path)
602
- const svcName = BRAND.serviceName.replace(".service", "");
603
- spawnSync("systemctl", ["--user", "stop", svcName], { stdio: "pipe" });
604
605
  console.log(` Installing platform dependencies (${join(INSTALL_DIR, "platform")})...`);
605
606
  shellRetry("npm", ["install", ...NPM_NET_FLAGS], { cwd: join(INSTALL_DIR, "platform") }, 3, 15);
606
607
  // MCP server dist/ files are pre-compiled in the payload — no build step needed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.461",
3
+ "version": "1.0.463",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -5102,7 +5102,7 @@ function getMcpServers(accountId, enabledPlugins) {
5102
5102
  // the always-on Chromium instance started by vnc.sh on display :99.
5103
5103
  "plugin_playwright_playwright": {
5104
5104
  command: "npx",
5105
- args: ["-y", "@playwright/mcp@latest", "--cdp-endpoint", "http://127.0.0.1:9222"]
5105
+ args: ["-y", "@playwright/mcp@latest", "--cdp-endpoint", "http://127.0.0.1:9222", "--caps", "pdf"]
5106
5106
  }
5107
5107
  };
5108
5108
  if (process.env.TELEGRAM_PUBLIC_BOT_TOKEN) {
@@ -41,6 +41,7 @@ Tools are available via the `admin` MCP server.
41
41
  | Manage access grants | Admin asks to invite visitors, revoke or extend access, list who has access, or set an agent's access mode | `skills/access-manager/SKILL.md` |
42
42
  | Manage plugins and settings | User asks to install, enable, disable, or configure plugins, or change account settings | `skills/plugin-management/skill.md` |
43
43
  | Manage specialists | User asks to install or remove a specialist subagent, or activate/deactivate premium plugin agents | `skills/specialist-management/skill.md` |
44
+ | Generate print-quality PDF | User asks to create a PDF document, one-pager, brochure, or any HTML intended for print/download | `skills/a4-print-documents/SKILL.md` |
44
45
 
45
46
  ## Hooks
46
47
 
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: a4-print-documents
3
+ description: >
4
+ Constraints for producing print-quality A4 HTML documents intended for PDF output
5
+ via browser_pdf_save. Use when creating or modifying any HTML document that will be
6
+ saved as PDF, uses A4 page dimensions, or contains glassmorphism/backdrop-filter effects
7
+ that must survive print. Trigger phrases: "PDF", "print to PDF", "download PDF",
8
+ "one-pager", "A4", "brochure", "executive document", "market analysis", or any request
9
+ to generate a document for print or download.
10
+ ---
11
+
12
+ # A4 Print-Ready HTML Documents
13
+
14
+ Constraints for producing HTML documents that render correctly when saved as PDF via the browser-specialist's `browser_pdf_save` tool. Every rule exists because violating it caused a visible problem in production documents.
15
+
16
+ ## Rendering path
17
+
18
+ Generate the HTML document, then delegate to the browser-specialist to save it as PDF using `browser_pdf_save`. The browser-specialist controls Playwright — you compose the delegation brief describing what to render and any pre-render steps (like glassmorphism screenshot capture).
19
+
20
+ ## Glassmorphism does not survive print
21
+
22
+ `backdrop-filter: blur()`, CSS glassmorphism, and layered transparency effects render as flat, transparent boxes in browser print/PDF output. This is a browser limitation, not a CSS error.
23
+
24
+ **Required pattern:** Every section using glassmorphism needs a pre-rendered PNG fallback that is hidden on screen and shown only in print.
25
+
26
+ ```css
27
+ .cover-print-img { display: none; }
28
+
29
+ @media print {
30
+ .cover > *:not(.cover-print-img) { display: none !important; }
31
+ .cover-print-img {
32
+ display: block !important;
33
+ position: absolute;
34
+ inset: 0;
35
+ width: 100%;
36
+ height: 100%;
37
+ object-fit: cover;
38
+ }
39
+ }
40
+ ```
41
+
42
+ ```html
43
+ <div class="cover">
44
+ <img class="cover-print-img" src="cover-print.png" alt="">
45
+ <!-- live glassmorphism content follows -->
46
+ </div>
47
+ ```
48
+
49
+ This pattern applies to every full-bleed glassmorphism section (cover pages, back pages).
50
+
51
+ ### Capturing the print image
52
+
53
+ Each glassmorphism section needs its own screenshot — you cannot reuse a print image from a different document or a differently-sized section.
54
+
55
+ Delegate to the browser-specialist with a brief that includes:
56
+
57
+ 1. **Serve the HTML over HTTP** — `file://` protocol is blocked by Playwright. The specialist should start a local server.
58
+ 2. **Set the viewport** to match the element's rendered size. Measure the element's bounding box first, then resize the viewport to `Math.ceil(width) + 1` by `Math.ceil(height) + 1` to eliminate scrollbars.
59
+ 3. **Hide UI chrome** (download buttons, navigation overlays) and set `document.body.style.overflow = 'hidden'` to suppress body-level scrollbars.
60
+ 4. **Screenshot the specific element** (e.g. `.cover`, `.backpage`) using element-level screenshot — not a full-page or viewport screenshot.
61
+ 5. **Save the PNG** alongside the HTML, named for the section it replaces (e.g. `cover-print.png`, `backpage-print.png`).
62
+ 6. **Restore** hidden elements and overflow after capture.
63
+ 7. **Verify** the saved PNG visually — confirm no scrollbars, no UI chrome, correct dimensions.
64
+
65
+ After capturing all print images, delegate a second task to save the final PDF via `browser_pdf_save`.
66
+
67
+ ## Page margins, page numbers, and running footers
68
+
69
+ Use `@page` margin boxes for page numbers and running footers — not `position: fixed` elements.
70
+
71
+ ```css
72
+ @page {
73
+ margin: 0.6in 0.7in 0.8in;
74
+ @bottom-center {
75
+ content: counter(page);
76
+ font-family: 'Playfair Display', Georgia, serif;
77
+ font-size: 9pt;
78
+ color: #8A8A84;
79
+ }
80
+ }
81
+
82
+ /* Cover page: zero margins, no page number */
83
+ @page :first {
84
+ margin: 0;
85
+ @bottom-center { content: none; }
86
+ }
87
+
88
+ /* Named page for full-bleed back page */
89
+ @page backpage-full {
90
+ margin: 0;
91
+ @bottom-center { content: none; }
92
+ }
93
+ ```
94
+
95
+ Then in `@media print`, the cover needs NO `page:` property — `@page :first` handles it. Only the backpage needs the named page assignment:
96
+
97
+ ```css
98
+ @media print {
99
+ .cover {
100
+ width: auto; margin: 0; box-shadow: none; /* reset screen-only properties */
101
+ min-height: 0;
102
+ height: 100vh;
103
+ page-break-after: always;
104
+ position: relative;
105
+ overflow: hidden;
106
+ }
107
+ .backpage {
108
+ width: auto; margin: 0; box-shadow: none; /* reset screen-only properties */
109
+ min-height: 0;
110
+ height: 100vh;
111
+ page-break-before: always;
112
+ position: relative;
113
+ overflow: hidden;
114
+ page: backpage-full;
115
+ }
116
+ }
117
+ ```
118
+
119
+ **Key details:**
120
+ - `@page :first` zeros the margins for the cover — no named page needed on the cover element.
121
+ - Named pages are only needed for non-first full-bleed pages (backpage).
122
+ - `counter(page)` gives automatic page numbering with no JavaScript.
123
+ - No `position: fixed` hacks are needed for repeating headers/footers.
124
+ - If the screen CSS uses `width: 210mm; margin: 20px auto; box-shadow: ...` on the cover/backpage (for the card-on-grey-background look), the print CSS MUST explicitly reset these: `width: auto; margin: 0; box-shadow: none;`. Screen-only layout properties leak into print if not reset. Do NOT use `width: 100vw` or `margin: 0 !important` — just `width: auto; margin: 0`.
125
+ - The print image uses `position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;`.
126
+
127
+ ## A4 layout — continuous flow, not fixed-height boxes
128
+
129
+ Forcing each section into a fixed `height: 297mm` div creates large whitespace gaps when content doesn't fill a full page.
130
+
131
+ **Correct approach:**
132
+
133
+ - **Cover page:** `min-height: 100vh` on screen; `height: 100vh; page-break-after: always;` in print.
134
+ - **Content:** Flows naturally. The `@page` margins handle spacing. No fixed-height containers.
135
+ - Use `page-break-inside: avoid` on logical units (cards, tables, callouts, stat groups, timeline items, competitor cards, pullquotes).
136
+ - Use `page-break-before: always` on major section dividers (part breaks).
137
+ - Use `page-break-after: avoid` on headings and section numbers so they don't strand at the bottom of a page.
138
+ - Set `orphans: 3; widows: 3;` on paragraphs to prevent single-line stragglers.
139
+
140
+ ## Dark backgrounds are stripped in print
141
+
142
+ Browsers strip background colours by default when printing.
143
+
144
+ **Required:** Add both properties to every dark element in `@media print`:
145
+
146
+ ```css
147
+ @media print {
148
+ .dark-element {
149
+ -webkit-print-color-adjust: exact;
150
+ print-color-adjust: exact;
151
+ }
152
+ }
153
+ ```
154
+
155
+ ## Stripping glassmorphism from content areas
156
+
157
+ In multi-page documents, strip `backdrop-filter` from content sections (where it won't render correctly anyway) while preserving it on cover/backpage elements that are replaced with print images:
158
+
159
+ ```css
160
+ @media print {
161
+ /* Strip glass from content */
162
+ .content *, .content *::before, .content *::after {
163
+ backdrop-filter: none !important;
164
+ -webkit-backdrop-filter: none !important;
165
+ border-radius: 0 !important;
166
+ box-shadow: none !important;
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Document structure pattern
172
+
173
+ Multi-page documents follow this structure:
174
+
175
+ 1. **Cover** — full-bleed, glassmorphism, with print image fallback. Uses `@page :first { margin: 0; }` — NO named page on the element. `page-break-after: always`.
176
+ 2. **Table of contents** (optional) — `page-break-after: always` to start content on a fresh page.
177
+ 3. **Content sections** — flowing, with part dividers using `page-break-before: always`.
178
+ 4. **Back page** — full-bleed CTA/contact page. **Not** an inline footer div — a separate top-level element outside `.body-wrap` with its own named page, print image fallback, and `page-break-before: always`.
179
+
180
+ **The back page is mandatory for multi-page documents.** An inline CTA footer (a `div` inside flowing content) ends up floating mid-page with whitespace below it. The back page pattern guarantees a clean final page.
181
+
182
+ ```css
183
+ @page backpage-full {
184
+ margin: 0;
185
+ @bottom-center { content: none; }
186
+ }
187
+
188
+ @media print {
189
+ .backpage {
190
+ page: backpage-full;
191
+ min-height: 0; height: 100vh;
192
+ page-break-before: always;
193
+ position: relative; overflow: hidden;
194
+ }
195
+ .backpage > *:not(.backpage-print-img) { display: none !important; }
196
+ .backpage-print-img {
197
+ display: block !important;
198
+ position: absolute;
199
+ inset: 0;
200
+ width: 100%; height: 100%;
201
+ object-fit: cover;
202
+ }
203
+ }
204
+ ```
205
+
206
+ ```html
207
+ <!-- Outside .body-wrap, after it closes -->
208
+ <div class="backpage">
209
+ <img class="backpage-print-img" src="backpage-print.png" alt="" style="display:none;">
210
+ <!-- live backpage content (bg, text, contact info) -->
211
+ </div>
212
+ ```
213
+
214
+ The backpage print image is captured via the same browser-specialist delegation process as the cover — element-level screenshot with UI chrome hidden.
215
+
216
+ ## Single-page documents
217
+
218
+ For single A4 documents (one-pagers), use fixed dimensions:
219
+
220
+ ```css
221
+ .page {
222
+ width: 210mm;
223
+ min-height: 297mm;
224
+ margin: 0 auto;
225
+ overflow: hidden;
226
+ }
227
+
228
+ @page { size: A4; margin: 0; }
229
+
230
+ @media print {
231
+ .page {
232
+ width: 210mm;
233
+ height: 297mm;
234
+ page-break-after: always;
235
+ }
236
+ }
237
+ ```
238
+
239
+ ## Document background for multi-page screen viewing
240
+
241
+ Multi-page documents use a neutral body background (e.g. `body { background: var(--background); }`) on screen. In `@media print`, reset to `body { background: white; }`.
@@ -46,6 +46,8 @@ Ask what rules the agent should follow when using this skill:
46
46
 
47
47
  Not every skill needs all of these. Only include what's relevant.
48
48
 
49
+ If the skill involves generating PDFs or print-ready documents, load `references/pdf-generation.md` for the constraints on HTML layout and the `browser_pdf_save` rendering path.
50
+
49
51
  ## Step 4: Decide on References
50
52
 
51
53
  If the skill has detailed procedures, templates, or data formats, those belong in `references/` files — not inline in SKILL.md.
@@ -0,0 +1,30 @@
1
+ # PDF Generation in Skills
2
+
3
+ When a skill needs to produce a PDF, the output is always a two-stage process: the skill authors the HTML, and the browser-specialist renders it to PDF via the `browser_pdf_save` MCP tool.
4
+
5
+ ## The rule
6
+
7
+ Never instruct the agent to write or execute raw Node.js scripts (e.g. `require('playwright')`, `page.pdf()`, `npx playwright`). Playwright is not in the Node.js module path — these scripts fail with MODULE_NOT_FOUND, waste tool calls searching the filesystem, and produce hardcoded paths that break on reinstall.
8
+
9
+ Instead, skills that produce PDFs should:
10
+
11
+ 1. **Build the HTML** — the skill's behaviour section describes what the document contains and how it's structured. The agent writes the HTML file using standard file tools.
12
+ 2. **Delegate rendering to browser-specialist** — the agent asks the browser-specialist to navigate to the HTML file and call `browser_pdf_save` to produce the PDF. The specialist has Playwright access through governed MCP tools; the admin agent does not.
13
+
14
+ ## Print-ready HTML constraints
15
+
16
+ HTML intended for PDF output must follow print-ready layout patterns. The most common failures when agents design their own pagination are rigid fixed-height page divs (causing whitespace gaps) and `position: fixed` hacks for headers/footers (causing overlap and duplication).
17
+
18
+ **Continuous flow layout** — content flows naturally. Use `@page` margin rules for page margins, not wrapper divs with fixed heights. Use `page-break-inside: avoid` on logical units (cards, tables, stat groups) and `page-break-before: always` on major section dividers.
19
+
20
+ **Page numbers and running footers** — use `@page` margin boxes (`@bottom-center { content: counter(page); }`), not JavaScript or position-fixed elements.
21
+
22
+ **Dark backgrounds in print** — browsers strip background colours by default. Add `print-color-adjust: exact; -webkit-print-color-adjust: exact;` to dark elements in `@media print`.
23
+
24
+ **Cover and back pages** — full-bleed pages use `height: 100vh; page-break-after: always;` in `@media print` with zero `@page` margins (via `@page :first` for covers, named pages for back pages).
25
+
26
+ **Glassmorphism and backdrop-filter** — these do not survive browser print rendering. Any section using glassmorphism needs a pre-rendered PNG fallback image that is hidden on screen and shown only in `@media print`.
27
+
28
+ ## What the skill file should contain
29
+
30
+ The skill's SKILL.md describes the document's purpose and structure. A `references/` file holds the HTML template or content specification. The skill should state that PDF rendering is delegated to browser-specialist — it should not contain Playwright code, npm commands, or file path assumptions about the Playwright installation.
@@ -31,6 +31,7 @@ Conversation is the only interface. Type what you need:
31
31
  - "Schedule a call with Sarah for Thursday at 2pm"
32
32
  - "What did I last discuss with Tom?"
33
33
  - "Send a Telegram message to the team: standup in 10 minutes"
34
+ - "Create a one-pager PDF about our new product launch"
34
35
 
35
36
  Maxy understands plain language. You don't need to learn commands or navigate menus.
36
37
 
@@ -17,22 +17,42 @@ Call `whatsapp-status` first — if no WhatsApp account is connected, direct the
17
17
 
18
18
  ## Presenting settings
19
19
 
20
- Call `whatsapp-config action: schema` to get field definitions with descriptions, types, defaults, and constraints. Use the Description column from the schema output as the `description` field on each form field — do not improvise descriptions.
20
+ Call `whatsapp-config action: schema` to get field definitions with descriptions, and `whatsapp-config action: get-config` to get current values. Use the Description column from the schema output as the `description` field on each form field — do not improvise descriptions.
21
21
 
22
- Group related settings logically when presenting:
22
+ ### Admin phones
23
23
 
24
- 1. **Messaging policies**dmPolicy, groupPolicy, allowFrom, groupAllowFrom
25
- 2. **Operational limits** — mediaMaxMb, textChunkLimit, debounceMs
26
- 3. **Behaviour** — sendReadReceipts, ackReaction
27
- 4. **Account settings** — name, enabled, selfChatMode
28
- 5. **Group configuration** — groups (per-group activation)
24
+ Before the form, call `whatsapp-config action: list-admin-phones` and display the result. Admin phones are managed via `add-admin-phone` / `remove-admin-phone` they are not editable in this form.
29
25
 
30
- Present settings as a `render-component` form with:
31
- - `description` on every field (from schema output)
32
- - `defaultValue` showing the current value or the schema default
33
- - Rich option labels with descriptions for enum fields (e.g. dmPolicy options should explain what "open", "allowlist", and "disabled" each mean)
26
+ ### Form fields
34
27
 
35
- Before the user submits, summarise what each default does the user should understand the implications of keeping defaults, not just see them pre-filled.
28
+ Present settings as a `render-component` form. Each field must have a unique `name` matching the schema field name (used as the state key and the `update-config` field key), a `type`, a `label` (plain English), and a `description` (from schema output). For selects, specify `options`. For all fields, set `defaultValue` from `get-config` (current value) or the schema default.
29
+
30
+ **Messaging policies:**
31
+
32
+ - `dmPolicy` (`select`): label "Who can message your agent (DMs)", options:
33
+ - `open` — "Open — anyone can message"
34
+ - `allowlist` — "Allowlist — only approved numbers"
35
+ - `disabled` — "Disabled — no public DMs"
36
+ - `groupPolicy` (`select`): label "Group message handling", options:
37
+ - `open` — "Always — respond to all group messages"
38
+ - `allowlist` — "Allowlist — only in approved groups"
39
+ - `disabled` — "Disabled — ignore all group messages"
40
+
41
+ **Behaviour:**
42
+
43
+ - `sendReadReceipts` (`select`): label "Blue ticks (read receipts)", options:
44
+ - `true` — "On — contacts see read receipts"
45
+ - `false` — "Off — no read receipts"
46
+
47
+ **Operational limits:**
48
+
49
+ - `mediaMaxMb` (`number`): label "Media size limit (MB)"
50
+ - `textChunkLimit` (`number`): label "Message chunk limit (characters)"
51
+ - `debounceMs` (`number`): label "Message batching delay (ms)"
52
+
53
+ ### Submit
54
+
55
+ The form's `submitMessage` must map the field values back to `update-config` field names: `Save these WhatsApp settings: {{json}}` — where `{{json}}` produces the JSON object with field names as keys (e.g. `{ "dmPolicy": "open", "mediaMaxMb": 50, ... }`).
36
56
 
37
57
  ## Group configuration
38
58
 
@@ -51,9 +71,11 @@ After the user submits, write changes via `whatsapp-config action: "update-confi
51
71
 
52
72
  ## Language
53
73
 
54
- Use plain English:
55
- - "Who can message your agent" not "dmPolicy"
56
- - "Message batching delay" not "debounceMs"
57
- - "Media size limit" not "mediaMaxMb"
58
- - "Blue ticks" not "sendReadReceipts"
59
- - Group names, not JIDs
74
+ Plain English goes in `label` — schema field names go in `name`. The `name` property is the machine key (must match the schema exactly); the `label` is what the user reads. Examples:
75
+
76
+ - `name: "dmPolicy"`, `label: "Who can message your agent (DMs)"`
77
+ - `name: "debounceMs"`, `label: "Message batching delay (ms)"`
78
+ - `name: "mediaMaxMb"`, `label: "Media size limit (MB)"`
79
+ - `name: "sendReadReceipts"`, `label: "Blue ticks (read receipts)"`
80
+
81
+ Group names (not JIDs) in all user-facing text.
@@ -3,7 +3,7 @@ name: browser-specialist
3
3
  description: "Web browser tasks — visiting websites, filling forms, clicking buttons, and reading page content. Delegate when a task requires controlling the browser."
4
4
  summary: "Browses the web on your behalf — visiting websites, filling in forms, and extracting information. For example, when you need to sign up for a service, check a competitor's pricing page, or set up an online account."
5
5
  model: claude-sonnet-4-6
6
- tools: mcp__plugin_playwright_playwright__browser_navigate, mcp__plugin_playwright_playwright__browser_navigate_back, mcp__plugin_playwright_playwright__browser_snapshot, mcp__plugin_playwright_playwright__browser_take_screenshot, mcp__plugin_playwright_playwright__browser_click, mcp__plugin_playwright_playwright__browser_fill, mcp__plugin_playwright_playwright__browser_fill_form, mcp__plugin_playwright_playwright__browser_type, mcp__plugin_playwright_playwright__browser_press_key, mcp__plugin_playwright_playwright__browser_hover, mcp__plugin_playwright_playwright__browser_select_option, mcp__plugin_playwright_playwright__browser_wait_for, mcp__plugin_playwright_playwright__browser_handle_dialog, mcp__plugin_playwright_playwright__browser_evaluate, mcp__plugin_playwright_playwright__browser_console_messages, mcp__plugin_playwright_playwright__browser_resize, mcp__plugin_playwright_playwright__browser_tabs, mcp__plugin_playwright_playwright__browser_close, mcp__admin__api-key-store
6
+ tools: mcp__plugin_playwright_playwright__browser_navigate, mcp__plugin_playwright_playwright__browser_navigate_back, mcp__plugin_playwright_playwright__browser_snapshot, mcp__plugin_playwright_playwright__browser_take_screenshot, mcp__plugin_playwright_playwright__browser_click, mcp__plugin_playwright_playwright__browser_fill, mcp__plugin_playwright_playwright__browser_fill_form, mcp__plugin_playwright_playwright__browser_type, mcp__plugin_playwright_playwright__browser_press_key, mcp__plugin_playwright_playwright__browser_hover, mcp__plugin_playwright_playwright__browser_select_option, mcp__plugin_playwright_playwright__browser_wait_for, mcp__plugin_playwright_playwright__browser_handle_dialog, mcp__plugin_playwright_playwright__browser_evaluate, mcp__plugin_playwright_playwright__browser_console_messages, mcp__plugin_playwright_playwright__browser_resize, mcp__plugin_playwright_playwright__browser_tabs, mcp__plugin_playwright_playwright__browser_close, mcp__plugin_playwright_playwright__browser_pdf_save, mcp__admin__api-key-store
7
7
  ---
8
8
 
9
9
  # Browser Specialist