open_blog 0.1.0 → 0.3.0

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -4
  3. data/README.md +65 -30
  4. data/app/assets/builds/open_blog/blog.css +1 -1
  5. data/app/assets/builds/open_blog/themes.css +403 -0
  6. data/app/assets/fonts/open_blog/OFL-dm-sans.txt +93 -0
  7. data/app/assets/fonts/open_blog/OFL-jetbrains-mono.txt +93 -0
  8. data/app/assets/fonts/open_blog/OFL-newsreader.txt +93 -0
  9. data/app/assets/fonts/open_blog/OFL-outfit.txt +93 -0
  10. data/app/assets/fonts/open_blog/OFL-space-grotesk.txt +93 -0
  11. data/app/assets/fonts/open_blog/dm-sans-italic-latin-ext.woff2 +0 -0
  12. data/app/assets/fonts/open_blog/dm-sans-italic-latin.woff2 +0 -0
  13. data/app/assets/fonts/open_blog/dm-sans-latin-ext.woff2 +0 -0
  14. data/app/assets/fonts/open_blog/dm-sans-latin.woff2 +0 -0
  15. data/app/assets/fonts/open_blog/jetbrains-mono-latin-ext.woff2 +0 -0
  16. data/app/assets/fonts/open_blog/jetbrains-mono-latin.woff2 +0 -0
  17. data/app/assets/fonts/open_blog/newsreader-italic-latin-ext.woff2 +0 -0
  18. data/app/assets/fonts/open_blog/newsreader-italic-latin.woff2 +0 -0
  19. data/app/assets/fonts/open_blog/newsreader-latin-ext.woff2 +0 -0
  20. data/app/assets/fonts/open_blog/newsreader-latin.woff2 +0 -0
  21. data/app/assets/fonts/open_blog/outfit-latin-ext.woff2 +0 -0
  22. data/app/assets/fonts/open_blog/outfit-latin.woff2 +0 -0
  23. data/app/assets/fonts/open_blog/space-grotesk-latin-ext.woff2 +0 -0
  24. data/app/assets/fonts/open_blog/space-grotesk-latin.woff2 +0 -0
  25. data/app/controllers/open_blog/api/v1/authors_controller.rb +1 -1
  26. data/app/controllers/open_blog/api/v1/pages_controller.rb +5 -5
  27. data/app/controllers/open_blog/media_controller.rb +20 -3
  28. data/app/helpers/open_blog/content_helper.rb +9 -2
  29. data/app/helpers/open_blog/faq_helper.rb +3 -1
  30. data/app/helpers/open_blog/theme_helper.rb +29 -5
  31. data/app/models/open_blog/image.rb +6 -0
  32. data/app/queries/open_blog/api_post_query.rb +5 -1
  33. data/config/routes.rb +2 -0
  34. data/db/migrate/20261003012512_create_open_blog_authors.rb +1 -1
  35. data/db/migrate/20261003012515_create_open_blog_images.rb +1 -1
  36. data/db/migrate/20261003012516_create_open_blog_posts.rb +4 -3
  37. data/db/migrate/20261020120000_align_open_blog_record_keys.rb +41 -0
  38. data/lib/generators/open_blog/generator_support.rb +5 -5
  39. data/lib/generators/open_blog/install/install_generator.rb +22 -1
  40. data/lib/generators/open_blog/install/templates/initializer.rb.tt +1 -0
  41. data/lib/generators/open_blog/install/templates/theme/blog.css +194 -93
  42. data/lib/generators/open_blog/install/templates/theme/open_blog_theme.css +17 -81
  43. data/lib/generators/open_blog/install/templates/theme/theme.css +3 -85
  44. data/lib/generators/open_blog/views/views_generator.rb +1 -1
  45. data/lib/open_blog/api_fields.rb +1 -1
  46. data/lib/open_blog/build_css.rb +51 -8
  47. data/lib/open_blog/configuration.rb +37 -1
  48. data/lib/open_blog/doctor/files.rb +50 -11
  49. data/lib/open_blog/doctor.rb +30 -1
  50. data/lib/open_blog/mcp/registry.rb +4 -4
  51. data/lib/open_blog/mcp/schemas.rb +5 -1
  52. data/lib/open_blog/post_attributes.rb +2 -2
  53. data/lib/open_blog/record_keys.rb +35 -0
  54. data/lib/open_blog/themes.rb +167 -0
  55. data/lib/open_blog/version.rb +1 -1
  56. data/lib/open_blog.rb +2 -0
  57. data/lib/tasks/open_blog.rake +1 -1
  58. data/skills/open-blog-install/SKILL.md +52 -4
  59. metadata +25 -2
@@ -1,10 +1,58 @@
1
1
  ---
2
2
  name: open-blog-install
3
- description: Install and configure Open Blog in a Rails host, customize its reader theme, and check setup.
3
+ description: Install or upgrade Open Blog in a Rails host, reuse application navigation and colors, integrate the theme control, and diagnose setup compatibility.
4
4
  ---
5
5
 
6
- Install the gem in the requested Rails application, then run `bin/rails generate open_blog:install`. Inspect the host's JavaScript, Tailwind, image processor, mount path, and authentication setup before selecting options. Use `--skip-tailwind` when the host should keep its CSS configuration; use the generated theme override for branding.
6
+ ## Locate the host and package
7
7
 
8
- Run `bin/rails open_blog:doctor` or `blog_doctor` and resolve relevant errors. Configure the actual publisher, author, public base URL, and policy links. Replace placeholders with user-supplied identities. Keep the initial API token secret; installation prints it once and repeat runs do not recover it. A host authentication hook takes precedence over tokens.
8
+ Work from the requested application's Rails root. Inspect its public layout and shared navbar/footer, CSS pipeline and palette variables, JavaScript entrypoint and Stimulus registration, existing theme preference, mount path, and editorial authentication. For a pilot, select isolated development/test databases before migrating.
9
9
 
10
- Check `tools/list` before using MCP tools. Finish with an actual reader request and authenticated `blog_list_posts` call. Do not publish unrelated content, change production routing, or deploy merely because installation was requested.
10
+ Use the requested gem release; inspect `Gemfile.lock` and `bundle show open_blog`. The installed package is the authority for its version. Inside it, layout and reader templates are under `lib/generators/open_blog/install/templates/views/`, theme sources under `lib/generators/open_blog/install/templates/theme/`, and browser controllers under `app/assets/javascripts/open_blog/controllers/`.
11
+
12
+ For examples and explanations, read [host integration](https://techwright-lab.github.io/open-blog/host-integration/); for task/file routing, read [usage](https://techwright-lab.github.io/open-blog/usage/). In a source checkout these are `docs/host-integration.md` and `docs/usage.md`. The steps below remain usable from the installed gem without the documentation site.
13
+
14
+ ## Check images before calling setup complete
15
+
16
+ - Inspect `active_storage_attachments.record_id` in the schema or with `ActiveStorage::Attachment.columns_hash.fetch("record_id").sql_type`. From 0.3.0 the migrations give Image and Author UUID keys when this column is `uuid`, and integer keys otherwise; doctor's Record keys check must report ok. A host that installed 0.2.0 on a UUID column needs `bin/rails railties:install:migrations FROM=open_blog` and `db:migrate` (the `AlignOpenBlogRecordKeys` migration). Keep the existing host attachment schema intact. With rich-text bodies, also follow doctor's Action Text key result; use Markdown when it reports a mismatch.
17
+ - Inspect the host variant processor before running the installer. It accepts `:vips` or `:mini_magick`; a disabled processor requires host configuration. Verify Ruby image-processing dependencies and native libvips/ImageMagick in the deployment image and production gem groups.
18
+ - Card and avatar variants use the engine's `/blog/media/:sha256/:variant/:filename` route and `config.image_delivery`, not the host's representation routes, so a host can keep those closed. Test originals and both variant URLs independently. Use `:proxy` when the host also blocks the storage service URLs that `:redirect` sends readers to. Preserve existing host access restrictions.
19
+
20
+ ## Install and configure
21
+
22
+ Add a missing gem with `bundle add open_blog`, passing the requested version constraint when specified. For a fresh application, use `bin/rails generate open_blog:install`. For an existing application retaining its CSS pipeline, use `--skip-tailwind`. A staged local pilot can use:
23
+
24
+ ```sh
25
+ bin/rails generate open_blog:install --theme=signal --skip-tailwind --skip-migrate --skip-sample
26
+ ```
27
+
28
+ Choose the requested preset. These flags still write files, add dependencies, register JavaScript, and mount routes. Review migrations and the host diff, migrate the intended database, then run `bin/rails open_blog:doctor`. Create the initial token with `open_blog:install_token` only when the selected access method needs it; keep the one-time secret private. A configured authentication hook takes precedence over tokens. Run `open_blog:sample` only when sample publishing is wanted and image setup works.
29
+
30
+ Set actual publisher/author identities, public origin (including the local port for a pilot), mount path, and policy links in `config/initializers/open_blog.rb`. The public origin excludes the mount prefix. Keep `config.mount_path` and `config/routes.rb` consistent. Restart after initializer changes.
31
+
32
+ ## Reuse application chrome
33
+
34
+ When shared navigation is requested, extract any inline public header/footer to host partials and render them in both the homepage and blog. Prefer a host-owned `app/views/layouts/blog.html.erb` with `config.layout = "blog"` when the main layout needs different behavior; `open_blog:views` does not overwrite that filename. Direct `config.layout = "application"` is also supported: branch on `@open_blog_page` for blog-specific head/assets. Layout selection is separate from `parent_controller`, whose inherited callbacks may require authentication or unavailable host state.
35
+
36
+ Adapt the installed layout while preserving `open_blog_theme_attributes`, `open_blog_head(@open_blog_page)`, early theme restoration, `open_blog_structured_data(@open_blog_page)`, `main#open-blog-main`, and the reader yield. Replace equivalent host head tags on reader requests so title/viewport/canonical are not duplicated. Keep host CSRF/CSP, icons, and required assets. Retain the reader's content/notices/byline/date helpers and policy/feed links, using a shared footer slot if needed. Host links in engine-rendered shared partials use `main_app`, for example `main_app.root_path`.
37
+
38
+ For `--skip-tailwind`/Tailwind 3, load the host's CSS explicitly and then `open_blog_stylesheets` (preset, compiled reader CSS, host override). For the Tailwind 4 component build, use `open_blog_theme_stylesheets` before the host build instead, keeping its generated `open_blog/theme.css` import. Register the `open-blog--` controllers in the public JavaScript entrypoint. Avoid `stylesheet_link_tag :all`; the compiled reader stylesheet contains reset rules. Scope `.ob-page` to the reader and inspect shared chrome after loading it.
39
+
40
+ ## Share palette and appearance state
41
+
42
+ Use `config.theme_colors` for fixed hex colors. For host CSS variables, edit `app/assets/stylesheets/open_blog_theme.css` (fallback CSS) or `app/assets/tailwind/open_blog/theme.css` (Tailwind 4). Map semantic `--ob-*` colors to host tokens; `var()` is invalid in `theme_colors`. Override both explicit and system-mode specificity, for example the selector list `:root[data-ob-theme="signal"][data-theme], :root[data-ob-theme="signal"]:not([data-theme])`, loaded after preset rules. Cover surfaces, text, borders, accents, code, notices, and alerts. Keep Signal typography/shape if requested. Use opaque surface mixes where translucent host colors expose unwanted layers. Doctor does not check CSS-derived contrast.
43
+
44
+ Place a single theme button in the shared navbar if requested; it is not a separate nav. Reuse the existing `open-blog--theme` controller and `cycle` action, its `systemLabel`/`lightLabel`/`darkLabel` values, and optional `label` target. Keep the initial `hidden` attribute, accessible mode label, keyboard focus, and mobile target size. The installed `_theme_toggle.html.erb` shows its markup; a host partial can use host styles.
45
+
46
+ The controller stores `open-blog-theme` and sets `data-theme="light"` or `"dark"` on `<html>`; System removes both and follows the OS. Restore that same key before CSS loads on homepage and blog using the gem helper or one shared equivalent script with the host's CSP nonce. Keep one preference owner when the host already has a theme controller. Honor a fixed `config.color_scheme` by retaining its root attribute and omitting the toggle. Check Turbo transitions if used, full reloads, explicit light/dark, and system mode.
47
+
48
+ ## Upgrade copied files deliberately
49
+
50
+ Read the target changelog, update any version constraint, then `bundle update open_blog --conservative`; review dependency changes too (Open Blog constrains JSON below 3). Bundler does not refresh copied host files.
51
+
52
+ `bin/rails generate open_blog:views` refreshes reader templates and `layouts/open_blog.html.erb` only. Compare controllers, locales, and theme sources with the installed package separately. Conflicting files are kept in a noninteractive rerun; a successful generator exit does not mean all copies are current. Merge required changes and use replacement only for reviewed files. A blanket `open_blog:install --force` also replaces the initializer. Review a host-owned layout against new helper/asset contracts manually. When moving from 0.1.0 to presets, replace old full-palette definitions with intentional overrides so they do not mask the new preset. Rebuild affected assets and restart.
53
+
54
+ ## Verify and report
55
+
56
+ Run doctor, relevant host regression tests, and real reader requests. Verify shared links/chrome, a single head/landmark, fonts and computed palette in all modes, preference persistence, keyboard access, and desktop/mobile overflow. Exercise a real upload and variant retrieval separately from text-only rendering; preserve host attachment regressions. Verify feeds/sitemap and any promised scheduling with the actual worker, not only a direct job invocation.
57
+
58
+ For MCP use, check `tools/list` and make an authenticated `blog_list_posts` call when that access is configured. Exercise draft privacy and signed previews; perform publication/edit checks within authorized local/test scope. Report observed passes, blockers, and unverified checks separately. Installation does not authorize unrelated content publication or production deployment.
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open_blog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TechWright Labs
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-03 00:00:00.000000000 Z
10
+ date: 2026-10-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: json
@@ -233,6 +233,26 @@ files:
233
233
  - LICENSE.txt
234
234
  - README.md
235
235
  - app/assets/builds/open_blog/blog.css
236
+ - app/assets/builds/open_blog/themes.css
237
+ - app/assets/fonts/open_blog/OFL-dm-sans.txt
238
+ - app/assets/fonts/open_blog/OFL-jetbrains-mono.txt
239
+ - app/assets/fonts/open_blog/OFL-newsreader.txt
240
+ - app/assets/fonts/open_blog/OFL-outfit.txt
241
+ - app/assets/fonts/open_blog/OFL-space-grotesk.txt
242
+ - app/assets/fonts/open_blog/dm-sans-italic-latin-ext.woff2
243
+ - app/assets/fonts/open_blog/dm-sans-italic-latin.woff2
244
+ - app/assets/fonts/open_blog/dm-sans-latin-ext.woff2
245
+ - app/assets/fonts/open_blog/dm-sans-latin.woff2
246
+ - app/assets/fonts/open_blog/jetbrains-mono-latin-ext.woff2
247
+ - app/assets/fonts/open_blog/jetbrains-mono-latin.woff2
248
+ - app/assets/fonts/open_blog/newsreader-italic-latin-ext.woff2
249
+ - app/assets/fonts/open_blog/newsreader-italic-latin.woff2
250
+ - app/assets/fonts/open_blog/newsreader-latin-ext.woff2
251
+ - app/assets/fonts/open_blog/newsreader-latin.woff2
252
+ - app/assets/fonts/open_blog/outfit-latin-ext.woff2
253
+ - app/assets/fonts/open_blog/outfit-latin.woff2
254
+ - app/assets/fonts/open_blog/space-grotesk-latin-ext.woff2
255
+ - app/assets/fonts/open_blog/space-grotesk-latin.woff2
236
256
  - app/assets/javascripts/open_blog/controllers/code_copy_controller.js
237
257
  - app/assets/javascripts/open_blog/controllers/reading_progress_controller.js
238
258
  - app/assets/javascripts/open_blog/controllers/search_controller.js
@@ -345,6 +365,7 @@ files:
345
365
  - db/migrate/20261003164418_create_open_blog_api_tokens.rb
346
366
  - db/migrate/20261003175454_create_open_blog_pages.rb
347
367
  - db/migrate/20261003182919_create_open_blog_page_views.rb
368
+ - db/migrate/20261020120000_align_open_blog_record_keys.rb
348
369
  - lib/generators/open_blog/admin_suite/admin_suite_generator.rb
349
370
  - lib/generators/open_blog/admin_suite/templates/author_resource.rb.tt
350
371
  - lib/generators/open_blog/admin_suite/templates/blog_portal.rb.tt
@@ -449,6 +470,7 @@ files:
449
470
  - lib/open_blog/reader_dates.rb
450
471
  - lib/open_blog/reader_page.rb
451
472
  - lib/open_blog/reader_queries.rb
473
+ - lib/open_blog/record_keys.rb
452
474
  - lib/open_blog/record_release.rb
453
475
  - lib/open_blog/redirect_target.rb
454
476
  - lib/open_blog/remove.rb
@@ -474,6 +496,7 @@ files:
474
496
  - lib/open_blog/surface_report/record_checks.rb
475
497
  - lib/open_blog/surface_report/robots.rb
476
498
  - lib/open_blog/syntax_css.rb
499
+ - lib/open_blog/themes.rb
477
500
  - lib/open_blog/unpublish.rb
478
501
  - lib/open_blog/version.rb
479
502
  - lib/open_blog/write_post.rb