@cmo-so/cli 0.12.8 → 0.12.10
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/cmo.mjs +200 -21
- package/package.json +1 -1
package/dist/cmo.mjs
CHANGED
|
@@ -14658,6 +14658,54 @@ function replace(blocks, ref, next, synced = {}) {
|
|
|
14658
14658
|
function sectionAt(blocks, ref, synced = {}) {
|
|
14659
14659
|
return pick(locate(blocks), ref, synced);
|
|
14660
14660
|
}
|
|
14661
|
+
function widthValue(width) {
|
|
14662
|
+
const w = String(width ?? "").trim();
|
|
14663
|
+
if (w === "content") return null;
|
|
14664
|
+
if (w === "wide") return "var(--wp--style--global--wide-size)";
|
|
14665
|
+
if (/^\d{2,4}(\.\d+)?(px|rem|em|vw|%)$/.test(w)) return w;
|
|
14666
|
+
throw new Error('width: "content", "wide" or a CSS length such as 1240px.');
|
|
14667
|
+
}
|
|
14668
|
+
var NARROW_PX = 700;
|
|
14669
|
+
var sizePx = (v) => {
|
|
14670
|
+
const m = /^(\d+(?:\.\d+)?)(px|rem|em)$/.exec(v);
|
|
14671
|
+
return m ? Number(m[1]) * (m[2] === "px" ? 1 : 16) : null;
|
|
14672
|
+
};
|
|
14673
|
+
function setSectionWidth(b, width) {
|
|
14674
|
+
const size = widthValue(width);
|
|
14675
|
+
const before = [];
|
|
14676
|
+
const visit = (x, top) => {
|
|
14677
|
+
let changed = false;
|
|
14678
|
+
for (const c of x.inner) if (visit(c, false)) changed = true;
|
|
14679
|
+
const lay = x.attrs.layout;
|
|
14680
|
+
const constrained = lay?.type === "constrained";
|
|
14681
|
+
const cur = lay?.contentSize;
|
|
14682
|
+
const px = cur ? sizePx(cur) : null;
|
|
14683
|
+
const eligible = constrained && (!cur || cur.includes("--wp--style--global") || px == null || px >= NARROW_PX);
|
|
14684
|
+
if (eligible || top && !lay && (x.name === "core/group" || x.name === "core/cover")) {
|
|
14685
|
+
if ((cur ?? null) !== size) {
|
|
14686
|
+
before.push(cur ?? "content");
|
|
14687
|
+
const next = { ...lay ?? {}, type: "constrained" };
|
|
14688
|
+
if (size) next.contentSize = size;
|
|
14689
|
+
else delete next.contentSize;
|
|
14690
|
+
x.attrs = { ...x.attrs, layout: next };
|
|
14691
|
+
changed = true;
|
|
14692
|
+
}
|
|
14693
|
+
}
|
|
14694
|
+
if (changed) delete x.raw;
|
|
14695
|
+
return changed;
|
|
14696
|
+
};
|
|
14697
|
+
visit(b, true);
|
|
14698
|
+
return { containers: before.length, before };
|
|
14699
|
+
}
|
|
14700
|
+
function refreshRaw(list3) {
|
|
14701
|
+
let any = false;
|
|
14702
|
+
for (const b of list3) {
|
|
14703
|
+
const inner = refreshRaw(b.inner);
|
|
14704
|
+
if (inner) delete b.raw;
|
|
14705
|
+
if (inner || b.raw == null) any = true;
|
|
14706
|
+
}
|
|
14707
|
+
return any;
|
|
14708
|
+
}
|
|
14661
14709
|
var escRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14662
14710
|
function applyEdits(b, e) {
|
|
14663
14711
|
let m = serializeBlock(b);
|
|
@@ -15195,6 +15243,15 @@ async function styleGet(site) {
|
|
|
15195
15243
|
fonts: (user.settings?.typography?.fontFamilies?.theme ?? []).map((f) => f.slug)
|
|
15196
15244
|
},
|
|
15197
15245
|
contrast: contrastReport(Object.fromEntries([...palette.values()].map((c) => [c.slug, c.color]))),
|
|
15246
|
+
layout: {
|
|
15247
|
+
content: user.settings?.layout?.contentSize ?? base.settings?.layout?.contentSize ?? null,
|
|
15248
|
+
wide: user.settings?.layout?.wideSize ?? base.settings?.layout?.wideSize ?? null,
|
|
15249
|
+
padding: {
|
|
15250
|
+
left: user.styles?.spacing?.padding?.left ?? base.styles?.spacing?.padding?.left ?? null,
|
|
15251
|
+
right: user.styles?.spacing?.padding?.right ?? base.styles?.spacing?.padding?.right ?? null
|
|
15252
|
+
}
|
|
15253
|
+
},
|
|
15254
|
+
css: user.styles?.css ?? "",
|
|
15198
15255
|
_palette: [...palette.values()],
|
|
15199
15256
|
_fonts: [...fonts.values()],
|
|
15200
15257
|
_user: user
|
|
@@ -15235,6 +15292,17 @@ function contrastReport(colors) {
|
|
|
15235
15292
|
});
|
|
15236
15293
|
}
|
|
15237
15294
|
async function styleSet(site, change, force = false) {
|
|
15295
|
+
const len = (v, what) => {
|
|
15296
|
+
const t = String(v ?? "").trim();
|
|
15297
|
+
if (!/^(0|\d{1,4}(\.\d+)?(px|rem|em|vw|%)|var\(--wp--preset--spacing--[a-z0-9-]+\)|clamp\([0-9a-z.,%+\-\s()]+\))$/i.test(
|
|
15298
|
+
t
|
|
15299
|
+
))
|
|
15300
|
+
throw new Error(`${what}: "${t}" isn't a CSS length like 1240px, 2rem or var(--wp--preset--spacing--50).`);
|
|
15301
|
+
return t;
|
|
15302
|
+
};
|
|
15303
|
+
for (const css of [change.css, change.css_append])
|
|
15304
|
+
if (css != null && /<\/?style|<\?|<script|@import\s+url\(\s*['"]?(?!https:)/i.test(css))
|
|
15305
|
+
throw new Error("css: plain CSS only (no <style>, <script>, PHP or non-https imports).");
|
|
15238
15306
|
const cur = await styleGet(site);
|
|
15239
15307
|
const palette = cur._palette.map((c) => ({ ...c }));
|
|
15240
15308
|
for (const [slug, color] of Object.entries(change.colors ?? {})) {
|
|
@@ -15259,15 +15327,48 @@ async function styleSet(site, change, force = false) {
|
|
|
15259
15327
|
);
|
|
15260
15328
|
const user = cur._user;
|
|
15261
15329
|
const settings2 = { ...user.settings ?? {} };
|
|
15330
|
+
const styles = { ...user.styles ?? {} };
|
|
15262
15331
|
if (change.colors) settings2.color = { ...settings2.color ?? {}, palette: { theme: palette } };
|
|
15263
15332
|
if (change.fonts)
|
|
15264
15333
|
settings2.typography = { ...settings2.typography ?? {}, fontFamilies: { theme: fonts } };
|
|
15334
|
+
if (change.layout) {
|
|
15335
|
+
const layout = { ...settings2.layout ?? {} };
|
|
15336
|
+
if (change.layout.content != null) layout.contentSize = len(change.layout.content, "layout.content");
|
|
15337
|
+
if (change.layout.wide != null) layout.wideSize = len(change.layout.wide, "layout.wide");
|
|
15338
|
+
settings2.layout = layout;
|
|
15339
|
+
}
|
|
15340
|
+
if (change.padding) {
|
|
15341
|
+
const spacing = { ...styles.spacing ?? {} };
|
|
15342
|
+
const pad = { ...spacing.padding ?? {} };
|
|
15343
|
+
if (change.padding.left != null) pad.left = len(change.padding.left, "padding.left");
|
|
15344
|
+
if (change.padding.right != null) pad.right = len(change.padding.right, "padding.right");
|
|
15345
|
+
styles.spacing = { ...spacing, padding: pad };
|
|
15346
|
+
settings2.useRootPaddingAwareAlignments = true;
|
|
15347
|
+
}
|
|
15348
|
+
if (change.css != null) styles.css = change.css;
|
|
15349
|
+
if (change.css_append)
|
|
15350
|
+
styles.css = `${String(styles.css ?? "").trimEnd()}
|
|
15351
|
+
|
|
15352
|
+
${change.css_append.trim()}
|
|
15353
|
+
`.trimStart();
|
|
15265
15354
|
await call(site, {
|
|
15266
15355
|
method: "POST",
|
|
15267
15356
|
path: `/wp/v2/global-styles/${cur.id}`,
|
|
15268
|
-
body: { settings: settings2, styles
|
|
15357
|
+
body: { settings: settings2, styles }
|
|
15269
15358
|
});
|
|
15359
|
+
const changedLayout = change.layout || change.padding;
|
|
15270
15360
|
return {
|
|
15361
|
+
...changedLayout ? {
|
|
15362
|
+
layout: {
|
|
15363
|
+
before: cur.layout,
|
|
15364
|
+
after: {
|
|
15365
|
+
content: settings2.layout?.contentSize ?? cur.layout.content,
|
|
15366
|
+
wide: settings2.layout?.wideSize ?? cur.layout.wide,
|
|
15367
|
+
padding: change.padding ? { ...cur.layout.padding, ...change.padding } : cur.layout.padding
|
|
15368
|
+
}
|
|
15369
|
+
}
|
|
15370
|
+
} : {},
|
|
15371
|
+
...change.css != null || change.css_append ? { css: { before: cur.css.length, after: String(styles.css ?? "").length, before_text: cur.css } } : {},
|
|
15271
15372
|
colors: Object.fromEntries(
|
|
15272
15373
|
Object.entries(change.colors ?? {}).map(([k, v]) => [k, { before: cur.colors[k], after: v }])
|
|
15273
15374
|
),
|
|
@@ -16386,7 +16487,7 @@ var siteTools = [
|
|
|
16386
16487
|
}),
|
|
16387
16488
|
tool({
|
|
16388
16489
|
name: "wp_style_get",
|
|
16389
|
-
description: "The
|
|
16490
|
+
description: "The site's look: colours (by name: canvas, panel, soft, ink, muted, olive, accent\u2026), fonts (display, body), layout widths (content, wide) and page padding, the extra CSS, and the text contrast of each colour pair.",
|
|
16390
16491
|
parameters: { type: "object", properties: {} },
|
|
16391
16492
|
group: "site",
|
|
16392
16493
|
need: READ,
|
|
@@ -16394,7 +16495,14 @@ var siteTools = [
|
|
|
16394
16495
|
gates: ["WP"],
|
|
16395
16496
|
run: async (ctx) => {
|
|
16396
16497
|
const s = await styleGet(siteOf(ctx));
|
|
16397
|
-
return {
|
|
16498
|
+
return {
|
|
16499
|
+
colors: s.colors,
|
|
16500
|
+
fonts: s.fonts,
|
|
16501
|
+
layout: s.layout,
|
|
16502
|
+
css: s.css,
|
|
16503
|
+
customized: s.customized,
|
|
16504
|
+
contrast: s.contrast
|
|
16505
|
+
};
|
|
16398
16506
|
}
|
|
16399
16507
|
})
|
|
16400
16508
|
];
|
|
@@ -16836,12 +16944,15 @@ var sectionTools = [
|
|
|
16836
16944
|
}),
|
|
16837
16945
|
tool({
|
|
16838
16946
|
name: "wp_section_update",
|
|
16839
|
-
description:
|
|
16947
|
+
description: 'Change one section. width: line its content up with the header and footer ("wide") or another width, one section or all. edits: change text, links or pictures inside it and keep its design (works on any section, the homepage too). slots: write the section again from new content (generated types; give the complete content). faq: add, remove (1-based numbers) or replace questions.',
|
|
16840
16948
|
parameters: {
|
|
16841
16949
|
type: "object",
|
|
16842
16950
|
properties: {
|
|
16843
16951
|
page: PAGE,
|
|
16844
|
-
section: str2(
|
|
16952
|
+
section: str2('Section id from wp_page_get (s2, m4) or its type (faq); "all" with width only.'),
|
|
16953
|
+
width: str2(
|
|
16954
|
+
`The section's inner width: "content" (the site's content width), "wide" (the site's wide width, as the header and footer) or a CSS length (1240px). Changes the section and its containers wider than 700px; with section "all", every section on the page.`
|
|
16955
|
+
),
|
|
16845
16956
|
edits: EDITS,
|
|
16846
16957
|
slots: obj("Complete new content for the section (same type unless type is given)."),
|
|
16847
16958
|
markup: str2(
|
|
@@ -16870,6 +16981,19 @@ var sectionTools = [
|
|
|
16870
16981
|
),
|
|
16871
16982
|
run: (ctx, a) => changePage(ctx, a, (blocks, kit) => {
|
|
16872
16983
|
const ref = String(a.section);
|
|
16984
|
+
if (a.width != null && a.width !== "") {
|
|
16985
|
+
const targets = ref === "all" ? locate(blocks) : [sectionAt(blocks, ref, kit.syncedTitles)];
|
|
16986
|
+
const changed = {};
|
|
16987
|
+
for (const t of targets) {
|
|
16988
|
+
if (t.block.name === "core/block") continue;
|
|
16989
|
+
const r = setSectionWidth(t.block, a.width);
|
|
16990
|
+
if (r.containers) changed[t.id] = r;
|
|
16991
|
+
}
|
|
16992
|
+
refreshRaw(blocks);
|
|
16993
|
+
if (!Object.keys(changed).length) throw new Error("Those sections already have that width.");
|
|
16994
|
+
return { blocks, note: { width: String(a.width), sections: changed } };
|
|
16995
|
+
}
|
|
16996
|
+
if (ref === "all") throw new Error('section "all" works with width only.');
|
|
16873
16997
|
const target = sectionAt(blocks, ref, kit.syncedTitles);
|
|
16874
16998
|
const type = classify(target.block, target.region, kit.syncedTitles);
|
|
16875
16999
|
let next;
|
|
@@ -17236,7 +17360,7 @@ var childTools = [
|
|
|
17236
17360
|
}),
|
|
17237
17361
|
tool({
|
|
17238
17362
|
name: "wp_child_theme_update",
|
|
17239
|
-
description: "Change a Maggie child theme's files (default: the active child): brand colours (by name, hex) and fonts (by name, CSS font-family of fonts already in it) in theme.json, extra theme.json styles, plain CSS (replace or append), the header or footer (block markup), templates, and the site's own patterns (shown in the editor's inserter).
|
|
17363
|
+
description: "Change a Maggie child theme's files (default: the active child): brand colours (by name, hex) and fonts (by name, CSS font-family of fonts already in it) in theme.json, extra theme.json styles, plain CSS (replace or append), the site's own JavaScript (assets/js/site.js, replace or append; runs for every visitor), the header or footer (block markup), templates, and the site's own patterns (shown in the editor's inserter). No PHP or server code. Each change keeps a backup (wp_child_theme_restore). Changes made with wp_style_set / wp_header_set are stored in the database and win over the child's files.",
|
|
17240
17364
|
parameters: {
|
|
17241
17365
|
type: "object",
|
|
17242
17366
|
properties: {
|
|
@@ -17257,6 +17381,10 @@ var childTools = [
|
|
|
17257
17381
|
styles: obj('theme.json styles to merge in (e.g. { "elements": { "button": { \u2026 } } }).'),
|
|
17258
17382
|
css: str2("Replace the child's CSS (plain CSS)."),
|
|
17259
17383
|
css_append: str2("Add CSS at the end."),
|
|
17384
|
+
js: str2(
|
|
17385
|
+
`Replace the site's own script (assets/js/site.js, plain JavaScript loaded deferred on every page; "" turns it off). Needs Maggie Core 0.12+ and a login allowed to add scripts. No eval or new Function; addresses only on the site or cdn.jsdelivr.net, unpkg.com, cdnjs.cloudflare.com.`
|
|
17386
|
+
),
|
|
17387
|
+
js_append: str2("Add JavaScript at the end of the site's script."),
|
|
17260
17388
|
header: str2("Header block markup (parts/header.html)."),
|
|
17261
17389
|
footer: str2("Footer block markup (parts/footer.html)."),
|
|
17262
17390
|
templates: obj('Templates by slug \u2192 block markup, e.g. { "page-landing": "\u2026" }.'),
|
|
@@ -17270,8 +17398,8 @@ var childTools = [
|
|
|
17270
17398
|
gates: [...GATES],
|
|
17271
17399
|
confirm: (a, lang) => say(
|
|
17272
17400
|
lang,
|
|
17273
|
-
`Change the child theme ${q2(a.slug, "(the active one)")} on your website
|
|
17274
|
-
`\u4FEE\u6539\u7DB2\u7AD9\u7684\u5B50\u4E3B\u984C ${q2(a.slug, "\uFF08\u76EE\u524D\u4F7F\u7528\u4E2D\u7684\uFF09")}\u3002`
|
|
17401
|
+
`Change the child theme ${q2(a.slug, "(the active one)")} on your website.${typeof a.js === "string" || typeof a.js_append === "string" ? a.js === "" ? " Turns off the site's own script." : " Includes JavaScript that runs in every visitor's browser on every page." : ""}`,
|
|
17402
|
+
`\u4FEE\u6539\u7DB2\u7AD9\u7684\u5B50\u4E3B\u984C ${q2(a.slug, "\uFF08\u76EE\u524D\u4F7F\u7528\u4E2D\u7684\uFF09")}\u3002${typeof a.js === "string" || typeof a.js_append === "string" ? a.js === "" ? "\u95DC\u9589\u7DB2\u7AD9\u81EA\u8A02\u8173\u672C\u3002" : "\u5305\u542B\u6703\u5728\u6BCF\u4F4D\u8A2A\u5BA2\u700F\u89BD\u5668\u3001\u6BCF\u500B\u9801\u9762\u57F7\u884C\u7684 JavaScript\u3002" : ""}`
|
|
17275
17403
|
),
|
|
17276
17404
|
run: async (ctx, a) => {
|
|
17277
17405
|
const site = siteOf(ctx);
|
|
@@ -17369,6 +17497,22 @@ var childTools = [
|
|
|
17369
17497
|
if (typeof a.css_append === "string")
|
|
17370
17498
|
files["style.css"] = `${(files["style.css"] ?? cur["style.css"] ?? "").replace(/\n*$/, "\n")}${a.css_append}
|
|
17371
17499
|
`;
|
|
17500
|
+
if (typeof a.js === "string" || typeof a.js_append === "string") {
|
|
17501
|
+
const parentV = String(info.parent?.version ?? "0");
|
|
17502
|
+
const [maj, min] = parentV.split(".").map(Number);
|
|
17503
|
+
if ((maj ?? 0) === 0 && (min ?? 0) < 12)
|
|
17504
|
+
throw new Error(
|
|
17505
|
+
`The site's script needs Maggie Core 0.12 or later (the site has ${parentV}): update it with wp_theme_update first.`
|
|
17506
|
+
);
|
|
17507
|
+
const js = typeof a.js === "string" ? a.js : `${(cur["assets/js/site.js"] ?? "").replace(/\n*$/, "\n")}${String(a.js_append)}
|
|
17508
|
+
`.trimStart();
|
|
17509
|
+
if (/<\/?script\b/i.test(js)) throw new Error("js: plain JavaScript only, no <script> tags.");
|
|
17510
|
+
if (/<\?(php|=)?/i.test(js)) throw new Error("js: PHP isn't allowed.");
|
|
17511
|
+
files["assets/js/site.js"] = js;
|
|
17512
|
+
notes.push(
|
|
17513
|
+
js.trim() ? "assets/js/site.js runs deferred on every page; undo with wp_child_theme_restore." : "The site's own script is off."
|
|
17514
|
+
);
|
|
17515
|
+
}
|
|
17372
17516
|
const markup = (path3, m) => {
|
|
17373
17517
|
if (typeof m !== "string" || !m.trim()) return;
|
|
17374
17518
|
if (!parse(m).some((b) => b.name)) throw new Error(`${path3}: give block markup (<!-- wp:\u2026 -->).`);
|
|
@@ -17775,23 +17919,41 @@ var elementTools = [
|
|
|
17775
17919
|
}),
|
|
17776
17920
|
tool({
|
|
17777
17921
|
name: "wp_style_set",
|
|
17778
|
-
description: "Change brand colours (by name, hex)
|
|
17922
|
+
description: "Change the whole site's look: brand colours (by name, hex), fonts (by name, CSS font-family), layout widths (content: the width sections and text use; wide: the header, footer and wide blocks), the left and right page padding, and extra CSS. Saved in the site's Global Styles (works on any block theme; returns before and after). Refuses colours that would make text hard to read (contrast under 4.5:1). One section's width: wp_section_update width.",
|
|
17779
17923
|
parameters: {
|
|
17780
17924
|
type: "object",
|
|
17781
17925
|
properties: {
|
|
17782
17926
|
colors: obj('e.g. { "olive": "#4F5B48", "accent": "#A8834F" }.'),
|
|
17783
|
-
fonts: obj('e.g. { "display": "\\"Playfair Display\\", Georgia, serif" }.')
|
|
17927
|
+
fonts: obj('e.g. { "display": "\\"Playfair Display\\", Georgia, serif" }.'),
|
|
17928
|
+
layout: obj('Widths, e.g. { "content": "1240px", "wide": "1240px" }.', {
|
|
17929
|
+
content: str2("Content width (CSS length)."),
|
|
17930
|
+
wide: str2("Wide width (CSS length).")
|
|
17931
|
+
}),
|
|
17932
|
+
padding: obj('Left and right page padding, e.g. { "left": "24px", "right": "24px" }.', {
|
|
17933
|
+
left: str2(""),
|
|
17934
|
+
right: str2("")
|
|
17935
|
+
}),
|
|
17936
|
+
css: str2("Replace the site's extra CSS (Global Styles \u2192 Additional CSS); plain CSS only."),
|
|
17937
|
+
css_append: str2("Add this CSS after the site's extra CSS.")
|
|
17784
17938
|
}
|
|
17785
17939
|
},
|
|
17786
17940
|
group: "site",
|
|
17787
17941
|
need: WRITE,
|
|
17788
17942
|
risk: "W3",
|
|
17789
17943
|
gates: [...GATES],
|
|
17790
|
-
confirm: (_a3, lang) => say(
|
|
17791
|
-
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17944
|
+
confirm: (_a3, lang) => say(
|
|
17945
|
+
lang,
|
|
17946
|
+
"Change the website's look for every page (colours, fonts, widths, padding or extra CSS); the result shows before and after.",
|
|
17947
|
+
"\u4FEE\u6539\u7DB2\u7AD9\u6240\u6709\u9801\u9762\u7684\u5916\u89C0\uFF08\u984F\u8272\u3001\u5B57\u9AD4\u3001\u5BEC\u5EA6\u3001\u908A\u8DDD\u6216\u984D\u5916 CSS\uFF09\uFF1B\u7D50\u679C\u6703\u5217\u51FA\u4FEE\u6539\u524D\u5F8C\u3002"
|
|
17948
|
+
),
|
|
17949
|
+
run: async (ctx, a) => styleSet(siteOf(ctx), {
|
|
17950
|
+
colors: a.colors,
|
|
17951
|
+
fonts: a.fonts,
|
|
17952
|
+
layout: a.layout,
|
|
17953
|
+
padding: a.padding,
|
|
17954
|
+
css: typeof a.css === "string" ? a.css : void 0,
|
|
17955
|
+
css_append: typeof a.css_append === "string" ? a.css_append : void 0
|
|
17956
|
+
})
|
|
17795
17957
|
})
|
|
17796
17958
|
];
|
|
17797
17959
|
function checkMarkup(markup, what) {
|
|
@@ -21766,7 +21928,7 @@ var program = new Command();
|
|
|
21766
21928
|
// package.json
|
|
21767
21929
|
var package_default = {
|
|
21768
21930
|
name: "@cmo-so/cli",
|
|
21769
|
-
version: "0.12.
|
|
21931
|
+
version: "0.12.10",
|
|
21770
21932
|
description: "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
21771
21933
|
type: "module",
|
|
21772
21934
|
license: "MIT",
|
|
@@ -32813,6 +32975,16 @@ function registerWp(program3) {
|
|
|
32813
32975
|
o.preview ? { tool: "wp_section_update", args } : args
|
|
32814
32976
|
);
|
|
32815
32977
|
});
|
|
32978
|
+
section.command("width <page> <section> <width>").description(
|
|
32979
|
+
'line sections up: width "wide" (as the header and footer), "content" or 1240px; section "all" = every section'
|
|
32980
|
+
).option("--preview", "show the result, save nothing").action(async (p, s, w, o, c) => {
|
|
32981
|
+
const args = { page: p, section: s, width: w };
|
|
32982
|
+
await run(
|
|
32983
|
+
g(c),
|
|
32984
|
+
o.preview ? "wp_preview" : "wp_section_update",
|
|
32985
|
+
o.preview ? { tool: "wp_section_update", args } : args
|
|
32986
|
+
);
|
|
32987
|
+
});
|
|
32816
32988
|
pos(section.command("move <page> <section>").description("move a section")).action(
|
|
32817
32989
|
(p, s, o, c) => run(g(c), "wp_section_move", { page: p, section: s, ...posArgs(o) })
|
|
32818
32990
|
);
|
|
@@ -32878,12 +33050,16 @@ ${table(r.issues, ["severity", "code", "path", "detail"])}`;
|
|
|
32878
33050
|
await run(g(c), part === "header" ? "wp_header_set" : "wp_footer_set", args);
|
|
32879
33051
|
});
|
|
32880
33052
|
}
|
|
32881
|
-
const style = wp.command("style").description("brand colours and
|
|
33053
|
+
const style = wp.command("style").description("brand colours, fonts, layout widths, page padding and extra CSS");
|
|
32882
33054
|
style.command("get", { isDefault: true }).action((_o, c) => run(g(c), "wp_style_get", {}));
|
|
32883
|
-
style.command("set [colors...]").description(`e.g. cmo wp style set olive=#4F5B48 --font 'display="Playfair Display", serif'`).option("--font <slug=family...>").action(
|
|
32884
|
-
(colors, o, c) => run(g(c), "wp_style_set", {
|
|
33055
|
+
style.command("set [colors...]").description(`e.g. cmo wp style set olive=#4F5B48 --font 'display="Playfair Display", serif'`).option("--font <slug=family...>").option("--content <width>", "content width, e.g. 1240px").option("--wide <width>", "wide width (header, footer, wide blocks)").option("--padding <length>", "left and right page padding, e.g. 24px").option("--css-file <file>", "replace the site's extra CSS with this file").option("--css-append <file>", "add this CSS file after the site's extra CSS").action(
|
|
33056
|
+
async (colors, o, c) => run(g(c), "wp_style_set", {
|
|
32885
33057
|
colors: colors.length ? Object.fromEntries(pairs(colors)) : void 0,
|
|
32886
|
-
fonts: o.font ? Object.fromEntries(pairs(o.font)) : void 0
|
|
33058
|
+
fonts: o.font ? Object.fromEntries(pairs(o.font)) : void 0,
|
|
33059
|
+
layout: o.content || o.wide ? { content: o.content, wide: o.wide } : void 0,
|
|
33060
|
+
padding: o.padding ? { left: o.padding, right: o.padding } : void 0,
|
|
33061
|
+
css: o.cssFile ? await readFile2(o.cssFile, "utf8") : void 0,
|
|
33062
|
+
css_append: o.cssAppend ? await readFile2(o.cssAppend, "utf8") : void 0
|
|
32887
33063
|
})
|
|
32888
33064
|
);
|
|
32889
33065
|
const media = wp.command("media").description("pictures in the media library");
|
|
@@ -33000,12 +33176,15 @@ ${table(r.issues, ["severity", "code", "path", "detail"])}`;
|
|
|
33000
33176
|
).option(
|
|
33001
33177
|
"--from <file>",
|
|
33002
33178
|
"JSON: { colors, fonts, styles, css, css_append, header, footer, templates, patterns, remove_patterns }"
|
|
33003
|
-
).option("--color <slug=hex...>").option("--css-file <file>", "replace the CSS with this file").option("--header-file <file>", "header block markup").option("--footer-file <file>", "footer block markup").action(
|
|
33179
|
+
).option("--color <slug=hex...>").option("--css-file <file>", "replace the CSS with this file").option("--js-file <file>", "replace the site's script (assets/js/site.js, runs on every page) with this file").option("--js-append <file>", "add this JavaScript file at the end of the site's script").option("--js-off", "turn the site's script off").option("--header-file <file>", "header block markup").option("--footer-file <file>", "footer block markup").action(
|
|
33004
33180
|
async (slug, o, c) => {
|
|
33005
33181
|
const args = o.from ? await json(o.from) : {};
|
|
33006
33182
|
if (slug) args.slug = slug;
|
|
33007
33183
|
if (o.color) args.colors = Object.fromEntries(pairs(o.color));
|
|
33008
33184
|
if (o.cssFile) args.css = await readFile2(o.cssFile, "utf8");
|
|
33185
|
+
if (o.jsFile) args.js = await readFile2(o.jsFile, "utf8");
|
|
33186
|
+
if (o.jsAppend) args.js_append = await readFile2(o.jsAppend, "utf8");
|
|
33187
|
+
if (o.jsOff) args.js = "";
|
|
33009
33188
|
if (o.headerFile) args.header = await readFile2(o.headerFile, "utf8");
|
|
33010
33189
|
if (o.footerFile) args.footer = await readFile2(o.footerFile, "utf8");
|
|
33011
33190
|
await run(g(c), "wp_child_theme_update", args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmo-so/cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.10",
|
|
4
4
|
"description": "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|