studio-engine 0.32.3 → 0.33.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e56dfd4be2d6f429f329626c4aebb8b22aa9e0069cfdf8905a02fab4bc47ab4c
4
- data.tar.gz: 71b6a6d3dafa57d3b25e9cb791049ae9b4a975efa7d14b08b961492b2b870d6f
3
+ metadata.gz: 9ed77550c057e9ec4e232cc40ea934ef4753cc1d73d30e98b52c0a56f7ad8c8d
4
+ data.tar.gz: 01b04c9da431ef4d43b75cf12533c3aece29c5557157af4c0f91eadf1fe9e2bb
5
5
  SHA512:
6
- metadata.gz: ea74d63cf741530df52e0fbe490a3fe48817845235f12aa911e094d67fe6012e3b9f1d139f95d8f5240d467fa079a2746f6a3985c256a3daee948136752e3c9c
7
- data.tar.gz: 75146aa7893ca074ada0c58b5ecfb20641615432c63090d3d8bd39bd0b6f6e480a6d7e558bbf45ac8003144a6fd224222fd7eeaac297571b522e255e43343472
6
+ metadata.gz: a1b26944f9f08b070f00aec356cc2435e3e35096d1353c970dd797b486293e50827fa6e6a11b3bc67ea306ef505f740114640595a4db10da4e9883a71561633b
7
+ data.tar.gz: ce46eddd0627c5eae83daa9fc2eca518d74eae7500ce0e44a22faf016c0059d68b01f1d7b874e1f38d063918c460d36bf981d33b2a7f5dc3fe07ac6e0db85811
data/CHANGELOG.md CHANGED
@@ -2,6 +2,102 @@
2
2
 
3
3
  The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — `MAJOR.MINOR.PATCH`. Consumer Rails apps install the released RubyGems package with `gem "studio-engine", "~> 0.6"`; bumping the gem version and updating consumer lockfiles is a release.
4
4
 
5
+ ## 0.33.0 — 2026-08-10
6
+
7
+ Two changes ship together in this release: local log files are now capped, and
8
+ the pinned bars above the navbar become a composable **stack** that sits beside
9
+ the navbar rather than inside it.
10
+
11
+ **Local log files are now capped — 16 MB development, 8 MB test.** New
12
+ `studio.logger` initializer. Nothing to install, run, or remember: it rides the
13
+ gem, so every app, every future app, every worktree, and a freshly rebuilt Mac
14
+ all get it by construction.
15
+
16
+ Rails' own default is the reason this was needed. `config.load_defaults "7.1"`
17
+ sets `log_file_size` to **100 MB** for development *and* test, and each keeps one
18
+ rotated sibling — up to ~400 MB of log per checkout, times every worktree on the
19
+ machine. The logs were never unbounded; the ceiling was just far too high for a
20
+ machine that carries many desks. New ceiling: ~48 MB per checkout.
21
+
22
+ **Production is untouched.** The cap applies only where `Rails.env.local?`, so
23
+ every `production.rb` that hands its stream to STDOUT keeps doing exactly that,
24
+ and a host that names its own `config.logger` is never overridden.
25
+
26
+ **Ordering is the load-bearing part of this change.** Rails' `:initialize_logger`
27
+ is a *bootstrap* initializer — it runs before every railtie and engine
28
+ initializer and does `Rails.logger ||= config.logger || <default>`. An engine
29
+ that assigns `app.config.logger` from an ordinary initializer is therefore a
30
+ silent no-op: Rails has already built the logger. So `studio.logger` declares
31
+ `before: :initialize_logger` and sets `config.log_file_size`, the knob Rails
32
+ itself reads one moment later, leaving Rails owning the path, formatter, level,
33
+ and tagging. `after: :load_environment_hook` pins the other edge of the window,
34
+ which also keeps Railtie's implicit initializer chaining from dragging
35
+ `studio.assets` forward.
36
+
37
+ `test/integration/log_rotation_test.rb` asserts the **behavior**, not the
38
+ config: it boots real Rails apps and checks that the log file actually rotates
39
+ on disk once it passes the cap. It carries a mutation control — the same 17 MB
40
+ log with the cap switched off must *not* rotate — so the suite cannot be
41
+ satisfied by Rails' 100 MB default. Dropping the `before:` ordering reds it.
42
+
43
+ **New setting — `Studio.local_log_max_bytes`.** `false` opts out; an Integer
44
+ sets your own cap. Unlike every other `Studio.*` setting, it must be set in
45
+ `config/application.rb` (after `require "studio"`) or `config/environments/*.rb`
46
+ — `config/initializers/studio.rb` loads too late to be read.
47
+
48
+ ---
49
+
50
+ **The environment banner is now the navbar's SIBLING, not its child, and the
51
+ navbar sizes itself to whatever bars are actually there.** Nesting the banner
52
+ inside the navbar coupled two unrelated components: every new bar meant editing
53
+ the navbar, and there is already a second bar (impersonation), so this was never
54
+ a 0-or-1 problem.
55
+
56
+ Render the stack immediately before the navbar:
57
+
58
+ ```erb
59
+ <%= render "studio/banners/stack" %>
60
+ <%= render "layouts/navbar" %>
61
+ ```
62
+
63
+ The bars do not know the navbar exists; the navbar does not know which bars
64
+ rendered — only how tall they are, via `--studio-bars-h`.
65
+
66
+ **The height is MEASURED, not assumed.** A `ResizeObserver` on the stack
67
+ publishes its real height, so a bar that needs to be taller, a second bar, or one
68
+ that wraps on a narrow screen all work with **no change to any consuming app**.
69
+ A server-rendered estimate paints first so the common case never flashes, then the
70
+ observer replaces it with the truth. Verified in a real browser: growing the bar
71
+ 32px moved the stack, the published property and the header's `top` together, on
72
+ the same frame.
73
+
74
+ **Backward-compatible.** An app that renders no stack gets
75
+ `var(--studio-bars-h, 0px)` — identical to the old `top-0`. Adoption is opt-in.
76
+
77
+ ### Added
78
+
79
+ - **`studio/banners/stack`** — renders whichever bars apply (environment via
80
+ `Studio.show_environment_banner?`, impersonation when the host passes
81
+ `impersonated_user` / `admin_user` / `stop_path`) and publishes their measured
82
+ height. Takes `preview:` and forwards `devnet:` / `extra:` to the environment bar.
83
+ A preview render emits nothing at all, so a navbar-preview copy cannot duplicate
84
+ live chrome or publish a height.
85
+ - **`Studio.local_log_max_bytes`** — the opt-out (`false`) or override (an
86
+ Integer) for the new local log cap. Set it in `config/application.rb` or
87
+ `config/environments/*.rb`, never `config/initializers/studio.rb`.
88
+
89
+ ### Changed
90
+
91
+ - **The navbar's sticky `top` reads `--studio-bars-h`** instead of hardcoding
92
+ `top-0`. It never branches on which bars rendered.
93
+ - **Banners are branded off the app's own theme tokens** — the environment bar
94
+ derives from `--color-warning` and impersonation from `--color-danger`, each
95
+ under a translucent gradient wash, replacing hardcoded hex stops. An app that
96
+ retunes its theme now gets a banner that follows it.
97
+ - **Local `development` and `test` logs rotate at 16 MB / 8 MB** via the new
98
+ `studio.logger` initializer, down from Rails' 100 MB default. Production is
99
+ untouched.
100
+
5
101
  ## 0.32.3 — 2026-08-09
6
102
 
7
103
  **New public CSS custom property: `--nav-bottom`.** `_head.html.erb` now
@@ -48,7 +144,7 @@ rendered the desktop trigger on mobile beside the real one. Callers now own
48
144
  the display class (bare renders default to `inline-flex`). Regression view
49
145
  tests pin both.
50
146
 
51
- ## 0.32.1 — Unreleased
147
+ ## 0.32.1 — 2026-08-09
52
148
 
53
149
  **Setup-guide corrections.** Docs only — no code, no behavior change.
54
150
 
data/README.md CHANGED
@@ -54,6 +54,35 @@ Studio.configure do |config|
54
54
  end
55
55
  ```
56
56
 
57
+ ### Local log rotation (automatic — nothing to configure)
58
+
59
+ The engine caps the host app's **development** log at 16 MB and its **test** log
60
+ at 8 MB, keeping one rotated sibling each. There is nothing to install, run, or
61
+ remember: it rides the gem, so every checkout and every worktree is born with it.
62
+
63
+ It exists because Rails' own default is far too generous for a machine that
64
+ carries many worktrees. `config.load_defaults "7.1"` sets `log_file_size` to
65
+ **100 MB** for development *and* test, and each keeps a rotated sibling — up to
66
+ ~400 MB of log per checkout.
67
+
68
+ **Production is untouched.** The cap applies only where `Rails.env.local?`, so
69
+ apps that hand their stream to STDOUT for the platform keep doing exactly that.
70
+ A host that names its own `config.logger` is never overridden.
71
+
72
+ To choose your own cap, or to opt out:
73
+
74
+ ```ruby
75
+ # config/application.rb (after `require "studio"`) or config/environments/development.rb
76
+ Studio.local_log_max_bytes = 64.megabytes # your own cap
77
+ Studio.local_log_max_bytes = false # opt out; Rails' 100 MB default returns
78
+ ```
79
+
80
+ **This one setting cannot go in `config/initializers/studio.rb`.** It is read
81
+ during boot — Rails builds the logger in a bootstrap initializer, long before
82
+ `config/initializers` is loaded — so an initializer would be too late and would
83
+ silently do nothing. Every *other* `Studio.*` setting belongs in the initializer
84
+ as usual.
85
+
57
86
  Transactional mail transport is shared through `Studio::MailTransport`:
58
87
 
59
88
  ```ruby
@@ -38,7 +38,13 @@
38
38
  %>
39
39
 
40
40
  <header x-data="{ scrolled: false }" <%= '@scroll.window="scrolled = scrolled ? (window.scrollY > 5) : (window.scrollY > 60)"'.html_safe unless is_preview %>
41
- class="<%= is_preview ? 'bg-page' : "#{'vt-pinned-header ' if pin_header}sticky top-0 z-50 bg-page transition-shadow duration-300" %>"
41
+ <%# top offsets by whatever studio/banners/_stack rendered above us. The
42
+ stack publishes --studio-bars-h on :root; with no stack the fallback
43
+ 0px makes this identical to the old `top-0`, so an app that has not
44
+ adopted the stack is unaffected. The navbar never learns WHICH bars
45
+ rendered — only how tall they are. %>
46
+ style="<%= "top:var(--studio-bars-h, 0px);" unless is_preview %>"
47
+ class="<%= is_preview ? 'bg-page' : "#{'vt-pinned-header ' if pin_header}sticky z-50 bg-page transition-shadow duration-300" %>"
42
48
  :class="scrolled && 'shadow-lg border-b border-subtle is-scrolled'">
43
49
  <style>
44
50
  .user-nav-col { width: 14rem; }
@@ -4,19 +4,32 @@
4
4
  message = local_assigns.fetch(:message)
5
5
  actions = local_assigns[:actions]
6
6
 
7
+ # Branded off the app's OWN theme tokens rather than hardcoded hexes, so a host
8
+ # that retunes --color-warning / --color-danger gets a banner that matches it.
9
+ # The gradient is a translucent black wash over the token — deliberately not
10
+ # color-mix(), which would need a modern-browser floor for pure decoration, and
11
+ # deliberately not two hardcoded stops, which cannot follow a themed colour.
7
12
  tones = {
8
13
  environment: {
9
- background: "linear-gradient(90deg, #9d174d 0%, #f72585 100%)",
14
+ background: "linear-gradient(90deg, rgba(0,0,0,0.28) 0%, rgba(0,0,0,0.04) 100%), " \
15
+ "var(--color-warning, #FF7C47)",
10
16
  color: "#ffffff",
11
17
  shadow: "0 2px 8px rgba(0,0,0,0.25)"
12
18
  },
13
19
  impersonation: {
14
- background: "linear-gradient(90deg, #b91c1c 0%, #d97706 100%)",
20
+ background: "linear-gradient(90deg, rgba(0,0,0,0.30) 0%, rgba(0,0,0,0.06) 100%), " \
21
+ "var(--color-danger, #EF4444)",
15
22
  color: "#ffffff",
16
23
  shadow: "0 2px 8px rgba(0,0,0,0.25)"
17
24
  }
18
25
  }
19
26
 
27
+ # INTRINSIC height — content decides, and studio/banners/_stack MEASURES the
28
+ # result. An earlier cut declared a fixed height so the stack could compute its
29
+ # total server-side; that was rejected deliberately, because it cannot express
30
+ # a bar that needs to be taller, or two bars stacked, without every consuming
31
+ # app being reworked. The apps should respond to what the bar needs, not the
32
+ # other way round.
20
33
  density_styles = {
21
34
  compact: "font-size:12px; font-weight:700; padding:2px 12px;",
22
35
  normal: "font-size:14px; font-weight:700; padding:8px 16px;"
@@ -0,0 +1,102 @@
1
+ <%#
2
+ The bar stack — every pinned bar that sits ABOVE the navbar, as the navbar's
3
+ SIBLING rather than nested inside it.
4
+
5
+ Render it immediately before the navbar — the stack partial first, the navbar
6
+ partial second, as siblings. (Deliberately not written as ERB tags here: an
7
+ escaped tag inside an ERB comment ends the comment at its own closing marker
8
+ and dumps the rest of this block onto the page as text.)
9
+
10
+ Why a sibling and not nested (operator call, 2026-08-10): it composes. There is
11
+ already a second bar (impersonation), so this is not a 0-or-1 problem — it is
12
+ 0, 1 or 2, and growing. Nesting each new bar inside the navbar coupled two
13
+ unrelated components and meant every new bar edited the navbar. Here the bars
14
+ do not know the navbar exists, and the navbar does not know which bars
15
+ rendered — only how tall they are, via --studio-bars-h.
16
+
17
+ HOW THE HEIGHT IS KNOWN. The stack MEASURES itself and publishes the result, so
18
+ a bar that needs to be taller — or a second bar, or a third — just works, and no
19
+ consuming app is reworked to allow it. The apps respond to what the bars need.
20
+
21
+ A server-rendered estimate (count × --studio-bar-unit) paints first so the
22
+ common case has no flash, then a ResizeObserver replaces it with the truth on
23
+ the same frame. An earlier cut declared a fixed bar height to avoid the
24
+ observer; that was rejected because it could only ever express the standard
25
+ case, which is the case that needed no help.
26
+
27
+ The property is published on :root from an inline <style>, deliberately. A
28
+ custom property set on this element would be invisible to the navbar, because
29
+ custom properties inherit DOWN, not ACROSS to siblings — and putting it on
30
+ <body> would need every host to change its layout.
31
+
32
+ Locals (all optional):
33
+ preview — true inside a navbar-preview render; renders nothing, so a
34
+ preview copy cannot duplicate live chrome or publish a height.
35
+ devnet — forwarded to the environment bar (chip / message segment).
36
+ extra — forwarded to the environment bar (message segments).
37
+ impersonated_user / admin_user / stop_path — render the impersonation bar
38
+ too; omit them and it is skipped.
39
+ %>
40
+ <%
41
+ preview = local_assigns.fetch(:preview, false)
42
+
43
+ impersonated_user = local_assigns[:impersonated_user]
44
+ admin_user = local_assigns[:admin_user]
45
+ stop_path = local_assigns[:stop_path]
46
+ show_impersonation = !preview && impersonated_user && admin_user && stop_path
47
+
48
+ show_environment = !preview && Studio.show_environment_banner?
49
+
50
+ bars = capture do
51
+ if show_environment
52
+ concat(render("studio/banners/environment",
53
+ devnet: local_assigns.fetch(:devnet, false),
54
+ extra: local_assigns.fetch(:extra, [])))
55
+ end
56
+ if show_impersonation
57
+ concat(render("studio/banners/impersonation",
58
+ impersonated_user: impersonated_user,
59
+ admin_user: admin_user,
60
+ stop_path: stop_path))
61
+ end
62
+ end
63
+
64
+ # count { } and not count(true): show_impersonation is a truthy USER, not the
65
+ # literal true, and count(true) compares with ==. That published a one-bar
66
+ # height for a two-bar stack — the navbar would have sat under a bar.
67
+ bar_count = [show_environment, show_impersonation].count { |bar| bar }
68
+ %>
69
+ <% if bar_count.positive? %>
70
+ <%# First-paint estimate only — the observer below replaces it with the measured
71
+ height. Expressed against a token so an app that retunes the unit still gets
72
+ a sensible pre-measurement value. %>
73
+ <%= tag.style safe_join([":root{--studio-bars-h:calc(#{bar_count} * var(--studio-bar-unit, 47px))}"]) %>
74
+ <div class="studio-bar-stack sticky top-0 z-[60] w-full" data-studio-bar-stack><%= bars %></div>
75
+ <script>
76
+ // Publishes the stack's REAL height, so the navbar offsets by what the bars
77
+ // actually need. Idempotent and re-bound on Turbo navigation — a stale
78
+ // observer pointed at a detached node silently stops updating, and the
79
+ // navbar would then sit at yesterday's offset.
80
+ (function () {
81
+ var apply = function () {
82
+ var el = document.querySelector("[data-studio-bar-stack]");
83
+ if (!el) {
84
+ document.documentElement.style.removeProperty("--studio-bars-h");
85
+ return;
86
+ }
87
+ if (window.__studioBarObserver) window.__studioBarObserver.disconnect();
88
+ var publish = function () {
89
+ var h = Math.round(el.getBoundingClientRect().height);
90
+ if (h > 0) document.documentElement.style.setProperty("--studio-bars-h", h + "px");
91
+ };
92
+ publish();
93
+ if (window.ResizeObserver) {
94
+ window.__studioBarObserver = new ResizeObserver(publish);
95
+ window.__studioBarObserver.observe(el);
96
+ }
97
+ };
98
+ apply();
99
+ document.addEventListener("turbo:load", apply);
100
+ })();
101
+ </script>
102
+ <% end %>
data/lib/studio/engine.rb CHANGED
@@ -1,5 +1,44 @@
1
+ require_relative "log_rotation"
2
+
1
3
  module Studio
2
4
  class Engine < ::Rails::Engine
5
+ # Cap the local (development + test) log files, for every host app and
6
+ # every future one, with nobody running anything.
7
+ #
8
+ # ORDERING IS THE WHOLE TRICK — do not demote this to a bare initializer.
9
+ # Rails' `:initialize_logger` is a BOOTSTRAP initializer, so it runs before
10
+ # every railtie/engine initializer and does `Rails.logger ||= config.logger
11
+ # || <default>`. An engine that assigns `app.config.logger` from an ordinary
12
+ # initializer is a silent NO-OP: Rails.logger is already built. Verified,
13
+ # not assumed — a probe boot kept Rails' 100 MB cap and its own file.
14
+ # So this hands Rails the size BEFORE Rails builds the logger, which is
15
+ # exactly the knob `:initialize_logger` reads:
16
+ # ActiveSupport::Logger.new(config.default_log_file, 1, config.log_file_size)
17
+ # and Rails keeps ownership of the path, formatter, level, and tagging.
18
+ #
19
+ # `after: :load_environment_hook` pins the lower edge of that window for two
20
+ # reasons: config/environments/*.rb is loaded by `:load_environment_config`
21
+ # (declared `before: :load_environment_hook`), so the host's own choices are
22
+ # already visible here; and it keeps Railtie's implicit `after: <previous
23
+ # initializer>` chaining from dragging `studio.assets` forward with us.
24
+ # WHICH cap (and whether to touch anything at all) is Studio::LogRotation's
25
+ # decision — Rails-free, and unit-tested a branch at a time.
26
+ #
27
+ # The host's escape hatch, `Studio.local_log_max_bytes`, is read here rather
28
+ # than from config.x.<key>: an unset config.x key returns an empty
29
+ # ActiveSupport::OrderedOptions, NOT nil, so `config.x.foo || default`
30
+ # silently assigns the OrderedOptions and rotation then dies inside a
31
+ # rescued comparison. The behavioral test caught that; a config read-back
32
+ # would have called it green.
33
+ initializer "studio.logger", before: :initialize_logger, after: :load_environment_hook do |app|
34
+ cap = Studio::LogRotation.cap_for(
35
+ env: Rails.env,
36
+ host_logger: app.config.logger,
37
+ override: Studio.local_log_max_bytes
38
+ )
39
+ app.config.log_file_size = cap if cap
40
+ end
41
+
3
42
  initializer "studio.assets" do |app|
4
43
  app.config.assets.precompile += %w[
5
44
  studio/sticky_table_header.css
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Studio
4
+ # The decision behind the engine's `studio.logger` initializer: given the
5
+ # environment and the host's own choices, how large may the local log file
6
+ # grow before it rotates — or should the engine keep its hands off entirely?
7
+ #
8
+ # Deliberately Rails-free so the whole decision table is unit-testable in
9
+ # milliseconds. The initializer in Studio::Engine owns the other half of the
10
+ # problem — running EARLY enough for the answer to matter — and that half is
11
+ # covered by test/integration/log_rotation_test.rb, which boots real apps and
12
+ # watches the file rotate on disk.
13
+ module LogRotation
14
+ # Deliberate values, not defaults. Rails' own `config.load_defaults "7.1"`
15
+ # sets log_file_size to 100 MB for development AND test, each keeping one
16
+ # rotated sibling — up to ~400 MB of log per checkout, times every worktree
17
+ # on the machine. 16 MB still holds a full day of local request logs; 8 MB
18
+ # covers a whole test run. Raising these is a decision, not a default.
19
+ DEVELOPMENT_MAX_BYTES = 16 * 1024 * 1024
20
+ TEST_MAX_BYTES = 8 * 1024 * 1024
21
+
22
+ # The environments whose logs are plain local files worth capping. Held here
23
+ # rather than delegating to Rails.env.local? so that a future Rails adding a
24
+ # third "local" environment cannot silently change where this engine writes
25
+ # a cap.
26
+ CAPPED_ENVIRONMENTS = %w[development test].freeze
27
+
28
+ # Returns the byte cap to apply, or nil for "leave the host's logging
29
+ # exactly as it is".
30
+ #
31
+ # env the Rails environment name
32
+ # host_logger the host's own config.logger, if it named one
33
+ # override Studio.local_log_max_bytes — false opts out, an Integer
34
+ # sets the host's own cap, nil means "use ours"
35
+ def self.cap_for(env:, host_logger: nil, override: nil)
36
+ # Production (and QA, which boots as production) hands its stream to the
37
+ # platform. Never point that at a file.
38
+ return nil unless CAPPED_ENVIRONMENTS.include?(env.to_s)
39
+ # A host that named its own logger has already decided.
40
+ return nil if host_logger
41
+ # Explicit opt-out; Rails' own default returns.
42
+ return nil if override == false
43
+ # Explicit host cap.
44
+ return override if override
45
+
46
+ env.to_s == "test" ? TEST_MAX_BYTES : DEVELOPMENT_MAX_BYTES
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  module Studio
2
- VERSION = "0.32.3"
2
+ VERSION = "0.33.0"
3
3
  end
data/lib/studio.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "studio/version"
2
+ require "studio/log_rotation"
2
3
  require "studio/engine"
3
4
  require "studio/color_scale"
4
5
  require "studio/environment_banner"
@@ -136,6 +137,18 @@ module Studio
136
137
  mattr_accessor :impersonation_started_at_session_key, default: :impersonation_started_at
137
138
  mattr_accessor :impersonation_max_minutes, default: 30
138
139
 
140
+ # Cap for the host app's local (development + test) log file, in bytes.
141
+ # nil means "use the engine's defaults" — Studio::Engine::DEVELOPMENT_LOG_MAX_BYTES
142
+ # and ::TEST_LOG_MAX_BYTES. An Integer sets your own cap; `false` opts out and
143
+ # leaves Rails' own 100 MB default alone.
144
+ #
145
+ # UNLIKE every other setting here, this one is read during BOOT — before
146
+ # config/initializers/studio.rb is loaded — so it must be set earlier than the
147
+ # usual seam: in config/application.rb (after `require "studio"`) or in
148
+ # config/environments/development.rb. Setting it in an initializer is too late
149
+ # and does nothing.
150
+ mattr_accessor :local_log_max_bytes, default: nil
151
+
139
152
  # Default From: for engine-sent mail (magic links). Apps set this to their
140
153
  # verified sending address in config/initializers/studio.rb.
141
154
  mattr_accessor :mailer_from, default: nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: studio-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.3
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex McRitchie
@@ -266,6 +266,7 @@ files:
266
266
  - app/views/studio/banners/_email_status_button.html.erb
267
267
  - app/views/studio/banners/_environment.html.erb
268
268
  - app/views/studio/banners/_impersonation.html.erb
269
+ - app/views/studio/banners/_stack.html.erb
269
270
  - app/views/studio/board/_board.html.erb
270
271
  - app/views/studio/board/_card_shell.html.erb
271
272
  - app/views/studio/board/_column.html.erb
@@ -336,6 +337,7 @@ files:
336
337
  - lib/studio/image_cache.rb
337
338
  - lib/studio/link_resolution.rb
338
339
  - lib/studio/link_token.rb
340
+ - lib/studio/log_rotation.rb
339
341
  - lib/studio/mail_transport.rb
340
342
  - lib/studio/redis.rb
341
343
  - lib/studio/s3.rb