hecks 3.9.1 → 3.11.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/examples/pizzas/bluebook/pizzas.bluebook +29 -0
- data/examples/pizzas/bluebook/pizzas.hecksagon +7 -0
- data/exe/hecks +4 -4
- data/lib/hecks/adapters/driven/d1.rb +2 -10
- data/lib/hecks/adapters/driven/heki.adapter +1 -1
- data/lib/hecks/adapters/driven/heki.rb +2 -12
- data/lib/hecks/adapters/driven/lambda.adapter +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +3 -18
- data/lib/hecks/adapters/driven/postgres.rb +4 -11
- data/lib/hecks/adapters/driven/sqlite.adapter +1 -1
- data/lib/hecks/adapters/driven/sqlite.rb +2 -10
- data/lib/hecks/adapters/driving/admission.rb +46 -0
- data/lib/hecks/adapters/driving/cli/nesting.rb +36 -0
- data/lib/hecks/adapters/driving/cli/shorthand.rb +88 -0
- data/lib/hecks/adapters/driving/cli.rb +127 -0
- data/lib/hecks/adapters/driving/cli_runner/answers.rb +160 -0
- data/lib/hecks/adapters/driving/cli_runner/resolution.rb +155 -0
- data/lib/hecks/adapters/driving/cli_runner/settling.rb +120 -0
- data/lib/hecks/adapters/driving/cli_runner/streaming.rb +93 -0
- data/lib/hecks/adapters/driving/cli_runner/suggestions.rb +47 -0
- data/lib/hecks/adapters/driving/cli_runner.rb +69 -0
- data/lib/hecks/adapters/driving/command_request.rb +121 -0
- data/lib/hecks/adapters/driving/handle.rb +214 -0
- data/lib/hecks/adapters/driving/json.rb +136 -0
- data/lib/hecks/adapters/driving/launcher_options.rb +267 -0
- data/lib/hecks/adapters/driving/mcp/properties.rb +49 -0
- data/lib/hecks/adapters/driving/mcp/tool_calls.rb +116 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/auditing.rb +53 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/calling.rb +71 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions/reading.rb +99 -0
- data/lib/hecks/adapters/driving/mcp/tool_definitions.rb +18 -0
- data/lib/hecks/adapters/driving/mcp.rb +159 -0
- data/lib/hecks/adapters/driving/mcp_guide_cache.rb +78 -0
- data/lib/hecks/adapters/driving/mcp_scope/argument_policy.rb +97 -0
- data/lib/hecks/adapters/driving/mcp_scope/env_problems.rb +69 -0
- data/lib/hecks/adapters/driving/mcp_scope/presenter.rb +83 -0
- data/lib/hecks/adapters/driving/mcp_scope.rb +213 -0
- data/lib/hecks/adapters/driving/ruby/aggregate_module.rb +171 -0
- data/lib/hecks/adapters/driving/ruby/chapter.rb +91 -0
- data/lib/hecks/adapters/driving/ruby.rb +83 -0
- data/lib/hecks/adapters/driving/usage_cache.rb +144 -0
- data/lib/hecks/{doors.rb → adapters/driving.rb} +10 -6
- data/lib/hecks/behaviors/expectations/boot.rb +1 -1
- data/lib/hecks/bench/ruby_runner.rb +1 -1
- data/lib/hecks/bluebook/ask_resolution.rb +130 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +8 -2
- data/lib/hecks/bluebook/assembly/contracts/rules.rb +4 -2
- data/lib/hecks/bluebook/assembly/contracts/structure.rb +3 -1
- data/lib/hecks/bluebook/assembly/marks.rb +1 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/command.rb +13 -8
- data/lib/hecks/bluebook/behaviour/policy.rb +30 -0
- data/lib/hecks/bluebook/capabilities/attribute_values.rb +72 -0
- data/lib/hecks/bluebook/capabilities.rb +91 -9
- data/lib/hecks/bluebook/domain_port.rb +16 -4
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +18 -6
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +13 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/computed_sources.rb +98 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/fan_out_rows.rb +42 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/projected_fields.rb +14 -2
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/provisions.rb +69 -3
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation/with_projections.rb +17 -10
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +5 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -0
- data/lib/hecks/bluebook/dsl/command_builder/mutations.rb +8 -1
- data/lib/hecks/bluebook/dsl/command_builder/operands.rb +121 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +2 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +10 -1
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +45 -2
- data/lib/hecks/bluebook/dsl/policy_builder.rb +47 -10
- data/lib/hecks/bluebook/dsl/rule_reference.rb +7 -4
- data/lib/hecks/bluebook/dsl/world_builder.rb +1 -1
- data/lib/hecks/bluebook/expression/ast_json/emitters.rb +6 -0
- data/lib/hecks/bluebook/expression/ast_json.rb +9 -6
- data/lib/hecks/bluebook/expression/ast_reader.rb +14 -9
- data/lib/hecks/bluebook/expression/projection.json +36 -0
- data/lib/hecks/bluebook/expression/resolver/operations.rb +31 -0
- data/lib/hecks/bluebook/expression/resolver/parsing.rb +38 -5
- data/lib/hecks/bluebook/expression/resolver/scanning.rb +22 -5
- data/lib/hecks/bluebook/expression/resolver/values.rb +10 -0
- data/lib/hecks/bluebook/expression/resolver.rb +20 -1
- data/lib/hecks/bluebook/hecksagon.rb +23 -3
- data/lib/hecks/bluebook/lifecycle.rb +22 -3
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +13 -1
- data/lib/hecks/bluebook/meta_validator/modes.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/readings.rb +18 -1
- data/lib/hecks/bluebook/meta_validator/reconstruction/heads.rb +2 -1
- data/lib/hecks/bluebook/meta_validator/shapes.rb +5 -0
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +1 -1
- data/lib/hecks/bluebook/meta_validator.rb +12 -12
- data/lib/hecks/bluebook/model_check/ask_checks.rb +71 -0
- data/lib/hecks/bluebook/model_check/policy_checks.rb +2 -1
- data/lib/hecks/bluebook/model_check/reference_checks.rb +70 -0
- data/lib/hecks/bluebook/model_check.rb +8 -2
- data/lib/hecks/bluebook/policy.rb +4 -2
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- data/lib/hecks/bluebook/synthesizer.rb +2 -0
- data/lib/hecks/bluebook.rb +1 -0
- data/lib/hecks/cli/command_table.rb +1 -1
- data/lib/hecks/cli/console.rb +2 -1
- data/lib/hecks/cli/document.rb +1 -1
- data/lib/hecks/cli/launcher_words.rb +4 -4
- data/lib/hecks/cli/mcp.rb +4 -4
- data/lib/hecks/cli/project_cli/launcher_source.rb +2 -2
- data/lib/hecks/cli/project_cli/templates.rb +5 -5
- data/lib/hecks/cli/project_cli.rb +9 -6
- data/lib/hecks/cli/run.rb +2 -2
- data/lib/hecks/cli/smoke_http/checks.rb +4 -1
- data/lib/hecks/cli/smoke_http/transport.rb +3 -3
- data/lib/hecks/cli/smoke_http.rb +3 -0
- data/lib/hecks/codemod.rb +5 -2
- data/lib/hecks/corpus/routes.rb +7 -0
- data/lib/hecks/corpus/rust.rb +3 -2
- data/lib/hecks/deploy/bluebook/deploy.bluebook +124 -2
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +8 -0
- data/lib/hecks/deploy/oidc.json +16 -3
- data/lib/hecks/doc/reference/rendering.rb +6 -3
- data/lib/hecks/forms/app/commands.rb +8 -7
- data/lib/hecks/forms/app/queries.rb +2 -1
- data/lib/hecks/forms/app.rb +1 -1
- data/lib/hecks/forms/record_renderer.rb +1 -1
- data/lib/hecks/framework/bluebook/privacy.bluebook +11 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +4 -1
- data/lib/hecks/fuzzing/failure_triage.rb +2 -1
- data/lib/hecks/fuzzing/mutation/run.rb +11 -4
- data/lib/hecks/fuzzing/properties/catalog.rb +6 -4
- data/lib/hecks/fuzzing/properties/guaranteed_by_construction.rb +18 -11
- data/lib/hecks/fuzzing/properties/guards.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency/saga_redelivery.rb +1 -1
- data/lib/hecks/fuzzing/self_consistency.rb +6 -2
- data/lib/hecks/fuzzing/shrinker.rb +3 -1
- data/lib/hecks/fuzzing/value_generator.rb +19 -5
- data/lib/hecks/gate/stages.yml +4 -10
- data/lib/hecks/grammar/evolve.rb +1 -1
- data/lib/hecks/grammar/expression_operators.json +372 -0
- data/lib/hecks/grammar/operators.rb +3 -1
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +10 -10
- data/lib/hecks/hecks/adapters/codebase/inspection/rubycritic.rb +35 -0
- data/lib/hecks/hecks/adapters/codebase/inspection.rb +104 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +12 -2
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +2 -1
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +1 -1
- data/lib/hecks/hecks/adapters/cost_explorer.rb +8 -5
- data/lib/hecks/hecks/adapters/deploy_toolchain/clearing.rb +51 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain/statuses.rb +2 -1
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +2 -0
- data/lib/hecks/hecks/adapters/finding_github.rb +13 -6
- data/lib/hecks/hecks/adapters/first_admin.rb +2 -2
- data/lib/hecks/hecks/adapters/github_rulesets.rb +6 -3
- data/lib/hecks/hecks/adapters/in_process_boot.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +1 -1
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +10 -20
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +28 -5
- data/lib/hecks/hecks/adapters/local_files.rb +2 -2
- data/lib/hecks/hecks/adapters/rehearsal/audit_report.rb +107 -0
- data/lib/hecks/hecks/adapters/rehearsal/census.rb +71 -0
- data/lib/hecks/hecks/adapters/rehearsal/declaration.rb +133 -0
- data/lib/hecks/hecks/adapters/rehearsal/environment.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/inquiry.rb +142 -0
- data/lib/hecks/hecks/adapters/rehearsal/memory_store.rb +96 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_census.rb +100 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_reading.rb +69 -0
- data/lib/hecks/hecks/adapters/rehearsal/postgres_store.rb +129 -0
- data/lib/hecks/hecks/adapters/rehearsal/rows.rb +41 -0
- data/lib/hecks/hecks/adapters/rehearsal/rust_audit.rb +83 -0
- data/lib/hecks/hecks/adapters/rehearsal/subject.rb +104 -0
- data/lib/hecks/hecks/adapters/rehearsal.rb +54 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/rehearsal_store.rb +81 -0
- data/lib/hecks/hecks/adapters/site_toolchain/role_prober.rb +78 -0
- data/lib/hecks/hecks/adapters/site_toolchain.rb +29 -4
- data/lib/hecks/hecks/adapters/terminal.rb +13 -11
- data/lib/hecks/hecks/adapters/world_clearing.rb +65 -0
- data/lib/hecks/hecks/codebase.behaviors +13 -1
- data/lib/hecks/hecks/codebase.bluebook +239 -5
- data/lib/hecks/hecks/custodian.behaviors +24 -6
- data/lib/hecks/hecks/custodian.bluebook +6 -1227
- data/lib/hecks/hecks/deploy.behaviors +1 -1
- data/lib/hecks/hecks/deploy.world +1 -3
- data/lib/hecks/hecks/hecks.behaviors +1 -1
- data/lib/hecks/hecks/hecks.hecksagon +61 -18
- data/lib/hecks/hecks/hecks.world +11 -10
- data/lib/hecks/hecks/rehearsal.bluebook +477 -0
- data/lib/hecks/hecks/site.behaviors +1 -1
- data/lib/hecks/hecks/site.world +0 -1
- data/lib/hecks/hecks/tooling.bluebook +1238 -0
- data/lib/hecks/indifferent_key.rb +20 -0
- data/lib/hecks/language/adapter.bluebook +13 -3
- data/lib/hecks/language/bluebook/aggregate.bluebook +23 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +15 -0
- data/lib/hecks/language/bluebook/entity.bluebook +18 -0
- data/lib/hecks/language/bluebook/policy.bluebook +9 -1
- data/lib/hecks/language/bluebook/query.bluebook +1 -1
- data/lib/hecks/language/bluebook/vocabulary.bluebook +11 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +1 -1
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +22 -0
- data/lib/hecks/language/oidc.json +10 -0
- data/lib/hecks/language/port.bluebook +4 -4
- data/lib/hecks/literal.rb +12 -3
- data/lib/hecks/ports/key_vault.rb +7 -2
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +21 -10
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/boot.rb +4 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +2 -1
- data/lib/hecks/ports/persistence/repository_factory.rb +6 -3
- data/lib/hecks/projections/deploy/box/templates/deploy-box.sh.tmpl +29 -0
- data/lib/hecks/projections/deploy/box/templates/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/fargate/settings/tuning.rb +15 -0
- data/lib/hecks/projections/deploy/fargate/settings.rb +3 -1
- data/lib/hecks/projections/deploy/fargate/stack/readers.rb +1 -0
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/shared.rb +5 -2
- data/lib/hecks/projections/deploy/templates/fargate/Makefile.tmpl +7 -4
- data/lib/hecks/projections/model/deviations.rb +2 -2
- data/lib/hecks/projections/model.rb +2 -2
- data/lib/hecks/projections/oidc.rb +13 -1
- data/lib/hecks/projections/shape.rb +5 -2
- data/lib/hecks/projections/site/cms_editor/attributes.rb +95 -0
- data/lib/hecks/projections/site/cms_editor/blocks.rb +157 -0
- data/lib/hecks/projections/site/cms_editor/checks.rb +77 -0
- data/lib/hecks/projections/site/cms_editor/clearing.rb +70 -0
- data/lib/hecks/projections/site/cms_editor/color.rb +124 -0
- data/lib/hecks/projections/site/cms_editor/composition.rb +42 -0
- data/lib/hecks/projections/site/cms_editor/destructive.rb +61 -0
- data/lib/hecks/projections/site/cms_editor/drafts.rb +102 -0
- data/lib/hecks/projections/site/cms_editor/hints.rb +74 -0
- data/lib/hecks/projections/site/cms_editor/icons.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/key_kinds.rb +31 -0
- data/lib/hecks/projections/site/cms_editor/limits.rb +72 -0
- data/lib/hecks/projections/site/cms_editor/media.rb +85 -0
- data/lib/hecks/projections/site/cms_editor/moment.rb +34 -0
- data/lib/hecks/projections/site/cms_editor/palette.rb +115 -0
- data/lib/hecks/projections/site/cms_editor/pickers.rb +85 -0
- data/lib/hecks/projections/site/cms_editor/pretty.rb +40 -0
- data/lib/hecks/projections/site/cms_editor/preview.rb +91 -0
- data/lib/hecks/projections/site/cms_editor/relations.rb +92 -0
- data/lib/hecks/projections/site/cms_editor/scale_checks.rb +66 -0
- data/lib/hecks/projections/site/cms_editor/scheduling.rb +150 -0
- data/lib/hecks/projections/site/cms_editor/schema.rb +161 -0
- data/lib/hecks/projections/site/cms_editor/setting.rb +130 -0
- data/lib/hecks/projections/site/cms_editor/targets.rb +86 -0
- data/lib/hecks/projections/site/cms_editor/templates/package.json.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/app.ts.tmpl +370 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/assets.ts.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/membership.ts.tmpl +87 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/session.ts.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/auth/sso.ts.tmpl +20 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/app.css.tmpl +412 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/autosave.js.tmpl +144 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/blocks.js.tmpl +500 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_doc.js.tmpl +175 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/body_editor.js.tmpl +418 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/epoch.js.tmpl +61 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/forms.js.tmpl +210 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/lists.js.tmpl +40 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/main.js.tmpl +26 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/media_picker.js.tmpl +232 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/moments.js.tmpl +73 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/pickers.js.tmpl +152 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/preview.js.tmpl +98 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/shell.js.tmpl +140 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/browser/toast.js.tmpl +66 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/choices.ts.tmpl +99 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/commands.ts.tmpl +133 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/config.ts.tmpl +29 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/flash.ts.tmpl +52 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/host.ts.tmpl +43 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/handler.ts.tmpl +177 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/multipart.ts.tmpl +53 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/sniff.ts.tmpl +94 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/media/storage.ts.tmpl +50 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/names.ts.tmpl +36 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/schema.ts.tmpl +214 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/server.ts.tmpl +65 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/availability.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/block_list.js.tmpl +213 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/blocks.ts.tmpl +275 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_model.js.tmpl +123 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/body_parse.js.tmpl +320 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/detail.ts.tmpl +88 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/dialogs.ts.tmpl +43 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/fields.ts.tmpl +275 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/html.ts.tmpl +61 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/icons.ts.tmpl +15 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/input.ts.tmpl +92 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/links.ts.tmpl +100 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/moments.ts.tmpl +44 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/outline.ts.tmpl +63 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pages.ts.tmpl +213 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/paging.ts.tmpl +82 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/pickers.ts.tmpl +110 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/preview.ts.tmpl +87 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/related.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/schedule.ts.tmpl +160 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/shell.ts.tmpl +211 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/table.ts.tmpl +151 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/theme.js.tmpl +16 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/values.ts.tmpl +69 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/words.ts.tmpl +97 -0
- data/lib/hecks/projections/site/cms_editor/templates/src/ui/world.ts.tmpl +35 -0
- data/lib/hecks/projections/site/cms_editor/templates/tsconfig.json.tmpl +17 -0
- data/lib/hecks/projections/site/cms_editor/theme.rb +29 -0
- data/lib/hecks/projections/site/cms_editor/theme_checks.rb +57 -0
- data/lib/hecks/projections/site/cms_editor.rb +133 -0
- data/lib/hecks/projections/site/role_probe.rb +74 -0
- data/lib/hecks/projector/cli_audience.rb +2 -1
- data/lib/hecks/projector/cli_projector/listing.rb +1 -1
- data/lib/hecks/projector/cli_projector/option_specs.rb +1 -1
- data/lib/hecks/projector/docs_projector/closing.rb +1 -1
- data/lib/hecks/projector/docs_projector.rb +1 -1
- data/lib/hecks/projector/exporter/bindings.rb +40 -10
- data/lib/hecks/projector/exporter/capability_values.rb +55 -0
- data/lib/hecks/projector/narrate_projector/reactions.rb +1 -1
- data/lib/hecks/projector/target.rb +11 -0
- data/lib/hecks/projector.rb +32 -5
- data/lib/hecks/quality_control/adapters/github_checks.rb +12 -8
- data/lib/hecks/quality_control/adapters/github_issues.rb +8 -4
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +2 -2
- data/lib/hecks/quality_control/cli/qa_sweep/checks/shrinking.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +1 -1
- data/lib/hecks/quality_control/cli/qa_sweep.rb +1 -1
- data/lib/hecks/quality_control/quality_control.bluebook +6 -2
- data/lib/hecks/release/approval.rb +64 -0
- data/lib/hecks/router/{door.rb → aggregate_reader.rb} +5 -4
- data/lib/hecks/router/namespace_installer.rb +16 -16
- data/lib/hecks/router.rb +1 -1
- data/lib/hecks/runtime/best_effort.rb +22 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +12 -2
- data/lib/hecks/runtime/command_interpreter.rb +3 -2
- data/lib/hecks/runtime/command_rules/emission.rb +1 -1
- data/lib/hecks/runtime/dispatcher.rb +4 -4
- data/lib/hecks/runtime/entity_element/location.rb +1 -1
- data/lib/hecks/runtime/event.rb +5 -0
- data/lib/hecks/runtime/identity.rb +7 -6
- data/lib/hecks/runtime/interpreting.rb +2 -1
- data/lib/hecks/runtime/invocation_builder.rb +1 -1
- data/lib/hecks/runtime/loader/boot_steps.rb +8 -5
- data/lib/hecks/runtime/loader.rb +10 -10
- data/lib/hecks/runtime/policy_interpreter/arguments.rb +7 -4
- data/lib/hecks/runtime/policy_interpreter/fan_out.rb +3 -3
- data/lib/hecks/runtime/policy_interpreter.rb +6 -6
- data/lib/hecks/runtime/port_operation_interpreter.rb +1 -1
- data/lib/hecks/runtime/reaction_invocation.rb +1 -1
- data/lib/hecks/runtime/rebuild_sweep.rb +11 -1
- data/lib/hecks/runtime/registry/ask_verification.rb +35 -0
- data/lib/hecks/runtime/registry/hecksagon_rules.rb +10 -0
- data/lib/hecks/runtime/registry/merging.rb +1 -1
- data/lib/hecks/runtime/registry/providers.rb +16 -0
- data/lib/hecks/runtime/registry/read_repository.rb +6 -4
- data/lib/hecks/runtime/registry/verification.rb +4 -1
- data/lib/hecks/runtime/registry/world_defaults.rb +29 -0
- data/lib/hecks/runtime/registry.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/compensation.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter/delivery.rb +4 -4
- data/lib/hecks/runtime/saga_interpreter/transitions.rb +1 -1
- data/lib/hecks/runtime/saga_interpreter.rb +3 -3
- data/lib/hecks/runtime/tenant_check.rb +5 -4
- data/lib/hecks/runtime/value/coercion.rb +2 -2
- data/lib/hecks/runtime/value/validation.rb +16 -4
- data/lib/hecks/runtime.rb +9 -9
- data/lib/hecks/rust_build/project_rust/target_ir.rb +1 -1
- data/lib/hecks/rust_build/wasm.rb +1 -1
- data/lib/hecks/rust_build/wasm_browser.rb +1 -1
- data/lib/hecks/rust_build.rb +11 -0
- data/lib/hecks/served_options.rb +53 -0
- data/lib/hecks/site/bluebook/site.bluebook +29 -1
- data/lib/hecks/site/bluebook/site.ports.hecksagon +6 -0
- data/lib/hecks/storehouse/audit.rb +1 -1
- data/lib/hecks/storehouse/dispatching.rb +8 -6
- data/lib/hecks/storehouse/introspection.rb +2 -2
- data/lib/hecks/storehouse/querying.rb +6 -4
- data/lib/hecks/storehouse.rb +4 -4
- data/lib/hecks/tools/comment_style/source_file.rb +4 -1
- data/lib/hecks/tools/deploy_recipe_lint/fixtures.rb +4 -1
- data/lib/hecks/tools/lanes/rows.rb +6 -0
- data/lib/hecks/tools/oidc_manifests.rb +4 -5
- data/lib/hecks/tools/regeneration_run.rb +11 -4
- data/lib/hecks/tools/site_routes/cli.rb +1 -1
- data/lib/hecks/tools/site_routes/editor_files.rb +45 -0
- data/lib/hecks/tools/site_routes.rb +14 -7
- data/lib/hecks/tools/tenant_provisioning.rb +2 -2
- data/lib/hecks/tools/tools_doc.rb +4 -4
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks/vocabulary.rb +4 -4
- data/lib/hecks.rb +15 -15
- data/lib/rubocop/cop/hecks/env_dump.rb +69 -0
- data/lib/rubocop/cop/hecks/monotonic_duration.rb +53 -0
- data/lib/rubocop/cop/hecks/no_wall_clock_in_runtime.rb +34 -0
- data/lib/rubocop/cop/hecks/raw_shell_interpolation.rb +79 -0
- data/lib/rubocop/cop/hecks/sleep_in_spec.rb +34 -0
- data/lib/rubocop/cop/hecks/swallowed_rescue.rb +37 -0
- data/lib/rubocop/cop/hecks/symbol_string_key_mix.rb +50 -0
- data/lib/rubocop/cop/hecks/untyped_raise.rb +37 -0
- data/prebuilt/05c358d38d661a3774f813d49c66f5b68939af94432d66257a56f49ee2598994.marshal +0 -0
- data/prebuilt/26c40c61f09b09b11651c64668eda3ceb180f83cf2a3802d3033d2fd99ac841b.marshal +0 -0
- data/prebuilt/verdicts-230ac18c25abfd3d92ede032bee2661a4c2cd2773ab0cf0e2ae52546ba2f7af9.json +1 -0
- data/rust/.gitignore +6 -0
- data/rust/Cargo.toml +9 -1
- data/rust/build/src/binding_pass.rs +103 -0
- data/rust/build/src/cargo_sync.rs +6 -0
- data/rust/build/src/lineage_pass.rs +3 -3
- data/rust/build/src/main.rs +17 -5
- data/rust/build/src/pipeline.rs +48 -5
- data/rust/build/src/seams_pass.rs +123 -0
- data/rust/build/src/translation_pass.rs +167 -0
- data/rust/codegen/src/asks.rs +103 -0
- data/rust/codegen/src/bridging.rs +1 -1
- data/rust/codegen/src/commands.rs +13 -8
- data/rust/codegen/src/constraints.rs +25 -0
- data/rust/codegen/src/domain_generator.rs +11 -9
- data/rust/codegen/src/expr_emitter.rs +13 -0
- data/rust/codegen/src/json_codec.rs +54 -15
- data/rust/codegen/src/main.rs +2 -1
- data/rust/codegen/src/mutations.rs +174 -4
- data/rust/codegen/src/naming.rs +30 -0
- data/rust/codegen/src/queries.rs +11 -2
- data/rust/codegen/src/reactions.rs +1 -1
- data/rust/codegen/src/types.rs +166 -8
- data/rust/host/HECKS_RELEASE +1 -1
- data/rust/host/src/api.rs +4 -4
- data/rust/host/src/bin/validate_harness.rs +43 -0
- data/rust/host/src/boundary_fuzz/expr_json.rs +2 -2
- data/rust/host/src/boundary_fuzz/ir.rs +1 -0
- data/rust/host/src/boundary_fuzz/server.rs +1 -1
- data/rust/host/src/checkout.rs +35 -19
- data/rust/host/src/commerce_ir.rs +408 -2
- data/rust/host/src/expr_json.rs +118 -0
- data/rust/host/src/mint.rs +1 -1
- data/rust/host/src/payments/tests.rs +27 -1
- data/rust/host/src/payments.rs +12 -4
- data/rust/host/src/query_step.rs +22 -4
- data/rust/host/src/reference_validate.rs +653 -108
- data/rust/host/src/resend.rs +2 -0
- data/rust/host/src/server.rs +19 -6
- data/rust/host/src/ui_schema.rs +132 -5
- data/rust/host/src/web/newsletter.rs +7 -8
- data/rust/host/src/web/newsletter_send.rs +38 -13
- data/rust/host/src/web/registrations.rs +229 -26
- data/rust/host/src/web.rs +3 -3
- data/rust/parser/src/emit.rs +38 -6
- data/rust/parser/src/expr/ast_json.rs +7 -1
- data/rust/parser/src/expr/resolver.rs +171 -6
- data/rust/parser/src/ir.rs +7 -0
- data/rust/parser/src/keywords.rs +24 -0
- data/rust/parser/src/main.rs +3 -0
- data/rust/parser/src/parse/aggregate.rs +2 -1
- data/rust/parser/src/parse/chapter.rs +2 -2
- data/rust/parser/src/parse/command.rs +2 -0
- data/rust/parser/src/parse/hecksagon.rs +5 -2
- data/rust/parser/src/parse/lifecycle.rs +81 -0
- data/rust/parser/src/parse/mod.rs +15 -1
- data/rust/parser/src/parse/policy.rs +13 -2
- data/rust/parser/src/parse/value_object.rs +13 -8
- data/rust/parser/src/ruby_value.rs +1 -1
- data/rust/src/exemplar/commands.rs +4 -4
- data/rust/src/exemplar/constraints.rs +1 -1
- data/rust/src/exemplar/json.rs +43 -1
- data/rust/src/kernel/cli.rs +7 -5
- data/rust/src/kernel/dispatch.rs +2 -2
- data/rust/src/kernel/dispatch_guard_tests.rs +1 -1
- data/rust/src/kernel/expr.rs +73 -4
- data/rust/src/kernel/expression_operators/arithmetic.rs +130 -5
- data/rust/src/kernel/expression_operators/presence.rs +41 -3
- data/rust/src/kernel/expression_operators/text.rs +26 -2
- data/rust/src/kernel/json.rs +15 -0
- data/rust/src/kernel/mod.rs +1 -1
- data/rust/src/kernel/orchestrate.rs +54 -5
- data/rust/src/kernel/orchestrate_guard_tests.rs +67 -0
- data/rust/src/kernel/pattern.rs +60 -0
- data/rust/src/kernel/reference_lookup.rs +90 -7
- metadata +174 -36
- data/lib/hecks/doors/cli_door/nesting.rb +0 -34
- data/lib/hecks/doors/cli_door/shorthand.rb +0 -85
- data/lib/hecks/doors/cli_door.rb +0 -124
- data/lib/hecks/doors/cli_runner/answers.rb +0 -138
- data/lib/hecks/doors/cli_runner/resolution.rb +0 -146
- data/lib/hecks/doors/cli_runner/settling.rb +0 -115
- data/lib/hecks/doors/cli_runner/streaming.rb +0 -90
- data/lib/hecks/doors/cli_runner/suggestions.rb +0 -43
- data/lib/hecks/doors/cli_runner.rb +0 -66
- data/lib/hecks/doors/command_request.rb +0 -119
- data/lib/hecks/doors/handle.rb +0 -208
- data/lib/hecks/doors/json_door.rb +0 -132
- data/lib/hecks/doors/launcher_options.rb +0 -247
- data/lib/hecks/doors/mcp_door/properties.rb +0 -47
- data/lib/hecks/doors/mcp_door/tool_calls.rb +0 -113
- data/lib/hecks/doors/mcp_door/tool_definitions/auditing.rb +0 -51
- data/lib/hecks/doors/mcp_door/tool_definitions/calling.rb +0 -69
- data/lib/hecks/doors/mcp_door/tool_definitions/reading.rb +0 -97
- data/lib/hecks/doors/mcp_door/tool_definitions.rb +0 -15
- data/lib/hecks/doors/mcp_door.rb +0 -156
- data/lib/hecks/doors/mcp_door_scope/argument_policy.rb +0 -92
- data/lib/hecks/doors/mcp_door_scope/env_problems.rb +0 -55
- data/lib/hecks/doors/mcp_door_scope/presenter.rb +0 -78
- data/lib/hecks/doors/mcp_door_scope.rb +0 -201
- data/lib/hecks/doors/mcp_guide_cache.rb +0 -75
- data/lib/hecks/doors/ruby_door/aggregate_door.rb +0 -162
- data/lib/hecks/doors/ruby_door/chapter.rb +0 -89
- data/lib/hecks/doors/ruby_door.rb +0 -80
- data/lib/hecks/doors/usage_cache.rb +0 -139
- data/prebuilt/0ee7f83cba59ce7d1c45c65ba166b071779f70143449f584f33ff7989f64eccb.marshal +0 -0
- data/prebuilt/6e4a6bcf0aa880e2e6b056e1846b70e5a768090b9dc998bbadeaf5d6bcfd3db8.marshal +0 -0
- data/prebuilt/verdicts-91aaf93ce8981bd9a754948f075d95650dc2ec6435015376f5c60992b36a24b1.json +0 -1
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
require "pathname"
|
|
2
|
+
require "stringio"
|
|
3
|
+
require_relative "../../ports/identity_generation"
|
|
4
|
+
require_relative "../../runtime/errors"
|
|
5
|
+
require_relative "cli"
|
|
6
|
+
|
|
7
|
+
module Hecks
|
|
8
|
+
module Adapters
|
|
9
|
+
module Driving
|
|
10
|
+
# What a domain's world file adds to its generated launcher, all of it opt-in.
|
|
11
|
+
#
|
|
12
|
+
# A `.world` that declares a `launcher` setting switches these on for that chapter; a
|
|
13
|
+
# domain without one keeps the launcher's plain forms exactly:
|
|
14
|
+
#
|
|
15
|
+
# - **run_keys** mints the `run` key of a creating command that was given none.
|
|
16
|
+
# - **settled** lists the commands (`aggregate.command`) that always act as if given `--wait`.
|
|
17
|
+
# - **unknown_runs** lists the questions that refuse a run this process does not hold.
|
|
18
|
+
# - **report** lists the settled commands whose answer is the report they recorded, as text.
|
|
19
|
+
# - **names** maps a launcher name to the command it stands for (see `CliProjector`).
|
|
20
|
+
# - **streams** lists the questions `--stream` may tail, one JSON line per new entry.
|
|
21
|
+
# - **maintainer**, **chapters**, **maintainer_chapters** shape the help for its audience.
|
|
22
|
+
module LauncherOptions
|
|
23
|
+
SETTING = "launcher".freeze
|
|
24
|
+
WAIT = "--wait".freeze
|
|
25
|
+
STREAM = "--stream".freeze
|
|
26
|
+
RUN_KEY = "run.value".freeze
|
|
27
|
+
# The lifecycle mark naming the states `--wait` reports as a failure (exit 1); the lifecycle
|
|
28
|
+
# says so with `mark :failure, "flagged"` (ADR 0097), so no setting lists them.
|
|
29
|
+
FAILURE_MARK = "failure".freeze
|
|
30
|
+
# What makes a directory a hecks checkout: this file stands beside `lib/`, the same test
|
|
31
|
+
# the Codebase aggregate's `Accept` applies before it runs anything.
|
|
32
|
+
CHECKOUT_MARKER = "hecks.gemspec".freeze
|
|
33
|
+
# `HECKS_MAINTAINER=1` shows the maintainer help anywhere, `0` hides it even in a checkout.
|
|
34
|
+
MAINTAINER_VARIABLE = "HECKS_MAINTAINER".freeze
|
|
35
|
+
|
|
36
|
+
module_function
|
|
37
|
+
|
|
38
|
+
# Reads a chapter's `launcher` setting.
|
|
39
|
+
#
|
|
40
|
+
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
|
|
41
|
+
# @param chapter [String] the chapter the command line speaks to
|
|
42
|
+
# @return [Hash{Symbol => Object}, nil] the setting, or nil when the chapter did not opt in
|
|
43
|
+
def settings(runtime, chapter)
|
|
44
|
+
return unless runtime.respond_to?(:registry)
|
|
45
|
+
|
|
46
|
+
found = runtime.registry.world(chapter)&.for_verb(SETTING)
|
|
47
|
+
found.nil? || found.empty? ? nil : found
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The options the launcher's projection is asked for: the program's name, the chapter's
|
|
51
|
+
# launcher names, and whether run keys are minted (so help shows them optional).
|
|
52
|
+
#
|
|
53
|
+
# @param settings [Hash, nil] the chapter's `launcher` setting
|
|
54
|
+
# @param program [String] how the caller was invoked
|
|
55
|
+
# @return [Hash{Symbol => Object}] the options `Projector::CliProjector` reads
|
|
56
|
+
def projection(settings, program)
|
|
57
|
+
{ program: program, names: settings && settings[:names], mint_run_keys: settings && settings[:run_keys] }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Whether the person is working on a hecks checkout: `dir` or a directory above it holds
|
|
61
|
+
# `hecks.gemspec` beside `lib/`. `HECKS_MAINTAINER` overrides the look.
|
|
62
|
+
#
|
|
63
|
+
# @param dir [String] where the command line was typed
|
|
64
|
+
# @param env [#[]] the environment
|
|
65
|
+
# @return [Boolean] true for the maintainer's view of the help
|
|
66
|
+
def maintainer?(dir = Dir.pwd, env = ENV)
|
|
67
|
+
forced = env[MAINTAINER_VARIABLE].to_s
|
|
68
|
+
return forced != "0" unless forced.empty?
|
|
69
|
+
|
|
70
|
+
Pathname.new(File.expand_path(dir)).ascend.any? do |root|
|
|
71
|
+
root.join(CHECKOUT_MARKER).exist? && root.join("lib").directory?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# The help options one audience gets: the aggregates left out of the lists (`maintainer`,
|
|
76
|
+
# shown only in a hecks checkout or to `--maintainer`) and the chapters pointed at
|
|
77
|
+
# (`chapters`, plus `maintainer_chapters` in a checkout). A chapter that did not opt in
|
|
78
|
+
# gets neither.
|
|
79
|
+
#
|
|
80
|
+
# @param settings [Hash, nil] the chapter's `launcher` setting
|
|
81
|
+
# @param maintainer [Boolean] whether the help is for someone working on a hecks checkout
|
|
82
|
+
# @return [Hash{Symbol => Object}] `:hide` and `:chapters`, to merge into the projection
|
|
83
|
+
def audience(settings, maintainer)
|
|
84
|
+
return {} unless settings
|
|
85
|
+
|
|
86
|
+
chapters = Array(settings[:chapters]) + (maintainer ? Array(settings[:maintainer_chapters]) : [])
|
|
87
|
+
{ hide: maintainer ? [] : Array(settings[:maintainer]).map(&:to_s), chapters: chapters.map(&:to_s) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Runs the block with standard error held back, so the wiring notes hecks prints about its
|
|
91
|
+
# own
|
|
92
|
+
# chapters (a Memory journal loses sagas on restart) do not open a console session. They are
|
|
93
|
+
# for an operator running a stored journal. A raised error still surfaces, unchanged.
|
|
94
|
+
#
|
|
95
|
+
# @param hold [Boolean] whether to hold standard error back; false runs the block as it is
|
|
96
|
+
# @yield the boot
|
|
97
|
+
# @return [Object] the block's value
|
|
98
|
+
def quietly(hold: true)
|
|
99
|
+
return yield unless hold
|
|
100
|
+
|
|
101
|
+
shown = $stderr
|
|
102
|
+
$stderr = StringIO.new
|
|
103
|
+
yield
|
|
104
|
+
ensure
|
|
105
|
+
$stderr = shown if hold
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Takes `--wait` out of a command's words, unless it declares a `wait` argument of its own.
|
|
109
|
+
#
|
|
110
|
+
# `--wait=false` (or `no`, `0`, `off`) is a `--wait` that was switched off; a bare `--wait`
|
|
111
|
+
# may be followed by its Boolean word.
|
|
112
|
+
#
|
|
113
|
+
# @param spec [Hash] the command's projected spec
|
|
114
|
+
# @param words [Array<String>] the words after the command
|
|
115
|
+
# @return [Array(Array<String>, Boolean)] the remaining words, and whether `--wait` was
|
|
116
|
+
# given
|
|
117
|
+
# @raise [Runtime::TypeMismatch] if `--wait=` carries something that is not a Boolean word
|
|
118
|
+
def take_wait(spec, words)
|
|
119
|
+
return [words, false] unless words.any? { |word| wait_word?(word) } && !declares_wait?(spec)
|
|
120
|
+
|
|
121
|
+
split_wait(words)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Whether the command declares an argument of its own named `wait`.
|
|
125
|
+
# @api private
|
|
126
|
+
def declares_wait?(spec)
|
|
127
|
+
spec[:arguments].any? { |argument| argument[:path].split(".").first == "wait" }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# The words without `--wait`, and whether it was given.
|
|
131
|
+
# @api private
|
|
132
|
+
def split_wait(words)
|
|
133
|
+
wait = false
|
|
134
|
+
rest = []
|
|
135
|
+
queue = words.dup
|
|
136
|
+
until queue.empty?
|
|
137
|
+
word = queue.shift
|
|
138
|
+
wait_word?(word) ? wait ||= Cli.boolean(wait_value(word, queue)) : rest << word
|
|
139
|
+
end
|
|
140
|
+
[rest, wait]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Whether a command always waits for its reactions, as if `--wait` had been given.
|
|
144
|
+
#
|
|
145
|
+
# @param launcher [Hash, nil] the chapter's `launcher` setting
|
|
146
|
+
# @param spec [Hash] the command's projected spec
|
|
147
|
+
# @return [Boolean] true for a command the setting lists under `settled`
|
|
148
|
+
def settled?(launcher, spec)
|
|
149
|
+
return false unless launcher && spec[:kind] == :command
|
|
150
|
+
|
|
151
|
+
Array(launcher[:settled]).map(&:to_s).include?(spec[:short].to_s)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Whether a question about one run refuses a run this process does not hold, instead of
|
|
155
|
+
# answering an empty list.
|
|
156
|
+
#
|
|
157
|
+
# @param launcher [Hash, nil] the chapter's `launcher` setting
|
|
158
|
+
# @param spec [Hash] the question's projected spec
|
|
159
|
+
# @return [Boolean] true for a question the setting lists under `unknown_runs`
|
|
160
|
+
def unknown_run?(launcher, spec)
|
|
161
|
+
return false unless launcher && spec[:kind] == :query
|
|
162
|
+
|
|
163
|
+
Array(launcher[:unknown_runs]).map(&:to_s).include?(spec[:short].to_s)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Whether a command prints the report it recorded instead of its whole record.
|
|
167
|
+
#
|
|
168
|
+
# @param launcher [Hash, nil] the chapter's `launcher` setting
|
|
169
|
+
# @param spec [Hash] the command's projected spec
|
|
170
|
+
# @return [Boolean] true for a command the setting lists under `report`
|
|
171
|
+
def report?(launcher, spec)
|
|
172
|
+
return false unless launcher && spec[:kind] == :command
|
|
173
|
+
|
|
174
|
+
Array(launcher[:report]).map(&:to_s).include?(spec[:short].to_s)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Whether a question may be tailed with `--stream`: the chapter's `launcher` setting lists
|
|
178
|
+
# it
|
|
179
|
+
# under `streams`, by the question's own name.
|
|
180
|
+
#
|
|
181
|
+
# @param launcher [Hash, nil] the chapter's `launcher` setting
|
|
182
|
+
# @param spec [Hash] the question's projected spec
|
|
183
|
+
# @return [Boolean] true for a question the setting names
|
|
184
|
+
def streams?(launcher, spec)
|
|
185
|
+
return false unless launcher && spec[:kind] == :query
|
|
186
|
+
|
|
187
|
+
Array(launcher[:streams]).map(&:to_s).include?(spec[:command].to_s.split(/[.:]+/).last)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Takes `--stream` out of a question's words.
|
|
191
|
+
#
|
|
192
|
+
# @param words [Array<String>] the words after the question
|
|
193
|
+
# @return [Array(Array<String>, Boolean)] the remaining words, and whether `--stream` was
|
|
194
|
+
# given
|
|
195
|
+
def take_stream(words)
|
|
196
|
+
[words.reject { |word| word == STREAM }, words.include?(STREAM)]
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# @api private
|
|
200
|
+
def wait_word?(word) = word == WAIT || word.start_with?("#{WAIT}=")
|
|
201
|
+
|
|
202
|
+
# The Boolean word a `--wait` carries: after `=`, or the next word when it is one.
|
|
203
|
+
# @api private
|
|
204
|
+
def wait_value(word, queue)
|
|
205
|
+
return word.split("=", 2).last if word.include?("=")
|
|
206
|
+
|
|
207
|
+
Cli::BOOLEAN_WORDS.key?(queue.first.to_s.downcase) ? queue.shift : "true"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Whether a question's text answer reports a gap, which `--wait` turns into a failing exit.
|
|
211
|
+
#
|
|
212
|
+
# The coverage checks end their report with a `GAP (n)` heading; a non-zero count is a
|
|
213
|
+
# finding, and a CI stage that waits on the question fails on it.
|
|
214
|
+
#
|
|
215
|
+
# @param text [String, nil] the question's text answer
|
|
216
|
+
# @return [Boolean] whether a `GAP (n)` heading with n above zero is in the text
|
|
217
|
+
def gap_reported?(text)
|
|
218
|
+
text.is_a?(String) && text.match?(/^GAP \((?!0\))\d+\)/)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Mints the `run` key a creating command was not given, when the domain opted in.
|
|
222
|
+
#
|
|
223
|
+
# An explicit key always wins. Nothing is minted for a command that acts on an existing
|
|
224
|
+
# record. When no identity adapter is bound the run is refused, saying to name a key,
|
|
225
|
+
# rather than sent on without one.
|
|
226
|
+
#
|
|
227
|
+
# @param runtime [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted domain
|
|
228
|
+
# @param spec [Hash] the command's projected spec
|
|
229
|
+
# @param args [Hash] the parsed arguments
|
|
230
|
+
# @param settings [Hash, nil] the chapter's `launcher` setting
|
|
231
|
+
# @return [Array(Hash, String)] the arguments, and the key minted (nil when none was)
|
|
232
|
+
# @raise [Runtime::NotFound] if a key is owed but no identity adapter is bound
|
|
233
|
+
def run_key(runtime, spec, args, settings)
|
|
234
|
+
return [args, nil] unless key_owed?(runtime, spec, args, settings)
|
|
235
|
+
|
|
236
|
+
key = Ports::IdentityGeneration.uuid(runtime.registry)
|
|
237
|
+
[args.merge(run: { value: key }), key]
|
|
238
|
+
rescue Runtime::WiringError => e
|
|
239
|
+
raise Runtime::NotFound, "cannot mint a run key (#{e.message.lines.first.strip}); name one with run=<key>"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Whether the command is a creating one of an opted-in chapter, takes a run key and was
|
|
243
|
+
# given none.
|
|
244
|
+
# @api private
|
|
245
|
+
def key_owed?(runtime, spec, args, settings)
|
|
246
|
+
return false unless settings && settings[:run_keys] && spec[:creates]
|
|
247
|
+
return false unless spec[:arguments].any? { |argument| argument[:path] == RUN_KEY }
|
|
248
|
+
|
|
249
|
+
!args.key?(:run) && runtime.respond_to?(:registry)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Whether a settled record sits in a state its lifecycle marks as a failure.
|
|
253
|
+
#
|
|
254
|
+
# @param aggregate [Bluebook::Aggregate, nil] the record's aggregate
|
|
255
|
+
# @param state [Hash, nil] the record's state
|
|
256
|
+
# @param settings [Hash, nil] the chapter's `launcher` setting
|
|
257
|
+
# @return [Boolean] false when the aggregate has no lifecycle
|
|
258
|
+
def failed?(aggregate, state, settings)
|
|
259
|
+
field = aggregate&.lifecycle&.field
|
|
260
|
+
return false unless field && state && settings
|
|
261
|
+
|
|
262
|
+
Array(aggregate.lifecycle.marked(FAILURE_MARK)).include?(state[field.to_sym].to_s)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require_relative "../../.."
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
module Driving
|
|
6
|
+
module Mcp
|
|
7
|
+
# The input-schema properties the MCP server's tools share.
|
|
8
|
+
module Properties
|
|
9
|
+
SUMMARY_PROPERTY = {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: "One line: why this call is happening. Required — it is what makes the audit trail legible later."
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
DOMAIN_PROPERTY = {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "The domain directory, containing a .hecksagon (e.g. \"examples/banking\"). The `domains` tool " \
|
|
17
|
+
"lists what's available."
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
20
|
+
ARGS_PROPERTY = {
|
|
21
|
+
type: "object",
|
|
22
|
+
description: "The command/query's declared arguments, nested value-object literals included " \
|
|
23
|
+
"(e.g. {\"reference\":{\"value\":\"BUG#1\"}})."
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
SOURCE_PROPERTY = {
|
|
27
|
+
type: "string",
|
|
28
|
+
enum: Hecks::Storehouse::SOURCE_TAGS,
|
|
29
|
+
description: "Optional: who is calling, for the audit log `follow` reads back."
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
ROLE_PROPERTY = {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Bind a caller identity for the call's duration, so a role-gated command's authorization is " \
|
|
35
|
+
"checked rather than merely documented. Required by `dispatch` for any command that declares a " \
|
|
36
|
+
"role — omitting it refuses the call rather than running it unchecked. Also required if " \
|
|
37
|
+
"`actor_id` is given."
|
|
38
|
+
}.freeze
|
|
39
|
+
|
|
40
|
+
ACTOR_ID_PROPERTY = {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Optional, alongside `role`: WHO holds that role — once the domain attaches Governance, checked " \
|
|
43
|
+
"against a real Governance::RoleAssignment instead of a bare string match. Requires `role`."
|
|
44
|
+
}.freeze
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require_relative "../../.."
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
module Driving
|
|
6
|
+
module Mcp
|
|
7
|
+
# Answers one `tools/call`: the tool a name stands for, run against the booted domain the
|
|
8
|
+
# call names. A domain refusal is already `{ok: false, ...}` from `Storehouse`.
|
|
9
|
+
module ToolCalls
|
|
10
|
+
# The method that answers each tool.
|
|
11
|
+
HANDLERS = {
|
|
12
|
+
"dispatch" => :dispatch_tool,
|
|
13
|
+
"query" => :query_tool,
|
|
14
|
+
"events" => :events_tool,
|
|
15
|
+
"state" => :state_tool,
|
|
16
|
+
"catalog" => :catalog_tool,
|
|
17
|
+
"describe" => :describe_tool,
|
|
18
|
+
"validate" => :validate_tool,
|
|
19
|
+
"domains" => :domains_tool,
|
|
20
|
+
"history" => :history_tool,
|
|
21
|
+
"behaviors" => :behaviors_tool,
|
|
22
|
+
"follow" => :follow_tool
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
# Runs the tool `name` with `args`, so the shared `rescue` catches every tool's escape
|
|
28
|
+
# once.
|
|
29
|
+
#
|
|
30
|
+
# @param name [String] the tool's name
|
|
31
|
+
# @param args [Hash{String => Object}] the call's arguments
|
|
32
|
+
# @return [Hash{Symbol => Object}] the tool's answer, or `{ok: false, error: ...}`
|
|
33
|
+
def call(name, args)
|
|
34
|
+
handler = HANDLERS[name]
|
|
35
|
+
return unknown(name) unless handler
|
|
36
|
+
|
|
37
|
+
public_send(handler, args)
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
# A defect, not a refusal: reaching here means a bad domain path or an
|
|
40
|
+
# argument shape `Adapters::Driving::Json` could not symbolize.
|
|
41
|
+
{ ok: false, error: "#{e.class}: #{e.message}" }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# The refusal for a tool the server does not have.
|
|
45
|
+
def unknown(name)
|
|
46
|
+
{ ok: false, error: "no such tool: #{name.inspect} — known: #{HANDLERS.keys.join(", ")}" }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# A question, once the scope has admitted its arguments.
|
|
50
|
+
def query_tool(args)
|
|
51
|
+
Mcp.scope.admit_arguments!(args["args"])
|
|
52
|
+
Storehouse.query(runtime: Mcp.boot(args["domain"]), question: args["question"],
|
|
53
|
+
summary: args["summary"], args: args["args"] || {}, source: args["source"],
|
|
54
|
+
role: args["role"], actor_id: args["actor_id"])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# A single command or a batch, once the scope has admitted every command in it.
|
|
58
|
+
def dispatch_tool(args)
|
|
59
|
+
runtime = Mcp.boot(args["domain"])
|
|
60
|
+
return dispatch_steps(runtime, args) if args["steps"]
|
|
61
|
+
|
|
62
|
+
Mcp.scope.admit_command!(runtime, args["command"], args["args"])
|
|
63
|
+
Storehouse.dispatch(runtime: runtime, command: args["command"], summary: args["summary"],
|
|
64
|
+
args: args["args"] || {}, source: args["source"],
|
|
65
|
+
dry_run: args["dry_run"] == true, role: args["role"], actor_id: args["actor_id"])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Several commands in one call.
|
|
69
|
+
def dispatch_steps(runtime, args)
|
|
70
|
+
Mcp.scope.admit_steps!(runtime, args["steps"])
|
|
71
|
+
Storehouse.dispatch_batch(runtime: runtime, steps: args["steps"], summary: args["summary"],
|
|
72
|
+
source: args["source"], role: args["role"], actor_id: args["actor_id"])
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def events_tool(args)
|
|
76
|
+
Storehouse.events(runtime: Mcp.boot(args["domain"]), aggregate: args["aggregate"], id: args["id"],
|
|
77
|
+
limit: args["limit"])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def state_tool(args)
|
|
81
|
+
Storehouse.state(runtime: Mcp.boot(args["domain"]), aggregate: args["aggregate"],
|
|
82
|
+
summary: args["summary"], id: args["id"])
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def catalog_tool(args)
|
|
86
|
+
Storehouse.catalog(runtime: Mcp.boot(args["domain"]))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def describe_tool(args)
|
|
90
|
+
Storehouse.describe(runtime: Mcp.boot(args["domain"]), aggregate: args["aggregate"])
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def validate_tool(args)
|
|
94
|
+
Storehouse.validate(domain: Mcp.scope.admit_domain!(args["domain"]), deep: args["deep"] == true)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def domains_tool(args)
|
|
98
|
+
Storehouse.domains(under: args["under"] || "examples")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def history_tool(args)
|
|
102
|
+
Storehouse.history(runtime: Mcp.boot(args["domain"]))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def behaviors_tool(args)
|
|
106
|
+
Storehouse.behaviors(target: args["target"])
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def follow_tool(args)
|
|
110
|
+
Storehouse.follow(runtime: Mcp.boot(args["domain"]), limit: args["limit"] || 20)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require_relative "../../mcp/properties"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
module Driving
|
|
6
|
+
module Mcp
|
|
7
|
+
module ToolDefinitions
|
|
8
|
+
# The tools that read what has been recorded: write history, behaviors and the audit log.
|
|
9
|
+
module Auditing
|
|
10
|
+
include Properties
|
|
11
|
+
|
|
12
|
+
LIST = [
|
|
13
|
+
{
|
|
14
|
+
name: "history",
|
|
15
|
+
description: "The full write history for every aggregate in a domain — every operation an append-only " \
|
|
16
|
+
"adapter ever recorded, not just current state. An aggregate on a non-append-only adapter " \
|
|
17
|
+
"answers an empty history honestly.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: { domain: DOMAIN_PROPERTY },
|
|
21
|
+
required: %w[domain]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "behaviors",
|
|
26
|
+
description: "Run a domain's hand-curated `.behaviors` example tests and report pass/fail/error per test. " \
|
|
27
|
+
"`target` is a single `.behaviors` file or a directory to sweep.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: { target: { type: "string", description: "A .behaviors file, or a directory to sweep." } },
|
|
31
|
+
required: %w[target]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "follow",
|
|
36
|
+
description: "Tail this server's own audit log for a domain — the last `limit` dispatch/query/state/dry-run " \
|
|
37
|
+
"calls made through it, each carrying its summary, source, and outcome.",
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
domain: DOMAIN_PROPERTY,
|
|
42
|
+
limit: { type: "integer", description: "How many recent entries to return. Defaults to 20." }
|
|
43
|
+
},
|
|
44
|
+
required: %w[domain]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
].freeze
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require_relative "../../mcp/properties"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
module Driving
|
|
6
|
+
module Mcp
|
|
7
|
+
module ToolDefinitions
|
|
8
|
+
# The tools that issue a command or ask a question.
|
|
9
|
+
module Calling
|
|
10
|
+
include Properties
|
|
11
|
+
|
|
12
|
+
LIST = [
|
|
13
|
+
{
|
|
14
|
+
name: "dispatch",
|
|
15
|
+
description: "Issue a command against a booted domain — or, with `steps`, several in one call. `command` is " \
|
|
16
|
+
"the short or qualified verb name (the catalog/describe tools show what's available). Set " \
|
|
17
|
+
"`dry_run: true` to check whether it WOULD succeed without committing anything. Answers the " \
|
|
18
|
+
"record's id, its resulting state, and the events it announced — or a structured refusal, " \
|
|
19
|
+
"never a crash.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
domain: DOMAIN_PROPERTY,
|
|
24
|
+
command: { type: "string", description: "The command's short or qualified name, e.g. \"open_account\". " \
|
|
25
|
+
"Ignored when `steps` is given." },
|
|
26
|
+
args: ARGS_PROPERTY,
|
|
27
|
+
summary: SUMMARY_PROPERTY,
|
|
28
|
+
source: SOURCE_PROPERTY,
|
|
29
|
+
role: ROLE_PROPERTY,
|
|
30
|
+
actor_id: ACTOR_ID_PROPERTY,
|
|
31
|
+
dry_run: { type: "boolean", description: "Preview only — check the command would succeed, commit nothing. " \
|
|
32
|
+
"Ignored when `steps` is given." },
|
|
33
|
+
steps: {
|
|
34
|
+
type: "array",
|
|
35
|
+
description: "Run several commands in one call, in order. Each item: {command, args}. When given, " \
|
|
36
|
+
"`command`/`args`/`dry_run` above are ignored.",
|
|
37
|
+
items: {
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: { command: { type: "string" }, args: ARGS_PROPERTY },
|
|
40
|
+
required: %w[command]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
required: %w[domain summary]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "query",
|
|
49
|
+
description: "Ask a declared question of a booted domain. `question` is the short or qualified query name. " \
|
|
50
|
+
"Answers the row array the query itself declares.",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
domain: DOMAIN_PROPERTY,
|
|
55
|
+
question: { type: "string", description: "The query's short or qualified name." },
|
|
56
|
+
args: ARGS_PROPERTY,
|
|
57
|
+
summary: SUMMARY_PROPERTY,
|
|
58
|
+
source: SOURCE_PROPERTY,
|
|
59
|
+
role: ROLE_PROPERTY,
|
|
60
|
+
actor_id: ACTOR_ID_PROPERTY
|
|
61
|
+
},
|
|
62
|
+
required: %w[domain question summary]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
].freeze
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require_relative "../../mcp/properties"
|
|
2
|
+
|
|
3
|
+
module Hecks
|
|
4
|
+
module Adapters
|
|
5
|
+
module Driving
|
|
6
|
+
module Mcp
|
|
7
|
+
module ToolDefinitions
|
|
8
|
+
# The tools that read a domain: its events, state, shape and wiring.
|
|
9
|
+
module Reading
|
|
10
|
+
include Properties
|
|
11
|
+
|
|
12
|
+
LIST = [
|
|
13
|
+
{
|
|
14
|
+
name: "events",
|
|
15
|
+
description: "What actually HAPPENED, with payloads, to one aggregate/record — events THIS SERVER witnessed " \
|
|
16
|
+
"(every real dispatch ever routed through it, sourced from its own audit log — not a full " \
|
|
17
|
+
"domain-wide event-sourcing replay). Distinct from `state` (what's stored now) and `history` " \
|
|
18
|
+
"(append-only operation snapshots, no payload). Narrow with `aggregate` and (requires " \
|
|
19
|
+
"`aggregate`) `id`; `limit` keeps only the most recent.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
domain: DOMAIN_PROPERTY,
|
|
24
|
+
aggregate: { type: "string", description: "Narrow to one aggregate, e.g. \"Account\"." },
|
|
25
|
+
id: { type: "string", description: "Narrow to one record's own events. Requires `aggregate`." },
|
|
26
|
+
limit: { type: "integer", description: "Keep only the most recent N events. Omit for all of them." }
|
|
27
|
+
},
|
|
28
|
+
required: %w[domain]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "state",
|
|
33
|
+
description: "Read what an aggregate actually has stored, no verb involved. Pass `id` for one record; " \
|
|
34
|
+
"omit it to list every record the aggregate currently holds.",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
domain: DOMAIN_PROPERTY,
|
|
39
|
+
aggregate: { type: "string", description: "The aggregate's name, e.g. \"Account\"." },
|
|
40
|
+
id: { type: "string", description: "A specific record's id. Omit to list every record." },
|
|
41
|
+
summary: SUMMARY_PROPERTY
|
|
42
|
+
},
|
|
43
|
+
required: %w[domain aggregate summary]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "catalog",
|
|
48
|
+
description: "Zoom level one: every aggregate a domain declares, and every command/query name each " \
|
|
49
|
+
"answers to. No summary needed — this changes nothing and commits nothing to any log.",
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: { domain: DOMAIN_PROPERTY },
|
|
53
|
+
required: %w[domain]
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "describe",
|
|
58
|
+
description: "Zoom level two: one aggregate's full contract — every command's arguments, the states it " \
|
|
59
|
+
"may be issued from, and every way it can refuse. Omit `aggregate` for the whole domain.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: {
|
|
63
|
+
domain: DOMAIN_PROPERTY,
|
|
64
|
+
aggregate: { type: "string", description: "Narrow to one aggregate. Omit for the whole domain." }
|
|
65
|
+
},
|
|
66
|
+
required: %w[domain]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "validate",
|
|
71
|
+
description: "Zoom level three: is this domain's wiring sound — every bind names a declared aggregate, " \
|
|
72
|
+
"every adapter satisfies its port, the default adapter is usable. {valid:false, error:…} " \
|
|
73
|
+
"on a real wiring defect, never a bare crash. Set `deep: true` to also model-check the IR " \
|
|
74
|
+
"for dead lifecycle transitions, unreachable saga states, and dispatches to nowhere.",
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: "object",
|
|
77
|
+
properties: {
|
|
78
|
+
domain: DOMAIN_PROPERTY,
|
|
79
|
+
deep: { type: "boolean", description: "Also run the static model checker (lifecycle/saga/policy IR)." }
|
|
80
|
+
},
|
|
81
|
+
required: %w[domain]
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "domains",
|
|
86
|
+
description: "Zoom level zero: every domain directory found under a root (default \"examples\"), so a " \
|
|
87
|
+
"caller who doesn't already know a path can find one.",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: "object",
|
|
90
|
+
properties: { under: { type: "string", description: "Root directory to scan. Defaults to \"examples\"." } }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
].freeze
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative "../mcp/tool_definitions/calling"
|
|
2
|
+
require_relative "../mcp/tool_definitions/reading"
|
|
3
|
+
require_relative "../mcp/tool_definitions/auditing"
|
|
4
|
+
|
|
5
|
+
module Hecks
|
|
6
|
+
module Adapters
|
|
7
|
+
module Driving
|
|
8
|
+
module Mcp
|
|
9
|
+
# The tools the MCP server answers: their names, descriptions and input schemas, in the
|
|
10
|
+
# order
|
|
11
|
+
# `tools/list` shows them.
|
|
12
|
+
module ToolDefinitions
|
|
13
|
+
TOOLS = (Calling::LIST + Reading::LIST + Auditing::LIST).freeze
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|