command_tower 0.16.0 → 0.17.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 +4 -4
- data/app/controllers/command_tower/application_controller.rb +1 -0
- data/app/controllers/concerns/command_tower/execution/client_compatibility_boundary.rb +39 -0
- data/app/errors/command_tower/errors/client_update_required_error.rb +27 -0
- data/app/serializers/command_tower/serializers/messaging/inbox.rb +2 -1
- data/app/services/command_tower/email_theme/resolver.rb +45 -0
- data/app/services/command_tower/messaging/notification_types/declaration.rb +14 -1
- data/app/services/command_tower/messaging/rendering/channel_renderer.rb +44 -13
- data/app/services/command_tower/messaging/rendering/inbox_document.rb +131 -0
- data/app/services/command_tower/messaging/rendering/inbox_document_renderer.rb +207 -0
- data/app/services/command_tower/messaging/rendering/template_resolver.rb +128 -0
- data/app/services/command_tower/services/client_compatibility/evaluate.rb +219 -0
- data/app/services/command_tower/services/messaging/inbox.rb +8 -1
- data/app/views/command_tower/email_verification_mailer/verify_email.html.erb +18 -17
- data/app/views/command_tower/messaging/rendering/email.html.erb +6 -5
- data/app/views/command_tower/password_reset_mailer/reset_password.html.erb +24 -23
- data/app/workflows/command_tower/workflows/auth/plain_text/login_workflow.rb +3 -0
- data/app/workflows/command_tower/workflows/auth/session/show_workflow.rb +3 -0
- data/app/workflows/command_tower/workflows/client_compatibility/evaluate_workflow.rb +83 -0
- data/app/workflows/command_tower/workflows/client_compatibility/recommendation_meta.rb +25 -0
- data/docs/api_reference.md +13 -2
- data/docs/extending.md +2 -1
- data/docs/host_integration_guide.md +35 -0
- data/docs/messaging_integration_guide.md +38 -0
- data/docs/upgrades/0.17.0.md +33 -0
- data/docs/upgrades/README.md +1 -0
- data/lib/command_tower/client_compatibility/version.rb +45 -0
- data/lib/command_tower/client_compatibility.rb +23 -0
- data/lib/command_tower/configuration/config.rb +6 -0
- data/lib/command_tower/configuration/email_theme/config.rb +69 -0
- data/lib/command_tower/configuration/registry/client_compatibility/binding_definition.rb +42 -0
- data/lib/command_tower/configuration/registry/client_compatibility/config.rb +353 -0
- data/lib/command_tower/configuration/registry/client_compatibility/contract_definition.rb +16 -0
- data/lib/command_tower/configuration/registry/client_compatibility/entity_requirement_definition.rb +67 -0
- data/lib/command_tower/configuration/registry/client_compatibility/minimum_overrides.rb +46 -0
- data/lib/command_tower/configuration/registry/client_compatibility/platform_definition.rb +66 -0
- data/lib/command_tower/configuration/registry/config.rb +14 -0
- data/lib/command_tower/configuration/registry/inbox_presentations/config.rb +105 -0
- data/lib/command_tower/configuration/registry/inbox_presentations/presentation_definition.rb +71 -0
- data/lib/command_tower/current.rb +1 -0
- data/lib/command_tower/engine.rb +4 -0
- data/lib/command_tower/inbox_presentations.rb +19 -0
- data/lib/command_tower/version.rb +1 -1
- metadata +24 -2
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Registry
|
|
8
|
+
module InboxPresentations
|
|
9
|
+
class PresentationDefinition
|
|
10
|
+
include ClassComposer::Generator
|
|
11
|
+
|
|
12
|
+
add_composer :composer_class,
|
|
13
|
+
desc: "String class name of the registered presentation composer " \
|
|
14
|
+
"(`.call(communication:, recipient_id:) -> Hash`), resolved via `.constantize` " \
|
|
15
|
+
"at InboxDocumentRenderer render time — never at registration time",
|
|
16
|
+
allowed: String,
|
|
17
|
+
default: ""
|
|
18
|
+
|
|
19
|
+
# Explicit output projection (Rich Messaging corrective slice —
|
|
20
|
+
# ServiceResult/context leak fix). `InboxDocumentRenderer#presentation_block`
|
|
21
|
+
# slices the composer's raw result down to exactly these keys before
|
|
22
|
+
# it ever reaches `content.blocks[].data` — every other key (declared
|
|
23
|
+
# `ApplicationService` inputs, incidental intermediate context state,
|
|
24
|
+
# or anything else a composer happens to set) is dropped
|
|
25
|
+
# unconditionally, regardless of whether the composer is an
|
|
26
|
+
# `ApplicationService` or a plain Hash-returning class. This is a
|
|
27
|
+
# declared allow-list owned by the registration, not an inference
|
|
28
|
+
# from `ServiceResult`/`ApplicationService` argument metadata.
|
|
29
|
+
add_composer :output_keys,
|
|
30
|
+
desc: "Array of Symbol keys that are the ONLY keys copied from the composer's " \
|
|
31
|
+
"result onto the Inbox wire (`content.blocks[].data`) — every other " \
|
|
32
|
+
"context/result key (composer inputs, intermediate state, anything else) " \
|
|
33
|
+
"is dropped at render time, regardless of composer shape",
|
|
34
|
+
allowed: Array,
|
|
35
|
+
default: []
|
|
36
|
+
|
|
37
|
+
attr_accessor :owner, :id
|
|
38
|
+
|
|
39
|
+
def validate_definition!(key:)
|
|
40
|
+
self.id = key.to_s
|
|
41
|
+
self.owner = owner&.to_sym || :host
|
|
42
|
+
self.composer_class = require_present_string!(composer_class, field: "composer_class", key:)
|
|
43
|
+
self.output_keys = require_present_output_keys!(output_keys, key:)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def require_present_string!(value, field:, key:)
|
|
49
|
+
text = value.to_s.strip
|
|
50
|
+
if text.empty?
|
|
51
|
+
raise CommandTower::InboxPresentations::InvalidPresentationDefinitionError,
|
|
52
|
+
"inbox presentation #{key} is missing #{field}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
text
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def require_present_output_keys!(value, key:)
|
|
59
|
+
keys = Array(value).map { |entry| entry.to_s.strip }
|
|
60
|
+
if keys.empty? || keys.any?(&:empty?)
|
|
61
|
+
raise CommandTower::InboxPresentations::InvalidPresentationDefinitionError,
|
|
62
|
+
"inbox presentation #{key} is missing output_keys"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
keys.map(&:to_sym)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/command_tower/engine.rb
CHANGED
|
@@ -22,12 +22,15 @@ module CommandTower
|
|
|
22
22
|
# ensure defaults are instantiated and all variables are assigned
|
|
23
23
|
CommandTower.config.class_composer_assign_defaults!(children: true)
|
|
24
24
|
CommandTower::CredentialResolution::SmtpActionMailerBridge.apply!
|
|
25
|
+
CommandTower.config.registry.client_compatibility.apply_env_overlay!
|
|
25
26
|
|
|
26
27
|
unless Rails.env.test?
|
|
27
28
|
CommandTower.config.impersonation.validate!
|
|
28
29
|
CommandTower.config.registry.audit.finalize!
|
|
29
30
|
CommandTower.config.registry.admin_workspace.finalize!
|
|
30
31
|
CommandTower.config.registry.principal_capabilities.finalize!
|
|
32
|
+
CommandTower.config.registry.client_compatibility.finalize!
|
|
33
|
+
CommandTower.config.registry.inbox_presentations.finalize!
|
|
31
34
|
CommandTower.config.admin_scope.finalize!
|
|
32
35
|
# Now that we can confirm all variables are defined, freeze all objects an their children
|
|
33
36
|
CommandTower.config.class_composer_freeze_objects!(behavior: :raise, children: true)
|
|
@@ -62,6 +65,7 @@ module CommandTower
|
|
|
62
65
|
entities = CommandTower::Authorization::Entity.entities
|
|
63
66
|
CommandTower.config.registry.admin_workspace.validate_required_entities!(entities)
|
|
64
67
|
CommandTower.config.registry.principal_capabilities.validate_required_entities!(entities)
|
|
68
|
+
CommandTower.config.registry.client_compatibility.validate!(entities)
|
|
65
69
|
CommandTower.config.admin_scope.validate_scoped_tools!
|
|
66
70
|
end
|
|
67
71
|
CommandTower::Logging::Subscriber.attach!
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CommandTower
|
|
4
|
+
# Rich Messaging Slice 2.5 — registry of registered Inbox presentation
|
|
5
|
+
# capabilities (semantic keys such as `pickem.make_picks`) mapped to a
|
|
6
|
+
# trusted, host- or CommandTower-owned composer class. See
|
|
7
|
+
# artifacts/visual-improvements/rich-messaging/authority/RICH_MESSAGING_PRESENTATION_AUTHORITY.md
|
|
8
|
+
# Part I and
|
|
9
|
+
# artifacts/visual-improvements/rich-messaging/authority/RICH_MESSAGING_RUBY_INBOX_DEFINITION_DISCOVERY.md §9.
|
|
10
|
+
module InboxPresentations
|
|
11
|
+
class Error < CommandTower::Error; end
|
|
12
|
+
|
|
13
|
+
class UnregisteredCapabilityError < Error; end
|
|
14
|
+
class DuplicateCapabilityError < Error; end
|
|
15
|
+
class InvalidKeyError < Error; end
|
|
16
|
+
class InvalidPresentationDefinitionError < Error; end
|
|
17
|
+
class FrozenRegistryError < Error; end
|
|
18
|
+
end
|
|
19
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: command_tower
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- matt-taylor
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: phonelib
|
|
@@ -231,6 +231,7 @@ files:
|
|
|
231
231
|
- app/controllers/concerns/command_tower/auth/invalid_credentials_deserializer_renderer.rb
|
|
232
232
|
- app/controllers/concerns/command_tower/auth/password_recovery_session_boundary.rb
|
|
233
233
|
- app/controllers/concerns/command_tower/auth/signup_session_boundary.rb
|
|
234
|
+
- app/controllers/concerns/command_tower/execution/client_compatibility_boundary.rb
|
|
234
235
|
- app/controllers/concerns/command_tower/execution/http_boundary.rb
|
|
235
236
|
- app/deserializers/command_tower/deserializers/admin/messaging/create_announcement_deserializer.rb
|
|
236
237
|
- app/deserializers/command_tower/deserializers/admin/scope_parameter.rb
|
|
@@ -309,6 +310,7 @@ files:
|
|
|
309
310
|
- app/errors/command_tower/errors/auth/signup_session_rate_limit_error.rb
|
|
310
311
|
- app/errors/command_tower/errors/auth/verification_code_invalid_error.rb
|
|
311
312
|
- app/errors/command_tower/errors/auth/verification_send_failed_error.rb
|
|
313
|
+
- app/errors/command_tower/errors/client_update_required_error.rb
|
|
312
314
|
- app/errors/command_tower/errors/continuation_exhausted_error.rb
|
|
313
315
|
- app/errors/command_tower/errors/forbidden_error.rb
|
|
314
316
|
- app/errors/command_tower/errors/internal_error.rb
|
|
@@ -409,6 +411,7 @@ files:
|
|
|
409
411
|
- app/services/command_tower/clients/transport/request.rb
|
|
410
412
|
- app/services/command_tower/clients/transport/response.rb
|
|
411
413
|
- app/services/command_tower/clients/url.rb
|
|
414
|
+
- app/services/command_tower/email_theme/resolver.rb
|
|
412
415
|
- app/services/command_tower/identity/phone/normalizer.rb
|
|
413
416
|
- app/services/command_tower/identity/phone_verification/sms_configuration.rb
|
|
414
417
|
- app/services/command_tower/identity/phone_verification/sms_transport.rb
|
|
@@ -592,11 +595,14 @@ files:
|
|
|
592
595
|
- app/services/command_tower/messaging/recipient_readiness/recipient_result.rb
|
|
593
596
|
- app/services/command_tower/messaging/recipient_readiness/unknown_channel_error.rb
|
|
594
597
|
- app/services/command_tower/messaging/rendering/channel_renderer.rb
|
|
598
|
+
- app/services/command_tower/messaging/rendering/inbox_document.rb
|
|
599
|
+
- app/services/command_tower/messaging/rendering/inbox_document_renderer.rb
|
|
595
600
|
- app/services/command_tower/messaging/rendering/render_error.rb
|
|
596
601
|
- app/services/command_tower/messaging/rendering/rendered_payload.rb
|
|
597
602
|
- app/services/command_tower/messaging/rendering/rendered_push_payload.rb
|
|
598
603
|
- app/services/command_tower/messaging/rendering/rendered_pushover_payload.rb
|
|
599
604
|
- app/services/command_tower/messaging/rendering/rendered_sms_payload.rb
|
|
605
|
+
- app/services/command_tower/messaging/rendering/template_resolver.rb
|
|
600
606
|
- app/services/command_tower/secrets.rb
|
|
601
607
|
- app/services/command_tower/secrets/cleanse.rb
|
|
602
608
|
- app/services/command_tower/secrets/generate.rb
|
|
@@ -660,6 +666,7 @@ files:
|
|
|
660
666
|
- app/services/command_tower/services/auth/signup_session/validate.rb
|
|
661
667
|
- app/services/command_tower/services/auth/tombstone_user.rb
|
|
662
668
|
- app/services/command_tower/services/auth/username_availability.rb
|
|
669
|
+
- app/services/command_tower/services/client_compatibility/evaluate.rb
|
|
663
670
|
- app/services/command_tower/services/impersonation/create.rb
|
|
664
671
|
- app/services/command_tower/services/impersonation/end.rb
|
|
665
672
|
- app/services/command_tower/services/impersonation/record_activity.rb
|
|
@@ -737,6 +744,8 @@ files:
|
|
|
737
744
|
- app/workflows/command_tower/workflows/auth/signup_session/authenticate_workflow.rb
|
|
738
745
|
- app/workflows/command_tower/workflows/auth/signup_session/create_workflow.rb
|
|
739
746
|
- app/workflows/command_tower/workflows/auth/username_availability_workflow.rb
|
|
747
|
+
- app/workflows/command_tower/workflows/client_compatibility/evaluate_workflow.rb
|
|
748
|
+
- app/workflows/command_tower/workflows/client_compatibility/recommendation_meta.rb
|
|
740
749
|
- app/workflows/command_tower/workflows/impersonation/error_mapping.rb
|
|
741
750
|
- app/workflows/command_tower/workflows/impersonation/start_workflow.rb
|
|
742
751
|
- app/workflows/command_tower/workflows/impersonation/stop_workflow.rb
|
|
@@ -816,6 +825,7 @@ files:
|
|
|
816
825
|
- docs/upgrades/0.14.0.md
|
|
817
826
|
- docs/upgrades/0.15.0.md
|
|
818
827
|
- docs/upgrades/0.16.0.md
|
|
828
|
+
- docs/upgrades/0.17.0.md
|
|
819
829
|
- docs/upgrades/README.md
|
|
820
830
|
- lib/command_tower.rb
|
|
821
831
|
- lib/command_tower/admin_scope.rb
|
|
@@ -838,6 +848,8 @@ files:
|
|
|
838
848
|
- lib/command_tower/authorization/effective_entity_grants.rb
|
|
839
849
|
- lib/command_tower/authorization/entity.rb
|
|
840
850
|
- lib/command_tower/authorization/role.rb
|
|
851
|
+
- lib/command_tower/client_compatibility.rb
|
|
852
|
+
- lib/command_tower/client_compatibility/version.rb
|
|
841
853
|
- lib/command_tower/configuration/account_deletion/config.rb
|
|
842
854
|
- lib/command_tower/configuration/admin/config.rb
|
|
843
855
|
- lib/command_tower/configuration/admin_scope/config.rb
|
|
@@ -850,6 +862,7 @@ files:
|
|
|
850
862
|
- lib/command_tower/configuration/credentials/smtp.rb
|
|
851
863
|
- lib/command_tower/configuration/credentials/twilio.rb
|
|
852
864
|
- lib/command_tower/configuration/email/config.rb
|
|
865
|
+
- lib/command_tower/configuration/email_theme/config.rb
|
|
853
866
|
- lib/command_tower/configuration/identity/config.rb
|
|
854
867
|
- lib/command_tower/configuration/identity/phone_verification.rb
|
|
855
868
|
- lib/command_tower/configuration/impersonation/config.rb
|
|
@@ -873,7 +886,15 @@ files:
|
|
|
873
886
|
- lib/command_tower/configuration/registry/admin_workspace/tool_definition.rb
|
|
874
887
|
- lib/command_tower/configuration/registry/audit/config.rb
|
|
875
888
|
- lib/command_tower/configuration/registry/audit/event_definition.rb
|
|
889
|
+
- lib/command_tower/configuration/registry/client_compatibility/binding_definition.rb
|
|
890
|
+
- lib/command_tower/configuration/registry/client_compatibility/config.rb
|
|
891
|
+
- lib/command_tower/configuration/registry/client_compatibility/contract_definition.rb
|
|
892
|
+
- lib/command_tower/configuration/registry/client_compatibility/entity_requirement_definition.rb
|
|
893
|
+
- lib/command_tower/configuration/registry/client_compatibility/minimum_overrides.rb
|
|
894
|
+
- lib/command_tower/configuration/registry/client_compatibility/platform_definition.rb
|
|
876
895
|
- lib/command_tower/configuration/registry/config.rb
|
|
896
|
+
- lib/command_tower/configuration/registry/inbox_presentations/config.rb
|
|
897
|
+
- lib/command_tower/configuration/registry/inbox_presentations/presentation_definition.rb
|
|
877
898
|
- lib/command_tower/configuration/registry/principal_capabilities/capability_definition.rb
|
|
878
899
|
- lib/command_tower/configuration/registry/principal_capabilities/config.rb
|
|
879
900
|
- lib/command_tower/configuration/signup_session/config.rb
|
|
@@ -896,6 +917,7 @@ files:
|
|
|
896
917
|
- lib/command_tower/impersonation/apply_overlay.rb
|
|
897
918
|
- lib/command_tower/impersonation/clear_overlay_for_audit.rb
|
|
898
919
|
- lib/command_tower/impersonation/establish_identity.rb
|
|
920
|
+
- lib/command_tower/inbox_presentations.rb
|
|
899
921
|
- lib/command_tower/install/baseline.rb
|
|
900
922
|
- lib/command_tower/install/doctor.rb
|
|
901
923
|
- lib/command_tower/intervention/severity.rb
|