@rubytech/create-maxy-code 0.1.67 → 0.1.69
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 +1 -1
- package/payload/platform/plugins/docs/references/admin-session.md +39 -2
- package/payload/platform/plugins/docs/references/deployment.md +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-not-applicable.test.js +3 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-not-applicable.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +55 -55
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +4 -4
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +19 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +18 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts +42 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js +330 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +10 -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 +15 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +8 -5
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +35 -16
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +8 -0
- package/payload/platform/templates/agents/admin/SOUL.md +1 -1
- package/payload/platform/templates/specialists/agents/database-operator.md +8 -48
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/brand-design/SKILL.md +48 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/make-brochure/SKILL.md +1 -1
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/SKILL.md +36 -5
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/build.md +256 -11
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/index.html +1 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/registers.md +65 -8
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-brochure/references/template.html +1 -0
- package/payload/server/{chunk-S6PQA6Q4.js → chunk-HZ77KMTV.js} +1 -1
- package/payload/server/{chunk-NPZKH5EC.js → chunk-ITQ55PCQ.js} +1 -1
- package/payload/server/{chunk-X3Y6ENKA.js → chunk-VGMVEYX7.js} +35 -61
- package/payload/server/{cloudflare-task-tracker-TL6R364J.js → cloudflare-task-tracker-PZBX7X3D.js} +2 -2
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/assets/{admin-t8QqVwJF.js → admin-BPRjc4z9.js} +3 -3
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DgfgldJT.js → architectureDiagram-Q4EWVU46-Asw7tNG5.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-agu8GDzA.js → blockDiagram-DXYQGD6D-Blvay4_b.js} +1 -1
- package/payload/server/public/assets/{brand-BWCtpG7_.js → brand-B8JhGW9e.js} +1 -1
- package/payload/server/public/assets/{brand-BDASZqMG.css → brand-CwHvVF8s.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CmNsUmAe.js → c4Diagram-AHTNJAMY-C2st6jZP.js} +1 -1
- package/payload/server/public/assets/channel-DTh_uFbz.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-D9Uts7k9.js → chunk-336JU56O-Cp7B2yh1.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-D4ABqXMn.js → chunk-426QAEUC-B0x3RXvj.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-D1KE4OAX.js → chunk-4TB4RGXK-B0yM0pgq.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CAh0GXe2.js → chunk-5FUZZQ4R-CqGhfArO.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-DBHa6HOv.js → chunk-5PVQY5BW-jSeD3Yrj.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BDC-6mL3.js → chunk-EDXVE4YY-C7HuvG2r.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CH3uROkW.js → chunk-ENJZ2VHE-DzCrge6H.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-BzZf0nAw.js → chunk-ICPOFSXX-BPvCh0Yc.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BrLHrI6O.js → chunk-OYMX7WX6-DamxwrTn.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-Bw4UkLe_.js → chunk-U2HBQHQK-DDiVd0qV.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-23xgdk05.js → chunk-X2U36JSP-CDof681v.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BA8iGgRa.js → chunk-YZCP3GAM-DYzaYjrN.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-B-ol4EgR.js → chunk-ZZ45TVLE-j0bcHHzU.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Dsupydrn.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DrwAXnBf.js +1 -0
- package/payload/server/public/assets/clone-COx5mf-H.js +1 -0
- package/payload/server/public/assets/{dagre--kXszEIb.js → dagre-C8nbdG6y.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-amN1uU2d.js → dagre-KV5264BT-1RnGN_fy.js} +1 -1
- package/payload/server/public/assets/data-DOI26n9p.js +1 -0
- package/payload/server/public/assets/{device-url-actions-CPoz5fqz.js → device-url-actions-C_Keyr0L.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-Cwizs9tP.js → diagram-5BDNPKRD-C6d3Rrui.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BpSu5Uao.js → diagram-G4DWMVQ6-aD4Dik01.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DiArtkto.js → diagram-MMDJMWI5-CAub49YE.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-_tygK58Y.js → diagram-TYMM5635-CAKnAfEr.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-CBV6LWYA.js → erDiagram-SMLLAGMA-BrqOworC.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CHZFrtOU.js → flowDiagram-DWJPFMVM-DV4eU-T2.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-B3vKq5ov.js → ganttDiagram-T4ZO3ILL-DayXUN42.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-dnJPjbtj.js → gitGraphDiagram-UUTBAWPF-CK1xV1OV.js} +1 -1
- package/payload/server/public/assets/graph-DP9P7TKZ.js +1 -0
- package/payload/server/public/assets/graph-labels-BoLyECfJ.js +1 -0
- package/payload/server/public/assets/{graphlib-CNXtnega.js → graphlib-CkF9o1XT.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-D8DYwVAF.js → infoDiagram-42DDH7IO-CiepM2H6.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CfEVY2Ud.js → ishikawaDiagram-UXIWVN3A-DwNkdQ6z.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-FmoBq7Kh.js → journeyDiagram-VCZTEJTY-BlDLMfu_.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-B-Q9qk99.js → kanban-definition-6JOO6SKY-ayZTc0Oj.js} +1 -1
- package/payload/server/public/assets/{line-DZwbJENP.js → line-LhPUiuH-.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-C3ahKykw.js → mermaid-parser.core-DyZYsQv_.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-B8OFZIE8.js → mermaid.core-CauxgRdz.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CqhkfbWa.js → mindmap-definition-QFDTVHPH-CQzcaJuh.js} +1 -1
- package/payload/server/public/assets/{page-B9GFro9g.js → page-BGv81dGN.js} +1 -1
- package/payload/server/public/assets/{page-BWKfXlHt.js → page-DAw3-U_s.js} +2 -2
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CJqQ6u3-.js → pieDiagram-DEJITSTG-BPhAeTm9.js} +1 -1
- package/payload/server/public/assets/{public-rWe9ADCS.js → public-CGI24wrL.js} +5 -5
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BtEqOXQM.js → quadrantDiagram-34T5L4WZ-CxrzL3ZF.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DPHWUtE6.js → requirementDiagram-MS252O5E-ZBSC4fGX.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-FBmc3wHT.js → sankeyDiagram-XADWPNL6-BTDBEisC.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BMSd2-1M.js → sequenceDiagram-FGHM5R23-Bv7fA5_J.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DqFbU-LT.js → stateDiagram-FHFEXIEX-D07lcZrk.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Cr1Qet-f.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DsfvHVK8.js → timeline-definition-GMOUNBTQ-DyeyUqKa.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-kHU05mqC.js → vennDiagram-DHZGUBPP-B9FqDmwS.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C696Mez_.js → wardleyDiagram-NUSXRM2D-4-5uCIAD.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-yht-JyXJ.js → xychartDiagram-5P7HB3ND-WdkP5T_y.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +5 -5
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +18 -6
- package/payload/server/public/assets/channel-DXGOX55q.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DTuuDxpK.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CIw8RU0q.js +0 -1
- package/payload/server/public/assets/clone-O4ZyuvYl.js +0 -1
- package/payload/server/public/assets/data-vHmNQyXt.js +0 -1
- package/payload/server/public/assets/graph-C7QOwigU.js +0 -1
- package/payload/server/public/assets/graph-labels-Dm2RMEFy.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CXTnsHGq.js +0 -1
|
@@ -4,17 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
1. Copy template to property directory, populate with content
|
|
6
6
|
2. Stage `output/images/` per `images.md → Image renaming and optimisation`
|
|
7
|
-
3.
|
|
8
|
-
4.
|
|
9
|
-
5.
|
|
10
|
-
6.
|
|
11
|
-
7.
|
|
12
|
-
8. Verify
|
|
13
|
-
9.
|
|
14
|
-
10.
|
|
15
|
-
11.
|
|
16
|
-
12. Build
|
|
17
|
-
13.
|
|
7
|
+
3. **If branded register and `<brand_dir>/DESIGN.md` contains a `## Type roles` block** — emit the role overlay into both `brochure.html` and `page.html`/`index.html` per **Type-role overlay generation** below. Run this **before** any snapshot capture; the overlay is part of what the user reviews in the browser, not a post-process applied to PDFs.
|
|
8
|
+
4. Serve locally: `python3 -m http.server <port>` from the project root
|
|
9
|
+
5. Navigate Playwright to the brochure URL
|
|
10
|
+
6. Present to user in browser for review
|
|
11
|
+
7. User requests changes — iterate on content, image sizing, page balance
|
|
12
|
+
8. Verify every page fits A4: measure `scrollHeight` for all `.page` elements
|
|
13
|
+
9. Verify no 404s in the browser console
|
|
14
|
+
10. Repeat 6–9 until user approves the final copy
|
|
15
|
+
11. **Only after user approval**: render snapshots (two passes — 300 dpi to `output/`, 192 dpi to `output/.snapshots-web/`) per **Print snapshot capture** below
|
|
16
|
+
12. Build both PDFs (img2pdf + qpdf) per **PDF deliverable** below
|
|
17
|
+
13. Build the web bundle (96 dpi JPGs + bundled web PDF + zip) per **Web bundle** below
|
|
18
|
+
14. User downloads the web PDF via brochure.html's Download button or receives the print master separately for press/print runs
|
|
18
19
|
|
|
19
20
|
Do not capture snapshots during the editing cycle — they are expensive and invalidated by every change.
|
|
20
21
|
|
|
@@ -268,3 +269,247 @@ The brochure should render the same as the canonical preview, just lighter on th
|
|
|
268
269
|
| `.snapshots-web/*-print.png` | ✓ intermediate (192 dpi PNGs used by the web-PDF build; deletable after) | — |
|
|
269
270
|
|
|
270
271
|
The convention: `output/` is the canonical archive for the property's lifetime. `output/web/` is a derived bundle, regenerable any time from the canonical artefacts.
|
|
272
|
+
|
|
273
|
+
## Type-role overlay generation
|
|
274
|
+
|
|
275
|
+
If the brand pack's `DESIGN.md` contains a `## Type roles` block (declared per `references/registers.md → Type-role overrides`), parse it and emit a single `<style id="brand-type-roles">…</style>` block at the `<!-- BRAND_TYPE_ROLES_OVERRIDE_SLOT -->` sentinel immediately before the closing `</style>` of the template's main stylesheet. The override CSS is generated **mechanically** from the recipe map below — the build does not invent selectors, it emits the documented ones using values from the DESIGN doc.
|
|
276
|
+
|
|
277
|
+
Two agents running this build on different days for the same brand pack produce byte-identical overlays. That is the contract.
|
|
278
|
+
|
|
279
|
+
The role-overlay step runs **before** snapshot capture (step 10 in the live-editing workflow), not after. The overlay is part of the rendered HTML the user reviews, not a post-process applied to PDFs.
|
|
280
|
+
|
|
281
|
+
### Recipe map — reference implementation
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
ROLE_RECIPES = {
|
|
285
|
+
'display-headline-style': {
|
|
286
|
+
'normal': [
|
|
287
|
+
'.cover-title, .opener-title, .ed-headline, .chapter-head h3, '
|
|
288
|
+
'.feature-page h3, .gallery-head h3, .siteplan-page h3, .toc-title, '
|
|
289
|
+
'.back-headline, .mi-head h2, .mi-head h3 '
|
|
290
|
+
'{ font-style: normal !important; }',
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
'display-em-style': {
|
|
294
|
+
'weight-shift': [
|
|
295
|
+
'.cover-title em, .opener-title em, .ed-headline em, .toc-title em, '
|
|
296
|
+
'.back-headline em, .mi-head em '
|
|
297
|
+
'{ font-style: normal !important; font-weight: 500 !important; }',
|
|
298
|
+
],
|
|
299
|
+
'normal': [
|
|
300
|
+
'.cover-title em, .opener-title em, .ed-headline em, .toc-title em, '
|
|
301
|
+
'.back-headline em, .mi-head em '
|
|
302
|
+
'{ font-style: normal !important; }',
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
'display-letterspacing': {
|
|
306
|
+
# tuned to family: Cormorant=wide (0.18em), humanist sans=medium (0.10em),
|
|
307
|
+
# geometric sans=tight (0.04em). Applies only to the two largest display lines.
|
|
308
|
+
'medium': [
|
|
309
|
+
'.cover-title { letter-spacing: 0.10em !important; text-indent: 0.10em !important; }',
|
|
310
|
+
'.opener-title { letter-spacing: -0.012em !important; }',
|
|
311
|
+
],
|
|
312
|
+
'tight': [
|
|
313
|
+
'.cover-title { letter-spacing: 0.04em !important; text-indent: 0.04em !important; }',
|
|
314
|
+
'.opener-title { letter-spacing: -0.02em !important; }',
|
|
315
|
+
],
|
|
316
|
+
},
|
|
317
|
+
'deck-family': {
|
|
318
|
+
'sans': [
|
|
319
|
+
'.ed-deck, .ed-deck em, .feature-deck, .gallery-deck, .siteplan-deck '
|
|
320
|
+
'{ font-family: var(--sans) !important; font-style: normal !important; }',
|
|
321
|
+
],
|
|
322
|
+
},
|
|
323
|
+
'deck-case': {
|
|
324
|
+
'sentence': [
|
|
325
|
+
'.ed-deck, .feature-deck, .gallery-deck, .siteplan-deck '
|
|
326
|
+
'{ letter-spacing: 0.02em !important; text-transform: none !important; }',
|
|
327
|
+
'.ed-deck em { font-weight: 500 !important; }',
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
'subtitle-family': {
|
|
331
|
+
'sans-tracked-caps': [
|
|
332
|
+
'.opener-title em, .cover-subtitle, .opener-spec '
|
|
333
|
+
'{ font-family: var(--sans) !important; font-style: normal !important; }',
|
|
334
|
+
'.opener-spec em { font-style: normal !important; font-weight: 500 !important; }',
|
|
335
|
+
],
|
|
336
|
+
'sans': [
|
|
337
|
+
'.opener-title em, .cover-subtitle, .opener-spec '
|
|
338
|
+
'{ font-family: var(--sans) !important; font-style: normal !important; '
|
|
339
|
+
'letter-spacing: 0.04em !important; text-transform: none !important; }',
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
'caption-family': {
|
|
343
|
+
'sans': [
|
|
344
|
+
'.ed-caption, .ed-caption strong, .caption, .caption-pill, .caption-text, '
|
|
345
|
+
'.img-caption, .photo-caption, .intermission .caption-pill '
|
|
346
|
+
'{ font-family: var(--sans) !important; font-style: normal !important; }',
|
|
347
|
+
],
|
|
348
|
+
},
|
|
349
|
+
'caption-em-style': {
|
|
350
|
+
'weight-shift': [
|
|
351
|
+
'.ed-caption em, .caption em, .caption-text em, .img-caption em, '
|
|
352
|
+
'.photo-caption em, .intermission .caption-pill em '
|
|
353
|
+
'{ font-style: normal !important; font-weight: 500 !important; }',
|
|
354
|
+
],
|
|
355
|
+
},
|
|
356
|
+
'dropcap': {
|
|
357
|
+
'ink': [
|
|
358
|
+
'.ed-body.dropcap::first-letter { color: var(--ink) !important; }',
|
|
359
|
+
],
|
|
360
|
+
'ink-bold-sans': [
|
|
361
|
+
'.ed-body.dropcap::first-letter { '
|
|
362
|
+
'font-family: var(--sans) !important; font-style: normal !important; '
|
|
363
|
+
'font-weight: 700 !important; color: var(--ink) !important; }',
|
|
364
|
+
],
|
|
365
|
+
'hidden': [
|
|
366
|
+
'.ed-body.dropcap::first-letter { '
|
|
367
|
+
'font-family: var(--sans) !important; font-style: normal !important; '
|
|
368
|
+
'font-size: inherit !important; font-weight: 400 !important; '
|
|
369
|
+
'line-height: inherit !important; color: inherit !important; '
|
|
370
|
+
'float: none !important; padding: 0 !important; }',
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
'hairline-rules': {
|
|
374
|
+
'eyebrow-only': [
|
|
375
|
+
'.opener .ed-rule, .opener-text .ed-rule, .opener-body .ed-rule, '
|
|
376
|
+
'.feature-page .ed-rule, .gallery-head .ed-rule, .siteplan-page .ed-rule, '
|
|
377
|
+
'.chapter-head .ed-rule { display: none !important; }',
|
|
378
|
+
],
|
|
379
|
+
'hidden': [
|
|
380
|
+
'.ed-rule, .toc-rule { display: none !important; }',
|
|
381
|
+
],
|
|
382
|
+
},
|
|
383
|
+
'body-em-style': {
|
|
384
|
+
'weight-shift': [
|
|
385
|
+
'.ed-body em, .opener-body em, .opener-text em, .gallery-cell em, '
|
|
386
|
+
'.siteplan-panel em, .spec-list li em, .mi-row em, .floorplan-lead em, '
|
|
387
|
+
'.floorplan-sub em, .epc-caption em '
|
|
388
|
+
'{ font-style: normal !important; font-weight: 500 !important; }',
|
|
389
|
+
],
|
|
390
|
+
},
|
|
391
|
+
'folio-em-style': {
|
|
392
|
+
'weight-shift': [
|
|
393
|
+
'.folio em, .folio .folio-mid em '
|
|
394
|
+
'{ font-style: normal !important; font-weight: 500 !important; '
|
|
395
|
+
'font-family: var(--sans) !important; }',
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
'backpage-em-style': {
|
|
399
|
+
'weight-shift': [
|
|
400
|
+
'.back-headline em, .back-tagline em, .back-foot em, .back-contact-grid em, '
|
|
401
|
+
'.back-rule em { font-style: normal !important; font-weight: 500 !important; }',
|
|
402
|
+
],
|
|
403
|
+
},
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def emit_overlay(role_values: dict[str, str]) -> str:
|
|
408
|
+
"""Compose the <style id='brand-type-roles'> block from a {role: value} dict.
|
|
409
|
+
|
|
410
|
+
role_values is parsed from the DESIGN.md `## Type roles` block — either a
|
|
411
|
+
role/value table or a flat `role: value` line list. Missing roles inherit
|
|
412
|
+
the template default (no CSS emitted). Unknown roles raise ValueError so
|
|
413
|
+
they surface during the build, not silently in the rendered brochure.
|
|
414
|
+
|
|
415
|
+
DARK_SURFACE_PROTECTION and STRUCTURAL_CLAMP_LOOSEN are emitted FIRST and
|
|
416
|
+
UNCONDITIONALLY whenever any role values are declared. They are the
|
|
417
|
+
foundation of any branded re-skin; see "Always-emit recipes" above.
|
|
418
|
+
"""
|
|
419
|
+
if not role_values:
|
|
420
|
+
return "" # No role block declared — emit nothing.
|
|
421
|
+
lines = ["<style id=\"brand-type-roles\">"]
|
|
422
|
+
lines.append(" /* === DARK SURFACE PROTECTION === */")
|
|
423
|
+
lines.extend(DARK_SURFACE_PROTECTION)
|
|
424
|
+
lines.append(" /* === STRUCTURAL CLAMP LOOSEN === */")
|
|
425
|
+
lines.extend(STRUCTURAL_CLAMP_LOOSEN)
|
|
426
|
+
for role, value in role_values.items():
|
|
427
|
+
if role not in ROLE_RECIPES:
|
|
428
|
+
raise ValueError(f"Unknown type role: {role}")
|
|
429
|
+
if value not in ROLE_RECIPES[role]:
|
|
430
|
+
raise ValueError(f"Unknown value '{value}' for role '{role}'")
|
|
431
|
+
lines.append(f" /* === ROLE: {role}: {value} === */")
|
|
432
|
+
lines.extend(ROLE_RECIPES[role][value])
|
|
433
|
+
lines.append("</style>")
|
|
434
|
+
return "\n".join(lines)
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
### Always-emit recipes — dark-surface protection and structural clamps
|
|
439
|
+
|
|
440
|
+
Two sections of the overlay are emitted **whenever the brand pack's `## Type roles` block is present**, regardless of which roles the operator declared. They are the foundation of any branded re-skin — without them the role API's targeted overrides can blow up adjacent template assumptions.
|
|
441
|
+
|
|
442
|
+
#### Dark-surface protection (fixed exclusion list)
|
|
443
|
+
|
|
444
|
+
The role API's color rules deliberately stop short of selectors that sit on dark surfaces — the toc-image caption pill, intermission caption pills, the spread-6 chapter-head overlay on a dark photo, the back-page masthead and tagline, and the back-page contact-grid name lines. The brand-token swap will have remapped `--gold-700` (the template's italic-emphasis color) to the brand's accent — typically navy or a deep brand colour. On a light surface, that's correct. On a dark surface, navy on dark is unreadable.
|
|
445
|
+
|
|
446
|
+
The recipe is a **fixed exclusion list**, not a heuristic. Ship it as part of the overlay:
|
|
447
|
+
|
|
448
|
+
```python
|
|
449
|
+
DARK_SURFACE_PROTECTION = [
|
|
450
|
+
# Body text on dark surfaces — keep paper-light regardless of brand-token swap.
|
|
451
|
+
'.toc-image .caption, .toc-image .caption *, '
|
|
452
|
+
'.intermission .caption-pill, .intermission .caption-pill *, '
|
|
453
|
+
'.spread-6 .top-image .overlay, .spread-6 .top-image .overlay *, '
|
|
454
|
+
'.back-headline, .back-tagline, .back-foot, .back-contact-grid, .back-rule '
|
|
455
|
+
'{ color: var(--paper-25) !important; }',
|
|
456
|
+
# Emphasis on dark surfaces — use the brand accent (--gold-300) which the
|
|
457
|
+
# brand-tokens block typically maps to the brand's bright/highlight colour.
|
|
458
|
+
'.toc-image .caption em, '
|
|
459
|
+
'.intermission .caption-pill em, '
|
|
460
|
+
'.spread-6 .top-image .overlay em, '
|
|
461
|
+
'.spread-6 .top-image .overlay .ed-headline em, '
|
|
462
|
+
'.back-headline em, '
|
|
463
|
+
'.back-tagline em, '
|
|
464
|
+
'.back-contact-grid .cell .name em, '
|
|
465
|
+
'.back-foot em '
|
|
466
|
+
'{ color: var(--gold-300) !important; }',
|
|
467
|
+
]
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
The selector list is closed. Two agents producing brochures for the same brand pack emit byte-identical dark-surface blocks. If the template adds a new dark-surface region in a future revision, this list (in `build.md`) is the authoritative update site.
|
|
471
|
+
|
|
472
|
+
#### Structural clamp loosen
|
|
473
|
+
|
|
474
|
+
The template's chapter-heading grid rows are sized for the Cormorant Garamond display setup (italic, weight 400, letter-spacing tuned for didone). When the role overlay swaps display family, weight, or letter-spacing, headings can grow a few millimetres beyond what the fixed-height rows accommodate — and the template's `overflow: hidden` on those rows clips the descenders. The proposal author's term for this is "structural-element clamps that need to be loosened together with the type-role overlay."
|
|
475
|
+
|
|
476
|
+
The recipe is bounded: only the known fixed-height heading rows in spreads 2 and 3 are loosened, and only to `minmax(<original>, max-content)`. A heading that already fits the original budget renders identically; a heading that needs a few extra mm no longer clips.
|
|
477
|
+
|
|
478
|
+
```python
|
|
479
|
+
STRUCTURAL_CLAMP_LOOSEN = [
|
|
480
|
+
# spread-3: chapter heading row fixed at 60mm in the template.
|
|
481
|
+
# Loosen to "60mm but grow if needed" — image cells in the second row
|
|
482
|
+
# absorb the shrinkage when the heading takes extra height.
|
|
483
|
+
'.spread-3 { grid-template-rows: minmax(60mm, max-content) 1fr !important; }',
|
|
484
|
+
'.spread-3 .head { overflow: visible !important; }',
|
|
485
|
+
# spread-2: bottom strip fixed at 56mm. Same treatment.
|
|
486
|
+
'.spread-2 { grid-template-rows: 1fr minmax(56mm, max-content) !important; }',
|
|
487
|
+
# Other spreads use auto 1fr or auto auto already — no loosening needed.
|
|
488
|
+
]
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
If a future template revision adds another fixed-height heading row, the entry is added here. The substitute step's `emit_overlay()` always emits these two sections first, then the per-role recipes.
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
### Where the overlay lands
|
|
495
|
+
|
|
496
|
+
The template's main `<style>` ends with the sentinel line:
|
|
497
|
+
|
|
498
|
+
```html
|
|
499
|
+
/* BRAND_TYPE_ROLES_OVERRIDE_SLOT — branded register may inject role overrides here */
|
|
500
|
+
</style>
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
The build replaces that sentinel comment with the emitted `<style id="brand-type-roles">…</style>` block (or with nothing if no role values are declared). The original `<style>` continues to its closing `</style>` immediately after. Both `brochure.html` and the landing page (`page.html` / `index.html`) carry the sentinel and receive the same overlay — the role API is global to the property's output.
|
|
504
|
+
|
|
505
|
+
### Verification
|
|
506
|
+
|
|
507
|
+
After the overlay is emitted, run a quick check:
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
grep -c 'id="brand-type-roles"' output/brochure.html output/web/page.html
|
|
511
|
+
# both must return 1 if the brand pack declared roles, 0 otherwise.
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
A branded run whose DESIGN.md declares `## Type roles` but whose rendered HTML lacks `id="brand-type-roles"` is **shipped broken** — the overlay step was skipped or failed silently.
|
|
515
|
+
|
|
@@ -13,17 +13,74 @@ The skill template ships with a default super-premium visual scheme. Two registe
|
|
|
13
13
|
|
|
14
14
|
| Register | What you change |
|
|
15
15
|
|---|---|
|
|
16
|
-
| **
|
|
17
|
-
| **
|
|
16
|
+
| **Branded** (default — full DESIGN.md re-skin) | Swap font names at the `--serif` / `--body-serif` / `--sans` custom properties; replace palette tokens (`--paper-25`, `--ink`, `--gold-500`, `--gold-700`, `--gold-300`, `--rule` etc.) with the DESIGN doc's values; **apply role-level type overrides from the DESIGN doc's `## Type roles` block** (see *Type-role overrides* below); substitute the brand's logo PNGs at the back-page masthead and TOC credit. The chapter structure (sixteen pages, Roman-numeral chapters, intermissions, gallery, site plan) stays — *layout, image slots, page geometry and folio chrome positions remain identical, only the styling of named type roles changes*. |
|
|
17
|
+
| **Premium** (opt-in only — template scheme retained) | Keep all super-premium tokens (palette, type, layout) verbatim. Swap **only** the agent's logo (back-page masthead + TOC credit) and the agent's contact details. Make subtle consistency adjustments — e.g. the accent dot in "Brand · Town" can pick up the brand's primary colour if doing so doesn't disrupt the ivory/ink/bronze relationship. **Do not apply the brand's palette or type tokens.** |
|
|
18
18
|
|
|
19
19
|
## Selecting the register — decide in this order
|
|
20
20
|
|
|
21
|
-
1. **The user said "premium" or "super-premium"** in the request → **Premium**, regardless of whether a DESIGN.md exists.
|
|
22
|
-
2. **
|
|
23
|
-
3. **Neither a DESIGN.md nor the word "premium"** → **Premium** (the template ships with super-premium defaults already in place).
|
|
21
|
+
1. **The user explicitly said "premium" or "super-premium"** in the request → **Premium**, regardless of whether a DESIGN.md exists.
|
|
22
|
+
2. **Otherwise → Branded.** If no DESIGN.md exists for the brand, **run `brand-design` first** to produce one — do not fall back to Premium just because the brand pack is missing. Premium is opt-in; "missing brand pack" is a setup step, not a register decision.
|
|
24
23
|
|
|
25
24
|
The signal is the user's wording, not the property. Don't infer premium from a high guide price or a country-house name when the user has handed over a DESIGN.md without qualifying language — the agent may want their brand on every brochure regardless of property tier. Conversely, when the user says "premium" but the property is plainly mid-market (a £450k semi, a city flat), surface the mismatch in one line ("Going premium register — confirm you want the country-folio look on this listing?") before generating, so the user can correct the wording rather than discover the mismatch in the rendered output.
|
|
26
25
|
|
|
26
|
+
## Type-role overrides
|
|
27
|
+
|
|
28
|
+
The branded register's font-family and palette swap alone produces a folio painted in the brand's colours but still wearing the template's editorial conventions — italic display, small-caps decks, gold hairlines under every heading, dropcap, italic emphasis on `<em>`. For brands whose live identity does not use those conventions (Cooper Adams' upright TrajanPro, eXp UK's Montserrat, Knight-Frank-adjacent vs corporate-residential), that's a mismatch. The brochure reads as a country-house folio with brand paint, not as a brand document.
|
|
29
|
+
|
|
30
|
+
To close the gap without leaving branded territory, the brand pack's `DESIGN.md` may declare a `## Type roles` block. Each row maps a named brochure type-role to a brand styling decision. The build pipeline reads these and emits a single override CSS block — see `build.md → Type-role overlay generation` for the recipe map.
|
|
31
|
+
|
|
32
|
+
The role API is **fixed and bounded**. Only the roles below may be overridden; the build does not invent selectors. Anything else stays at template defaults.
|
|
33
|
+
|
|
34
|
+
| Role | Targets (CSS selectors) | Allowed values |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `display-headline-style` | `.cover-title`, `.opener-title`, `.ed-headline`, `.chapter-head h3`, `.feature-page h3`, `.gallery-head h3`, `.siteplan-page h3`, `.toc-title`, `.back-headline`, `.mi-head h2`, `.mi-head h3` | `italic` (default) / `normal` |
|
|
37
|
+
| `display-em-style` | `<em>` inside the headline selectors above | `italic` (default) / `weight-shift` / `normal` |
|
|
38
|
+
| `display-letterspacing` | `.cover-title`, `.opener-title` | `wide` (default, ≈0.18em — tuned for Cormorant/didone) / `medium` (≈0.10em — humanist sans) / `tight` (≈0.04em — geometric sans) |
|
|
39
|
+
| `deck-family` | `.ed-deck`, `.feature-deck`, `.gallery-deck`, `.siteplan-deck` | `serif` (default) / `sans` |
|
|
40
|
+
| `deck-case` | same as `deck-family` | `caps-tracked` (default) / `sentence` |
|
|
41
|
+
| `eyebrow-family` | `.ed-eyebrow`, `.toc-eyebrow`, `.chapter-eyebrow`, `.ed-eyebrow-light` | `sans` (default — documented for explicitness) |
|
|
42
|
+
| `subtitle-family` | `.opener-title em`, `.cover-subtitle`, `.opener-spec` | `serif-smallcaps` (default) / `sans-tracked-caps` / `sans` |
|
|
43
|
+
| `caption-family` | `.ed-caption`, `.caption-pill`, `.caption-text`, `.img-caption`, `.photo-caption`, `.intermission .caption-pill` | `serif` (default) / `sans` |
|
|
44
|
+
| `caption-em-style` | `<em>` inside any caption selector | `italic` (default) / `weight-shift` / `normal` |
|
|
45
|
+
| `dropcap` | `.ed-body.dropcap::first-letter` | `gold` (default — italic serif in `--gold-700`) / `ink` (italic serif in `--ink`) / `ink-bold-sans` (bold sans in `--ink`, no italic) / `hidden` (neutralised — first letter inline at body size) |
|
|
46
|
+
| `hairline-rules` | `.ed-rule`, `.toc-rule` | `visible` (default) / `eyebrow-only` (rules beside eyebrows only, not under chapter heads) / `hidden` |
|
|
47
|
+
| `body-em-style` | `.ed-body em`, `.opener-body em`, `.opener-text em`, `.gallery-cell em`, `.siteplan-panel em`, `.spec-list li em`, `.mi-row em`, `.floorplan-lead em`, `.floorplan-sub em`, `.epc-caption em` | `italic` (default) / `weight-shift` / `normal` |
|
|
48
|
+
| `folio-em-style` | `.folio em`, `.folio .folio-mid em` | `italic` (default) / `weight-shift` / `normal` |
|
|
49
|
+
| `backpage-em-style` | `.back-headline em`, `.back-tagline em`, `.back-foot em`, `.back-contact-grid em`, `.back-rule em` | `italic-gold` (default) / `weight-shift` / `normal` |
|
|
50
|
+
|
|
51
|
+
### What the role API permits
|
|
52
|
+
|
|
53
|
+
Each `value` maps to a deterministic, named CSS recipe (the full map lives in `build.md → Type-role overlay generation`). For example:
|
|
54
|
+
|
|
55
|
+
- `display-em-style: weight-shift` → emits `{ font-style: normal !important; font-weight: 500 !important; }`
|
|
56
|
+
- `deck-family: sans` + `deck-case: sentence` → emits `{ font-family: var(--sans) !important; font-style: normal !important; letter-spacing: 0.02em !important; text-transform: none !important; }`
|
|
57
|
+
- `dropcap: hidden` → emits a `::first-letter` override that neutralises the float, size, color and font-family overrides from the template
|
|
58
|
+
|
|
59
|
+
### What the role API does NOT permit
|
|
60
|
+
|
|
61
|
+
- Changing page layout, grid structure, image slot positions, page count, folio position
|
|
62
|
+
- Adding new CSS classes or DOM elements
|
|
63
|
+
- Changing colour assignments (those belong to the palette tokens, not the role API)
|
|
64
|
+
- Restyling the back page's QR strip or contact grid layout
|
|
65
|
+
- Restyling the MI three-column grid layout
|
|
66
|
+
- Defining new roles ad hoc — the role list above is the complete API
|
|
67
|
+
|
|
68
|
+
A branded brochure must remain layout-identical to the premium brochure; only the *styling of named type roles* may differ.
|
|
69
|
+
|
|
70
|
+
### Backward compatibility
|
|
71
|
+
|
|
72
|
+
Existing brand packs whose `DESIGN.md` files do not contain a `## Type roles` block are **unaffected**. Omitted roles inherit template defaults — which match the template's current behaviour exactly. Two agents producing brochures for the same brand on different days produce identical results because the role list is fixed and the recipe per value is fixed.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Foundation: always-emit recipes
|
|
76
|
+
|
|
77
|
+
Two sections of the role overlay are emitted **whenever the brand pack declares any `## Type roles`**, regardless of which specific roles the operator chose. They are the foundation of any branded re-skin:
|
|
78
|
+
|
|
79
|
+
1. **Dark-surface protection.** A fixed exclusion list of selectors that sit on dark surfaces — the TOC hero caption pill, intermission caption pills, the spread-6 chapter-head overlay on its dark photo, the back-page masthead and tagline, and the back-page contact-grid name lines. The brand-token swap remaps `--gold-700` (the template's italic-emphasis colour) to the brand's accent. On a light surface that's correct. On a dark surface, a brand-accent like navy or maroon on dark photographic background is unreadable. The dark-surface protection forces text on these selectors to `var(--paper-25)` and emphasis to `var(--gold-300)` (the brand's accent / highlight). This is **not** a per-implementer concern — the exclusion list is fixed in `build.md → Always-emit recipes`.
|
|
80
|
+
2. **Structural clamp loosen.** The template's chapter-heading rows in `.spread-2` and `.spread-3` are sized for the Cormorant Garamond display setup (italic, weight 400, didone-tuned letter-spacing). When the role overlay changes display family, weight, or letter-spacing, headings can grow a few millimetres beyond what those fixed-height rows accommodate, and the template's `overflow: hidden` clips the descenders. The clamp-loosen recipe converts the affected rows to `minmax(<original>, max-content)` and lifts the heading-row `overflow` from `hidden` to `visible`. A heading that already fits renders identically; a heading that needs a few extra mm no longer clips. If a future template revision adds another fixed-height heading row, the entry is added in `build.md` — not handwritten per property.
|
|
81
|
+
|
|
82
|
+
A branded brochure built with the role overlay must show both blocks in the emitted `<style id="brand-type-roles">`. Their absence is a build-time defect, not a stylistic choice.
|
|
83
|
+
|
|
27
84
|
## Forbidden template sources
|
|
28
85
|
|
|
29
86
|
**Do not** start from any of the following, even when they exist in the same brand workspace and look "more on-brand" than the skill template:
|
|
@@ -31,9 +88,9 @@ The signal is the user's wording, not the property. Don't infer premium from a h
|
|
|
31
88
|
- `<brand>/properties/<other-listing>/output/brochure.html` — a sibling property's rendered brochure
|
|
32
89
|
- A previous brochure that was hand-edited after the last template release
|
|
33
90
|
- A "brand brochure" or "marketing PDF" supplied by the agency
|
|
34
|
-
- An older version of `template.html` cached anywhere outside `~/.claude/plugins/
|
|
91
|
+
- An older version of `template.html` cached anywhere outside `~/.claude/plugins/property-brochure/skills/property-brochure/references/`
|
|
35
92
|
|
|
36
|
-
Sibling brochures contain property-specific copy edits, hand-tuned image positions, ad-hoc CSS overrides, and drift from the canonical layout. Starting from one bakes that drift into the new brochure and silently diverges every property's structure over time. The DESIGN doc supplies design **tokens** (fonts, palette, voice) — it does not authorise reaching for an existing brochure as a starting point.
|
|
93
|
+
Sibling brochures contain property-specific copy edits, hand-tuned image positions, ad-hoc CSS overrides, and drift from the canonical layout. Starting from one bakes that drift into the new brochure and silently diverges every property's structure over time. The DESIGN doc supplies design **tokens** (fonts, palette, voice) and **role declarations** — it does not authorise reaching for an existing brochure as a starting point.
|
|
37
94
|
|
|
38
95
|
If the canonical `references/template.html` looks wrong for the brand, the right action is to **patch the template** (open a discussion with the user about what to change), not to substitute a different starting point for one run.
|
|
39
96
|
|
|
@@ -44,4 +101,4 @@ If the canonical `references/template.html` looks wrong for the brand, the right
|
|
|
44
101
|
- Adding new pages, removing pages, or merging spreads to "look more like" the brand's website
|
|
45
102
|
- Importing CSS from the brand's website into the brochure to "match the live experience"
|
|
46
103
|
|
|
47
|
-
If a branded re-skin is genuinely incompatible with the sixteen-page editorial folio (rare — most brands sit happily in this structure with token swaps), surface that to the user before generating anything. Don't unilaterally substitute structure. Any alternative count must still be **even** — see `a4-print-documents` → Even-page count for duplex printing.
|
|
104
|
+
If a branded re-skin is genuinely incompatible with the sixteen-page editorial folio (rare — most brands sit happily in this structure with token swaps plus role overrides), surface that to the user before generating anything. Don't unilaterally substitute structure. Any alternative count must still be **even** — see `a4-print-documents` → Even-page count for duplex printing.
|
|
@@ -1008,74 +1008,48 @@ async function loadUserProfile(accountId, userId, conversationId) {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
}
|
|
1010
1010
|
function formatProfileSummary(profile, preferences, extraTemplates = {}) {
|
|
1011
|
+
const summary = composeOperatorSummary(profile, preferences);
|
|
1012
|
+
return [
|
|
1013
|
+
`This is what you know about the operator: ${summary}.`,
|
|
1014
|
+
`You must seek to MAXIMISE what you know about the operator to do your job effectively.`
|
|
1015
|
+
].join("\n");
|
|
1016
|
+
}
|
|
1017
|
+
function composeOperatorSummary(profile, preferences) {
|
|
1018
|
+
const facts = [];
|
|
1011
1019
|
const givenName = typeof profile.givenName === "string" ? profile.givenName.trim() : "";
|
|
1012
1020
|
const familyName = typeof profile.familyName === "string" ? profile.familyName.trim() : "";
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const locale = profile.locale ? `, ${profile.locale}` : "";
|
|
1018
|
-
const expertise = profile.expertise ? `
|
|
1019
|
-
Expertise: ${typeof profile.expertise === "string" ? profile.expertise : JSON.stringify(profile.expertise)}` : "";
|
|
1020
|
-
const lines = [`## About the Owner
|
|
1021
|
-
`];
|
|
1022
|
-
lines.push(`${name}${role}${tz}${locale}${expertise}
|
|
1023
|
-
`);
|
|
1024
|
-
const categories = {};
|
|
1025
|
-
for (const pref of preferences) {
|
|
1026
|
-
if (pref.notApplicable === true) continue;
|
|
1027
|
-
if (!categories[pref.category]) categories[pref.category] = [];
|
|
1028
|
-
categories[pref.category].push(pref);
|
|
1021
|
+
const fullName = [givenName, familyName].filter((s) => s.length > 0).join(" ");
|
|
1022
|
+
if (fullName) facts.push(`name ${fullName}`);
|
|
1023
|
+
if (typeof profile.role === "string" && profile.role.trim()) {
|
|
1024
|
+
facts.push(`role ${profile.role.trim()}`);
|
|
1029
1025
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
scheduling: "Scheduling",
|
|
1033
|
-
decision: "Decisions",
|
|
1034
|
-
workflow: "Workflow",
|
|
1035
|
-
content: "Content",
|
|
1036
|
-
interaction: "Interaction patterns"
|
|
1037
|
-
};
|
|
1038
|
-
const workCategories = ["communication", "scheduling", "decision", "workflow", "content"];
|
|
1039
|
-
const workPrefs = workCategories.filter((c) => categories[c]);
|
|
1040
|
-
if (workPrefs.length > 0) {
|
|
1041
|
-
lines.push(`### How they work`);
|
|
1042
|
-
for (const cat of workPrefs) {
|
|
1043
|
-
const label = categoryLabels[cat] || cat;
|
|
1044
|
-
const items = categories[cat].map((p) => p.value).join("; ");
|
|
1045
|
-
lines.push(`- ${label}: ${items}`);
|
|
1046
|
-
}
|
|
1047
|
-
lines.push("");
|
|
1026
|
+
if (typeof profile.timezone === "string" && profile.timezone.trim()) {
|
|
1027
|
+
facts.push(`timezone ${profile.timezone.trim()}`);
|
|
1048
1028
|
}
|
|
1049
|
-
if (
|
|
1050
|
-
|
|
1051
|
-
for (const pref of categories.interaction) {
|
|
1052
|
-
lines.push(`- ${pref.value}`);
|
|
1053
|
-
}
|
|
1054
|
-
lines.push("");
|
|
1029
|
+
if (typeof profile.locale === "string" && profile.locale.trim()) {
|
|
1030
|
+
facts.push(`locale ${profile.locale.trim()}`);
|
|
1055
1031
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
{
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1032
|
+
if (typeof profile.email === "string" && profile.email.trim()) {
|
|
1033
|
+
facts.push(`email ${profile.email.trim()}`);
|
|
1034
|
+
}
|
|
1035
|
+
if (typeof profile.telephone === "string" && profile.telephone.trim()) {
|
|
1036
|
+
facts.push(`telephone ${profile.telephone.trim()}`);
|
|
1037
|
+
}
|
|
1038
|
+
if (profile.expertise) {
|
|
1039
|
+
const expVal = typeof profile.expertise === "string" ? profile.expertise : JSON.stringify(profile.expertise);
|
|
1040
|
+
if (expVal.trim()) facts.push(`expertise ${expVal.trim()}`);
|
|
1041
|
+
}
|
|
1042
|
+
const byCategory = {};
|
|
1043
|
+
for (const pref of preferences) {
|
|
1044
|
+
if (pref.notApplicable === true) continue;
|
|
1045
|
+
if (typeof pref.value !== "string" || pref.value.trim().length === 0) continue;
|
|
1046
|
+
if (!byCategory[pref.category]) byCategory[pref.category] = [];
|
|
1047
|
+
byCategory[pref.category].push(pref.value.trim());
|
|
1071
1048
|
}
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
lines.push(`### Coverage`);
|
|
1075
|
-
lines.push(`Missing: ${absentFields.join(", ")}`);
|
|
1076
|
-
lines.push("");
|
|
1049
|
+
for (const [cat, vals] of Object.entries(byCategory)) {
|
|
1050
|
+
facts.push(`${cat} ${vals.join(", ")}`);
|
|
1077
1051
|
}
|
|
1078
|
-
return
|
|
1052
|
+
return facts.length > 0 ? facts.join("; ") : "NOTHING";
|
|
1079
1053
|
}
|
|
1080
1054
|
var RECENT_FAILURES_TAIL_BYTES = 10 * 1024;
|
|
1081
1055
|
var AGENT_FILE_ROLES = [
|
package/payload/server/{cloudflare-task-tracker-TL6R364J.js → cloudflare-task-tracker-PZBX7X3D.js}
RENAMED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
readTunnelState,
|
|
8
8
|
recoverRunningCloudflareTasks,
|
|
9
9
|
resolveUnitGoneVerdict
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-ITQ55PCQ.js";
|
|
11
|
+
import "./chunk-VGMVEYX7.js";
|
|
12
12
|
import "./chunk-JSBRDJBE.js";
|
|
13
13
|
export {
|
|
14
14
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|