@omniharmonic/openspace-cli 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/{agents-md-PVK5NBFF.js → agents-md-Q2TI3NHB.js} +2 -2
  2. package/dist/bin.js +2 -2
  3. package/dist/{chunk-RG7S2MUH.js → chunk-7SWL46LQ.js} +106 -10
  4. package/dist/chunk-7SWL46LQ.js.map +1 -0
  5. package/dist/{chunk-UQXJVMUV.js → chunk-BW42R6WD.js} +494 -57
  6. package/dist/chunk-BW42R6WD.js.map +1 -0
  7. package/dist/index.js +2 -2
  8. package/dist/templates/atelier/content/pages/home.json +11 -11
  9. package/dist/templates/beacon/content/collections/news/2026-09-12-heat-map-2026.mdoc +2 -2
  10. package/dist/templates/beacon/content/collections/news/2026-09-30-school-gardens-harvest.mdoc +2 -2
  11. package/dist/templates/beacon/content/collections/news/2026-10-14-planting-season-begins.mdoc +2 -2
  12. package/dist/templates/beacon/content/pages/home.json +1 -1
  13. package/dist/templates/beacon/media/LICENSES.json +33 -0
  14. package/dist/templates/commons/content/pages/home.json +4 -4
  15. package/dist/templates/commons/content/site.json +1 -1
  16. package/dist/templates/commons/media/LICENSES.json +11 -11
  17. package/dist/templates/darkroom/content/collections/work/after-hours.mdoc +7 -4
  18. package/dist/templates/darkroom/content/collections/work/faces-of-the-guild.mdoc +10 -7
  19. package/dist/templates/darkroom/content/collections/work/first-light.mdoc +34 -0
  20. package/dist/templates/darkroom/content/pages/home.json +27 -15
  21. package/dist/templates/darkroom/media/LICENSES.json +82 -49
  22. package/dist/templates/encore/content/pages/home.json +8 -4
  23. package/dist/templates/encore/media/LICENSES.json +11 -0
  24. package/dist/templates/field-notes/content/collections/essays/a-year-of-apples.mdoc +2 -2
  25. package/dist/templates/field-notes/content/collections/essays/in-praise-of-dirt-roads.mdoc +27 -0
  26. package/dist/templates/field-notes/content/collections/essays/learning-a-field.mdoc +2 -2
  27. package/dist/templates/field-notes/content/collections/essays/the-barn-that-leans.mdoc +29 -0
  28. package/dist/templates/field-notes/content/collections/essays/the-wall-builders.mdoc +2 -2
  29. package/dist/templates/field-notes/content/pages/home.json +3 -3
  30. package/dist/templates/field-notes/media/LICENSES.json +55 -33
  31. package/dist/templates/gather/content/pages/home.json +25 -11
  32. package/dist/templates/harbor/content/collections/news/2026-09-15-meet-the-repair-crew.mdoc +2 -2
  33. package/dist/templates/harbor/content/pages/get-involved.json +1 -1
  34. package/dist/templates/harbor/content/pages/home.json +9 -5
  35. package/dist/templates/harbor/content/pages/programs.json +2 -2
  36. package/dist/templates/harbor/media/LICENSES.json +22 -0
  37. package/dist/templates/hearth/content/pages/home.json +17 -22
  38. package/dist/templates/hearth/media/LICENSES.json +22 -11
  39. package/dist/templates/kiln/content/collections/classes/glaze-day-march.mdoc +2 -2
  40. package/dist/templates/kiln/content/collections/classes/hand-building-february.mdoc +2 -2
  41. package/dist/templates/kiln/content/collections/classes/wheel-weekend-january.mdoc +2 -2
  42. package/dist/templates/kiln/content/pages/home.json +5 -5
  43. package/dist/templates/kiln/media/LICENSES.json +55 -0
  44. package/dist/templates/link/content/pages/home.json +35 -31
  45. package/dist/templates/link/media/LICENSES.json +25 -25
  46. package/dist/templates/meadow/content/collections/workshops/breath-and-rest-workshop.mdoc +2 -2
  47. package/dist/templates/meadow/media/LICENSES.json +11 -0
  48. package/dist/templates/orbit/content/pages/home.json +25 -11
  49. package/package.json +7 -7
  50. package/dist/chunk-RG7S2MUH.js.map +0 -1
  51. package/dist/chunk-UQXJVMUV.js.map +0 -1
  52. package/dist/templates/darkroom/content/collections/work/dry-season.mdoc +0 -28
  53. /package/dist/{agents-md-PVK5NBFF.js.map → agents-md-Q2TI3NHB.js.map} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { createRequire as __osCreateRequire } from "node:module"; const require = __osCreateRequire(import.meta.url);
2
2
  import {
3
3
  generateAgentsMd
4
- } from "./chunk-UQXJVMUV.js";
4
+ } from "./chunk-BW42R6WD.js";
5
5
  import "./chunk-26AZCID5.js";
6
6
  export {
7
7
  generateAgentsMd
8
8
  };
9
- //# sourceMappingURL=agents-md-PVK5NBFF.js.map
9
+ //# sourceMappingURL=agents-md-Q2TI3NHB.js.map
package/dist/bin.js CHANGED
@@ -3,9 +3,9 @@ import { createRequire as __osCreateRequire } from "node:module"; const require
3
3
  import {
4
4
  processIo,
5
5
  run
6
- } from "./chunk-RG7S2MUH.js";
6
+ } from "./chunk-7SWL46LQ.js";
7
7
  import "./chunk-WE4QCL3R.js";
8
- import "./chunk-UQXJVMUV.js";
8
+ import "./chunk-BW42R6WD.js";
9
9
  import "./chunk-26AZCID5.js";
10
10
 
11
11
  // src/bin.ts
@@ -50,6 +50,7 @@ import {
50
50
  MediaMetaSchema,
51
51
  MediaPathSchema,
52
52
  NavItemSchema,
53
+ PLACEHOLDER_RE,
53
54
  PRESET_CATEGORIES,
54
55
  PageIdSchema,
55
56
  PageSchema,
@@ -92,17 +93,19 @@ import {
92
93
  parseColor,
93
94
  plainText,
94
95
  presetCatalog,
96
+ presetSampleStrings,
95
97
  presetSection,
96
98
  presetsIn,
97
99
  registerAll,
98
100
  renderPageHtml,
99
101
  resolve,
100
102
  responsive,
103
+ sampleMatches,
101
104
  starterRef,
102
105
  toHex,
103
106
  toJsonSchema,
104
107
  toMarkdown
105
- } from "./chunk-UQXJVMUV.js";
108
+ } from "./chunk-BW42R6WD.js";
106
109
  import {
107
110
  __commonJS,
108
111
  __require,
@@ -12045,6 +12048,42 @@ var Ctx = class {
12045
12048
  this.primaryActions(page, section);
12046
12049
  this.copyLength(page, section);
12047
12050
  this.background(page, section);
12051
+ this.sampleContent(page, section);
12052
+ this.placeholders(page, section);
12053
+ }
12054
+ }
12055
+ /** Unedited preset sample content: made-up people, quotes, prices and contact details. */
12056
+ sampleContent(page, section) {
12057
+ if (!section.preset) return;
12058
+ const matches = sampleMatches(section, presetSampleStrings(section.preset));
12059
+ const first = matches[0];
12060
+ if (!first) return;
12061
+ const examples = matches.flatMap((m) => m.found).slice(0, 2).map((s2) => `\u201C${s2.length > 48 ? `${s2.slice(0, 47)}\u2026` : s2}\u201D`).join(", ");
12062
+ this.add({
12063
+ rule: "sample-content",
12064
+ severity: "warning",
12065
+ page,
12066
+ section: section.id,
12067
+ block: first.blockId,
12068
+ message: `This section still has sample content from its design (${examples}): people, quotes, prices or details that aren't about your site.`,
12069
+ fix: "Edit it with your own words, people and numbers \u2014 or delete the section. Never publish made-up reviews or names."
12070
+ });
12071
+ }
12072
+ /** Placeholder text left in: "[PLACEHOLDER]", "[Your name]", "Lorem ipsum". */
12073
+ placeholders(page, section) {
12074
+ for (const b of section.blocks) {
12075
+ if (b.hidden) continue;
12076
+ const m = PLACEHOLDER_RE.exec(blockText(b));
12077
+ if (!m) continue;
12078
+ this.add({
12079
+ rule: "placeholder-text",
12080
+ severity: "warning",
12081
+ page,
12082
+ section: section.id,
12083
+ block: b.id,
12084
+ message: `This block still has placeholder text (\u201C${m[0]}\u201D).`,
12085
+ fix: "Edit it to say what you mean, or remove it before publishing."
12086
+ });
12048
12087
  }
12049
12088
  }
12050
12089
  headings(page, sections) {
@@ -25029,6 +25068,8 @@ var getSite = defineTool({
25029
25068
  media: Object.keys(doc.media).length,
25030
25069
  capabilities: {
25031
25070
  ...ctx.store.capabilities,
25071
+ // Same answer as list_sites: publishing needs both the store and this connection.
25072
+ canPublish: ctx.grant.publish && ctx.store.capabilities.canPublish,
25032
25073
  grantPublish: ctx.grant.publish
25033
25074
  }
25034
25075
  }
@@ -26626,7 +26667,7 @@ var publish = defineTool({
26626
26667
  const siteId = await ctx.siteId(input.site);
26627
26668
  if (!ctx.grant.publish)
26628
26669
  throw new ToolError(
26629
- "This connection isn't allowed to publish. The owner can publish from Studio, or allow publishing for this connection.",
26670
+ "This connection isn't allowed to publish. Publish from Studio, or ask the site owner to allow publishing for this connection in Studio \u2192 Settings \u2192 Connect your AI.",
26630
26671
  "forbidden"
26631
26672
  );
26632
26673
  if (!ctx.store.capabilities.canPublish)
@@ -28227,7 +28268,7 @@ async function renderAgentsMd(root, siteTitle) {
28227
28268
  } catch {
28228
28269
  }
28229
28270
  }
28230
- const { generateAgentsMd: generateAgentsMd2 } = await import("./agents-md-PVK5NBFF.js");
28271
+ const { generateAgentsMd: generateAgentsMd2 } = await import("./agents-md-Q2TI3NHB.js");
28231
28272
  return generateAgentsMd2(title ? { siteTitle: title } : {});
28232
28273
  }
28233
28274
  async function writeAgentsMd(root, siteTitle) {
@@ -28262,6 +28303,11 @@ function compareVersions(a, b) {
28262
28303
 
28263
28304
  // src/dev.ts
28264
28305
  var ASTRO_MIN_NODE = "22.23.4";
28306
+ function astroNodeProblem(nodeVersion) {
28307
+ if (compareVersions(nodeVersion, ASTRO_MIN_NODE) >= 0) return null;
28308
+ return `Astro needs Node ${ASTRO_MIN_NODE} or newer (Node 24 recommended), but this is Node ${nodeVersion}.
28309
+ Install Node 24 (for example with nvm: "nvm install 24 && nvm use 24").`;
28310
+ }
28265
28311
  function findAstroBin(cwd) {
28266
28312
  try {
28267
28313
  const req = createRequire(join5(cwd, "package.json"));
@@ -28276,11 +28322,9 @@ function findAstroBin(cwd) {
28276
28322
  }
28277
28323
  }
28278
28324
  async function runDev(io, args, spawner = (c, a, o) => spawn(c, a, { ...o, stdio: "inherit" }), findBin = findAstroBin) {
28279
- if (compareVersions(io.nodeVersion, ASTRO_MIN_NODE) < 0)
28280
- throw new CliError(
28281
- `Astro needs Node ${ASTRO_MIN_NODE} or newer, but this is Node ${io.nodeVersion}.
28282
- Install a newer Node 22 (for example with nvm: "nvm install 22 && nvm use 22") and run "openspace dev" again.`
28283
- );
28325
+ const tooOld = astroNodeProblem(io.nodeVersion);
28326
+ if (tooOld) throw new CliError(`${tooOld}
28327
+ Then run "openspace dev" again.`);
28284
28328
  if (!existsSync(join5(io.cwd, "openspace.json")))
28285
28329
  throw new CliError('No openspace.json here. Run "openspace dev" from the root of your site.');
28286
28330
  const bin = findBin(io.cwd);
@@ -29448,6 +29492,30 @@ async function loadPlaywright(importer = defaultImporter) {
29448
29492
  error: "Playwright is not installed. Run `npm i -D playwright && npx playwright install chromium` in the site folder and restart `openspace mcp`."
29449
29493
  };
29450
29494
  }
29495
+ function prepareScript(sectionId) {
29496
+ return `(async () => {
29497
+ const imgs = Array.from(document.images);
29498
+ for (const img of imgs) { img.loading = "eager"; img.decoding = "sync"; }
29499
+ const step = Math.max(200, Math.floor(window.innerHeight * 0.8));
29500
+ for (let y = 0; y < document.documentElement.scrollHeight; y += step) {
29501
+ window.scrollTo(0, y);
29502
+ await new Promise((r) => setTimeout(r, 30));
29503
+ }
29504
+ window.scrollTo(0, 0);
29505
+ const done = Promise.all(Array.from(document.images).map((img) => img.complete ? null :
29506
+ new Promise((r) => { img.addEventListener("load", r, { once: true }); img.addEventListener("error", r, { once: true }); })));
29507
+ await Promise.race([done, new Promise((r) => setTimeout(r, 5000))]);
29508
+ const id = ${JSON.stringify(sectionId ?? null)};
29509
+ if (id) {
29510
+ const target = document.querySelector('[data-os-id="' + id + '"]');
29511
+ for (const el of Array.from(document.body.querySelectorAll("*"))) {
29512
+ if (target && (el.contains(target) || target.contains(el))) continue;
29513
+ const pos = getComputedStyle(el).position;
29514
+ if (pos === "fixed" || pos === "sticky") el.style.setProperty("visibility", "hidden", "important");
29515
+ }
29516
+ }
29517
+ })()`;
29518
+ }
29451
29519
  function createScreenshotter(chromium) {
29452
29520
  let browser;
29453
29521
  const launch = async () => {
@@ -29481,6 +29549,7 @@ function createScreenshotter(chromium) {
29481
29549
  await page.goto(url, { waitUntil: "load", timeout: 3e4 });
29482
29550
  await page.waitForLoadState("networkidle", { timeout: 5e3 }).catch(() => void 0);
29483
29551
  await page.evaluate("document.fonts && document.fonts.ready").catch(() => void 0);
29552
+ await page.evaluate(prepareScript(req.sectionId)).catch(() => void 0);
29484
29553
  let png;
29485
29554
  if (req.sectionId) {
29486
29555
  png = await page.locator(`[data-os-id="${req.sectionId}"]`).first().screenshot({ type: "png" });
@@ -29742,7 +29811,11 @@ async function scaffold(templateId, dir, tpl, opts) {
29742
29811
  search: true
29743
29812
  }
29744
29813
  };
29745
- if (opts.title) doc.site = { ...doc.site, title: opts.title };
29814
+ if (opts.title) {
29815
+ const from = doc.site.title.trim();
29816
+ const footer = from && from !== opts.title ? rebrand(doc.site.footer, from, opts.title) : null;
29817
+ doc.site = { ...doc.site, title: opts.title, ...footer ? { footer } : {} };
29818
+ }
29746
29819
  await writeSiteDocument(dir, doc);
29747
29820
  await writeAgentsMd(dir, doc.site.title);
29748
29821
  return {
@@ -29754,6 +29827,23 @@ async function scaffold(templateId, dir, tpl, opts) {
29754
29827
  files: Object.keys(files).length
29755
29828
  };
29756
29829
  }
29830
+ var NOT_TEXT = /^(?:src|url|href|link|id|type|variant|icon|target|kind|style|preset)$/;
29831
+ function rebrand(value, from, to) {
29832
+ let changed = false;
29833
+ const walk5 = (v, key) => {
29834
+ if (typeof v === "string") {
29835
+ if (key && NOT_TEXT.test(key) || !v.includes(from)) return v;
29836
+ changed = true;
29837
+ return v.split(from).join(to);
29838
+ }
29839
+ if (Array.isArray(v)) return v.map((x) => walk5(x));
29840
+ if (v && typeof v === "object")
29841
+ return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, walk5(x, k)]));
29842
+ return v;
29843
+ };
29844
+ const out = walk5(value);
29845
+ return changed ? out : null;
29846
+ }
29757
29847
 
29758
29848
  // src/import.ts
29759
29849
  function defaultFolder(url) {
@@ -29978,6 +30068,9 @@ function createProgram(io, setExit, deps = {}) {
29978
30068
  io.out(formatReport(report, (code2, s2) => paint(color, code2, s2)));
29979
30069
  }
29980
30070
  if (!report.ok) setExit(1);
30071
+ const tooOld = astroNodeProblem(io.nodeVersion);
30072
+ if (tooOld && !opts.json) io.err(`Note: ${tooOld}
30073
+ The site won't build until you do.`);
29981
30074
  }
29982
30075
  );
29983
30076
  program.command("dev").description("Start the local preview (astro dev) in this site.").allowUnknownOption().argument("[astroArgs...]", "extra arguments passed to astro dev").action(async (args) => {
@@ -30014,6 +30107,9 @@ function createProgram(io, setExit, deps = {}) {
30014
30107
  io.out(" npm install");
30015
30108
  io.out(" npx openspace check");
30016
30109
  io.out(" npx openspace dev");
30110
+ const tooOld = astroNodeProblem(io.nodeVersion);
30111
+ if (tooOld) io.err(`Warning: ${tooOld}
30112
+ The site won't preview or build until you do.`);
30017
30113
  if (opts.url === void 0 && opts.repo === void 0 && !opts.domain)
30018
30114
  io.out("Set deploy.url in openspace.json to where the site will be published.");
30019
30115
  }
@@ -30176,4 +30272,4 @@ export {
30176
30272
  createProgram,
30177
30273
  run
30178
30274
  };
30179
- //# sourceMappingURL=chunk-RG7S2MUH.js.map
30275
+ //# sourceMappingURL=chunk-7SWL46LQ.js.map