ultimate-jekyll-manager 1.9.22 → 1.9.24

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/CLAUDE.md CHANGED
@@ -179,7 +179,7 @@ Note: `-t` short alias belongs to `translation`. The `test` command uses `--test
179
179
 
180
180
  - **🚫 NEVER use `npx mgr ...` from the framework repo** — `npx mgr` is for CONSUMER projects only (where the bin lives in `node_modules/.bin/`). From the framework repo, use `npm test`, `npm start`, etc. — the `scripts` in `package.json` call `node bin/ultimate-jekyll-manager` directly. This applies to ALL four OMEGA frameworks (BEM/UJM/BXM/EM).
181
181
  - **🚫 NEVER run `npm start` in a consumer project** — the user runs the dev server; running it again kills theirs. Assume it's already running; if it isn't, **instruct the user to run it** rather than running it yourself. Instead, **check `logs/dev.log`** after editing files to confirm the watcher recompiled successfully (`Reloading Browsers...` = success; `errored` = fix the error) — never tail/attach to the process. If editing multiple files, check the log once after the last edit. A change that breaks the build is not a completed change. Running `npx mgr test` is fine.
182
- - **Live-test UI changes via CDP.** After code changes compile, use the `chrome-devtools` MCP tools (screenshots, click, evaluate JS, console logs) to verify the change works in the running browser. This is the primary way to confirm UI changes — type-checking and test suites verify code correctness, not feature correctness. Read the URL from the consumer's `.temp/_config_browsersync.yml`. Prefer `https://localhost:4000`; fall back to the local network IP (e.g. `https://192.168.x.x:4000`) if localhost doesn't connect. See [docs/cdp-debugging.md](docs/cdp-debugging.md) + `~/.claude/mcp-server/servers/chrome-devtools/CLAUDE.md`.
182
+ - **Live-test UI changes via CDP.** After code changes compile, use the `chrome-devtools` MCP tools (screenshots, click, evaluate JS, console logs) to verify the change works in the running browser — your session auto-launches its own private Chrome on the first tool call (no setup, no ports). This is the primary way to confirm UI changes — type-checking and test suites verify code correctness, not feature correctness. The dev server URL is **`https://localhost:4000`** (port from the consumer's `.temp/_config_browsersync.yml` when multiple sites run) **NEVER the LAN IP** (`https://192.168.x.x:...`). See [docs/cdp-debugging.md](docs/cdp-debugging.md) + `~/.claude/mcp-server/servers/chrome-devtools/CLAUDE.md`.
183
183
 
184
184
  ## Supply-Chain Security
185
185
 
@@ -209,6 +209,8 @@ Whenever you make a behavioral change (new command, new flag, new pattern, remov
209
209
 
210
210
  Don't ship behavioral changes with stale docs. Validate first, then document — write docs that describe shipped reality, not intentions.
211
211
 
212
+ **The OMEGA docs are structurally MIRRORED.** This file's section skeleton, the consumer template (`src/defaults/CLAUDE.md`), shared-concept `docs/*.md` filenames, and the `omega:*` skills are identical in structure and order across the sister frameworks (UJM / BEM / BXM / EM / MAM — WM mirrors the library subset). Never add, rename, or reorder a section here without making the SAME change in every sister repo in the same pass. The canonical skeletons + omission rules live in the `omega:main` skill's `mirror-spec.md` resource.
213
+
212
214
  ## Documentation
213
215
 
214
216
  Deep references live in `docs/`. Treat docs as a first-class deliverable. **Whenever you make a behavioral change, update both this overview AND the relevant `docs/*.md` deep reference.**
@@ -1,6 +1,8 @@
1
1
  # ========== Default Values ==========
2
2
  # Ultimate Jekyll Manager (UJM) — consumer project
3
3
 
4
+ <!-- MAINTAINERS (framework repo): this consumer template is MIRRORED across UJM/BEM/BXM/EM/MAM — same sections, same order (framework-specific extras may be inserted; canonical sections are never reordered/renamed). Edit all five together. Canonical skeleton: omega:main skill → resources/mirror-spec.md -->
5
+
4
6
  ## Framework
5
7
 
6
8
  This project consumes **Ultimate Jekyll Manager** (UJM) — a comprehensive framework for building modern Jekyll-powered static sites. UJM provides one-line bootstrap per context (build / frontend / service-worker), a multi-stage gulp pipeline (defaults / distribute / webpack / sass / imagemin / jekyll / audit / translation / minifyHtml / serve), default Jekyll layouts + themes, a frontend ES-module Manager with dynamic per-page module loading, a service worker with Firebase Messaging + cache management, and a built-in three-layer test framework.
@@ -398,6 +398,11 @@ function filterBySource(source, files, sourceFilter, pathPart) {
398
398
  });
399
399
  }
400
400
 
401
+ // Glob ignore patterns implementing the "underscore = not a suite" convention:
402
+ // `_`-prefixed FILES (e.g. test/_init.js) and everything under a `_`-prefixed
403
+ // DIRECTORY at any depth (helpers, fixtures — e.g. test/_helpers/harness.js).
404
+ const DISCOVERY_IGNORE = ['**/_*.js', '**/_*/**'];
405
+
401
406
  function discoverTestFiles(target) {
402
407
  const { source: sourceFilter, pathPart } = parseTarget(target);
403
408
 
@@ -421,7 +426,7 @@ function discoverTestFiles(target) {
421
426
  // Consumers write their own boot tests under <cwd>/test/boot/.
422
427
  const frameworkSuitesDir = path.join(__dirname, 'suites');
423
428
  if (jetpack.exists(frameworkSuitesDir)) {
424
- const ignore = ['_**'];
429
+ const ignore = [...DISCOVERY_IGNORE];
425
430
  if (!isFrameworkSelfTest) ignore.push('boot/**');
426
431
  glob('**/*.js', { cwd: frameworkSuitesDir, ignore }).sort().forEach((rel) => {
427
432
  framework.push(path.join(frameworkSuitesDir, rel));
@@ -430,9 +435,10 @@ function discoverTestFiles(target) {
430
435
 
431
436
  // Consumer project suites — CWD/test/**/*.js. Skip when running from inside the
432
437
  // framework's own dist tree (where consumer-tests-dir === framework-tests-parent).
438
+ // Excludes `_`-prefixed files and directories (see DISCOVERY_IGNORE).
433
439
  const projectTestsDir = path.join(process.cwd(), 'test');
434
440
  if (jetpack.exists(projectTestsDir) && projectTestsDir !== path.dirname(frameworkSuitesDir)) {
435
- glob('**/*.js', { cwd: projectTestsDir, ignore: ['_**'] }).sort().forEach((rel) => {
441
+ glob('**/*.js', { cwd: projectTestsDir, ignore: [...DISCOVERY_IGNORE] }).sort().forEach((rel) => {
436
442
  project.push(path.join(projectTestsDir, rel));
437
443
  });
438
444
  }
@@ -508,4 +514,4 @@ async function runInitSetups() {
508
514
  }
509
515
  }
510
516
 
511
- module.exports = { run, SkipError };
517
+ module.exports = { run, SkipError, DISCOVERY_IGNORE };
@@ -0,0 +1,63 @@
1
+ // Build-layer tests for test-suite discovery — specifically the
2
+ // "underscore = not a suite" convention: `_`-prefixed files and everything
3
+ // under `_`-prefixed directories (at ANY depth) must be excluded, so consumers
4
+ // can keep helpers and fixture trees (e.g. test/_helpers/harness.js)
5
+ // next to their suites.
6
+
7
+ const path = require('path');
8
+
9
+ module.exports = {
10
+ type: 'suite',
11
+ layer: 'build',
12
+ description: 'test discovery — underscore exclusion convention',
13
+ tests: [
14
+ {
15
+ name: 'runner exports DISCOVERY_IGNORE',
16
+ run: (ctx) => {
17
+ const runner = require(path.join(__dirname, '..', '..', 'runner.js'));
18
+ ctx.expect(Array.isArray(runner.DISCOVERY_IGNORE)).toBe(true);
19
+ ctx.expect(runner.DISCOVERY_IGNORE.length >= 2).toBe(true);
20
+ },
21
+ },
22
+ {
23
+ name: 'glob with DISCOVERY_IGNORE skips _ files and _ dirs at any depth',
24
+ run: (ctx) => {
25
+ const fs = require('fs');
26
+ const os = require('os');
27
+ const glob = require('glob').globSync;
28
+ const { DISCOVERY_IGNORE } = require(path.join(__dirname, '..', '..', 'runner.js'));
29
+
30
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ujm-discovery-test-'));
31
+ const write = (rel) => {
32
+ const file = path.join(tmp, rel);
33
+ fs.mkdirSync(path.dirname(file), { recursive: true });
34
+ fs.writeFileSync(file, 'module.exports = {};\n');
35
+ };
36
+
37
+ // Should be DISCOVERED:
38
+ write('build/config.test.js');
39
+ write('page/runner.test.js');
40
+ write('boot/nested/deep.test.js');
41
+
42
+ // Should be EXCLUDED:
43
+ write('_init.js'); // top-level _ file
44
+ write('page/_helper.js'); // nested _ file
45
+ write('_helpers/harness.js'); // file in top-level _ dir
46
+ write('_fixtures/packages/runner/mod/index.js'); // deep inside a _ dir
47
+ write('boot/_private/util.js'); // _ dir below a layer dir
48
+
49
+ const found = glob('**/*.js', { cwd: tmp, ignore: [...DISCOVERY_IGNORE] }).sort();
50
+
51
+ try {
52
+ ctx.expect(found).toEqual([
53
+ 'boot/nested/deep.test.js',
54
+ 'build/config.test.js',
55
+ 'page/runner.test.js',
56
+ ]);
57
+ } finally {
58
+ fs.rmSync(tmp, { recursive: true, force: true });
59
+ }
60
+ },
61
+ },
62
+ ],
63
+ };
@@ -1,48 +1,28 @@
1
1
  # CDP Debugging (driving a live browser)
2
2
 
3
- How to launch a browser you can CONTROL — see the site live, screenshot it, click, type, read console logs, inspect network requests — for agents (Claude via MCP/CDP) and humans.
3
+ How to drive a browser you can CONTROL — see the site live, screenshot it, click, type, read console logs, inspect network requests — for agents (Claude via MCP/CDP) and humans.
4
4
 
5
- > Mirrored across the four sister frameworks (UJM / BEM / BXM / EM) — same core section, framework-flavored. Edit all four together.
5
+ > Mirrored across the five sister frameworks (UJM / BEM / BXM / EM / WM) — same core section, framework-flavored. Edit all five together.
6
6
 
7
- ## Launching a controllable Chrome (the canonical command)
7
+ ## The browser: your Claude session owns one
8
8
 
9
- ```bash
10
- open -gna "Google Chrome" --args \
11
- --remote-debugging-port=9223 \
12
- --user-data-dir="$HOME/Library/Application Support/chrome-profiles/agent" \
13
- --no-first-run --no-default-browser-check \
14
- --disable-background-timer-throttling \
15
- --disable-backgrounding-occluded-windows \
16
- --disable-renderer-backgrounding \
17
- https://localhost:4000 # ← the UJM dev server (or the IP from .temp/_config_browsersync.yml if localhost doesn't connect)
18
- ```
9
+ Browser work runs through the **`chrome-devtools` MCP** (via mcp-router). There is NO launch procedure anymore — no ports, no profile dirs, no curl checks:
19
10
 
20
- Verify it's up: `curl -s http://127.0.0.1:9223/json/version`
11
+ - **Just call the tools** — `new_page`, `navigate_page`, `take_screenshot`, `click`, `fill`, `evaluate_script`, `list_console_messages`, `list_network_requests`. The browser auto-launches on the first call.
12
+ - **Each Claude session gets its OWN private Chrome** (`--isolated`): temp profile, CDP over an internal pipe. Parallel sessions cannot see or touch each other's pages — open and close pages freely, the whole browser is yours.
13
+ - **It dies with the session.** No orphans, no cleanup, nothing to kill.
14
+ - **Ephemeral profile** — cookies/logins do NOT persist between sessions. If a flow needs auth, log in during the task.
15
+ - **Self-signed HTTPS is pre-accepted** (`--acceptInsecureCerts` in the upstream) — dev servers load without certificate interstitials.
16
+ - **NEVER quit/kill Chrome by app name** (`killall "Google Chrome"`, osascript) — that's the user's personal browser, not yours.
21
17
 
22
- The rules that make this work (each one learned the hard way):
18
+ Humans: the agent's Chrome window is visible you can watch it drive. Full reference: `~/.claude/mcp-server/servers/chrome-devtools/CLAUDE.md`.
23
19
 
24
- - **`open -gna` launches WITHOUT stealing focus.** `-g` = don't bring to foreground, `-n` = new instance (required — without it `open` just activates the already-running daily Chrome and the `--args` are ignored). Launching the Chrome binary directly ALWAYS activates the app and steals focus. Do NOT use `-j`/`--hide` — animations need a visible window; instead the three `--disable-*` flags keep timers/rAF/rendering at FULL speed while the window sits behind your work (verified: rAF at the display's native 120fps while backgrounded, focus never moved).
25
- - **`--user-data-dir` is REQUIRED, not optional.** Chrome 136+ **silently ignores** `--remote-debugging-port` on the default profile — no error, no port, nothing (verified on Chrome 149). This is the #1 "why isn't CDP up" trap.
26
- - **The profile dir IS the persistent login state.** Cookies + localStorage survive relaunches (verified by round-trip). **Log into sites once in the agent profile and every agent reuses the authenticated state.** Ecosystem convention: ONE shared profile at `~/Library/Application Support/chrome-profiles/agent` across all four frameworks, so logins are a one-time setup.
27
- - **One Chrome instance per profile dir — but MANY agents per instance.** CDP is multi-client (verified: two concurrent clients driving different tabs of one instance): agents and sessions attach to the SAME port, each drives its own tab, and all share the profile's logins. One agent per tab is the only rule. A second launch with the same dir just opens a window in the existing instance and **ignores the new debug port** — attach to the running one instead. Reach for a second profile + port (`…/b` on 9224) only for a different IDENTITY (a different account = a different cookie jar) or hard isolation.
28
- - It runs **side-by-side with the daily Chrome** — a different `--user-data-dir` is a fully separate instance.
29
- - **Quit by profile match, never by app name**: `pkill -f "chrome-profiles/agent"`. (`osascript 'tell app "Google Chrome" to quit'` hits the daily browser too — same app name.)
20
+ ## Electron apps are the exception (attach, don't launch)
30
21
 
31
- ## Driving it
32
-
33
- | Client | Good for | Port handoff |
34
- |---|---|---|
35
- | `chrome-devtools` MCP | rich interaction — click, fill, type, screenshots, network requests, console messages, performance traces | `CHROME_CDP_PORT` env var, **expanded ONCE when the Claude session spawns its MCP — set it BEFORE launching `claude`** (mid-session changes do nothing) |
36
- | Any CDP client — including EM's `npx mgr cdp` run from any EM project | quick JS eval, per-renderer screenshots | per invocation: `EM_CDP_PORT=9223 npx mgr cdp eval ":4000" 'document.title'` |
37
-
38
- Port conventions: **9222** = Electron apps (EM), **9223+** = Chrome instances.
22
+ An Electron dev app is a running singleton — you ATTACH to it instead of launching a browser: the `chrome-devtools-electron` MCP upstream (reads `EM_CDP_PORT`, default 9222, expanded once at session start) or EM's per-invocation `npx mgr cdp`. See EM's `docs/cdp-debugging.md`.
39
23
 
40
24
  ## UJM specifics
41
25
 
42
- <<<<<<< HEAD
43
- - **The dev server URL is NEVER `localhost`.** BrowserSync serves on the machine's local network IP over HTTPS (e.g. `https://192.168.86.69:4000`) `localhost:4000` is refused. The port also varies (4001, …) when multiple sites run simultaneously. The exact served URL is written to `.temp/_config_browsersync.yml` at the root of the WEBSITE project being served (the UJM consumer — e.g. `<brand>-website/.temp/_config_browsersync.yml`) — read that file FIRST, every time, before navigating.
44
- =======
45
- - **The dev server is HTTPS.** BrowserSync serves over HTTPS (self-signed cert). Prefer `https://localhost:4000`; fall back to the machine's local network IP (e.g. `https://192.168.x.x:4000`) if localhost doesn't connect. Port 4000 by default, increments to 4001+ when multiple sites run. The exact URL is in `.temp/_config_browsersync.yml` at the root of the WEBSITE project (the UJM consumer — e.g. `<brand>-website/.temp/_config_browsersync.yml`) — read that file FIRST, every time, before navigating.
46
- >>>>>>> df950b1 (v1.9.0: MCP OAuth flow on /token page, CDP debugging docs, dev-URL updates)
47
- - Launch it pointed at the dev server — UJM's live reload keeps the tab current as you edit, so the agent sees every change without relaunching anything.
26
+ - **The dev server URL is `https://localhost:4000` — NEVER the LAN IP.** Do not use `https://192.168.x.x:...` forms. BrowserSync serves HTTPS (self-signed — pre-accepted, see above); the port is 4000 by default and increments (4001, …) when multiple sites run. The exact port is in `.temp/_config_browsersync.yml` at the root of the WEBSITE project being served (the UJM consumer — e.g. `<brand>-website/.temp/_config_browsersync.yml`) — read it when in doubt, but always navigate to the `localhost` form.
27
+ - Point a page at the dev server UJM's live reload keeps the tab current as you edit, so the agent sees every change without relaunching anything.
48
28
  - Typical loop: edit → reload happens → MCP `take_screenshot` / `list_console_messages` / `list_network_requests` to verify the page, requests to the backend, and console cleanliness.
@@ -234,7 +234,7 @@ Same protocol as EM (`__EM_TEST__`) and BXM (`__BXM_TEST__`). One marker per fra
234
234
 
235
235
  - **Framework suites**: glob `<ujm>/dist/test/suites/**/*.js` (resolved from `__dirname/suites` in `runner.js`).
236
236
  - **Consumer suites**: glob `<cwd>/test/**/*.js`.
237
- - **Excluded** (`_` underscore convention): any file or directory starting with `_` is excluded from suite discovery. Put shared helpers, fixture data, and non-test support files in `_`-prefixed paths — e.g. `test/_fixtures/`, `test/_helpers/`. The runner still specifically loads `test/_init.js` as the lifecycle hook. Matches the same convention in BEM/EM/BXM.
237
+ - **Excluded** (the `_` underscore convention — `DISCOVERY_IGNORE` in `src/test/runner.js`): `_`-prefixed FILES (`test/_init.js`, `test/page/_helper.js`) and everything under a `_`-prefixed DIRECTORY at **any depth** (`test/_fixtures/**`, `test/boot/_private/**`) are excluded from suite discovery. Put shared helpers, fixture data, and non-test support files in `_`-prefixed paths — e.g. `test/_fixtures/`, `test/_helpers/`. The runner still specifically loads `test/_init.js` as the lifecycle hook. Matches the same convention in BEM/EM/BXM.
238
238
  - **Framework boot suites** are excluded when the cwd's `package.json#name` is not `ultimate-jekyll-manager` — they target UJM's fixture site, not the consumer's. Consumers write their own boot tests in `<cwd>/test/boot/`.
239
239
 
240
240
  ## `test/_init.js` — pre-test lifecycle hook
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "1.9.22",
3
+ "version": "1.9.24",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "files": [