hecks 2.9.0 → 3.0.1
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/exe/hecks +51 -6
- data/lib/hecks/adapters/driven/heki/journal.rb +1 -1
- data/lib/hecks/adapters/driven/lambda/client.rb +1 -1
- data/lib/hecks/adapters/driven/lambda.rb +1 -1
- data/lib/hecks/adapters/driven/memory.rb +16 -3
- data/lib/hecks/adapters/driven/postgres/reconnect.rb +6 -2
- data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
- data/lib/hecks/adapters/driven/postgres.rb +13 -4
- data/lib/hecks/adapters/driven/prism.rb +41 -8
- data/lib/hecks/adapters/driven/tenant_provisioner.rb +73 -16
- data/lib/hecks/behaviors/expectations.rb +1 -1
- data/lib/hecks/behaviors.rb +1 -1
- data/lib/hecks/bench/cli.rb +62 -0
- data/lib/hecks/bench/environment.rb +71 -0
- data/lib/hecks/bench/postgres_probe.rb +30 -0
- data/lib/hecks/bench/report.rb +76 -0
- data/lib/hecks/bench/ruby_runner.rb +93 -0
- data/lib/hecks/bench/run.rb +55 -0
- data/lib/hecks/bench/rust_runner.rb +101 -0
- data/lib/hecks/bench/stats.rb +46 -0
- data/lib/hecks/bench/suite.rb +98 -0
- data/lib/hecks/bench/workload.rb +89 -0
- data/lib/hecks/bench.rb +17 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +2 -0
- data/lib/hecks/bluebook/attribute.rb +1 -1
- data/lib/hecks/bluebook/behaviour/aggregate.rb +30 -1
- data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -0
- data/lib/hecks/bluebook/chapter.rb +6 -2
- data/lib/hecks/bluebook/domain_port.rb +36 -5
- data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +10 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +8 -0
- data/lib/hecks/bluebook/dsl/bootstrap_table.rb +2 -1
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +31 -3
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +122 -3
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +1 -1
- data/lib/hecks/bluebook/dsl/query_builder.rb +27 -1
- data/lib/hecks/bluebook/dsl/rule_reference.rb +1 -1
- data/lib/hecks/bluebook/dsl/world_builder.rb +29 -2
- data/lib/hecks/bluebook/expression/canonical_form.rb +1 -1
- data/lib/hecks/bluebook/expression/resolver.rb +3 -2
- data/lib/hecks/bluebook/hexagon.rb +13 -5
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +1 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +4 -1
- data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
- data/lib/hecks/bluebook/meta_validator.rb +9 -4
- data/lib/hecks/bluebook/model_check.rb +23 -0
- data/lib/hecks/bluebook/pattern_subset.rb +38 -0
- data/lib/hecks/bluebook/query.rb +20 -5
- data/lib/hecks/bluebook/smoke_test.rb +1 -1
- data/lib/hecks/canonical_json.rb +30 -0
- data/lib/hecks/chapters.rb +102 -0
- data/lib/hecks/cli/behaviors.rb +61 -0
- data/lib/hecks/cli/canonicalise.rb +25 -0
- data/lib/hecks/cli/check_engine_agreement.rb +32 -0
- data/lib/hecks/cli/check_era.rb +88 -0
- data/lib/hecks/cli/console.rb +66 -0
- data/lib/hecks/cli/deploy_template_diff.rb +40 -0
- data/lib/hecks/cli/doc_coverage.rb +32 -0
- data/lib/hecks/cli/document.rb +2 -2
- data/lib/hecks/cli/expression_projection.rb +41 -0
- data/lib/hecks/cli/follow.rb +88 -0
- data/lib/hecks/cli/history.rb +44 -0
- data/lib/hecks/cli/ir.rb +1 -1
- data/lib/hecks/cli/mcp.rb +3 -3
- data/lib/hecks/cli/model_check.rb +15 -8
- data/lib/hecks/cli/pattern_cases.rb +47 -0
- data/lib/hecks/cli/present.rb +39 -0
- data/lib/hecks/cli/project_cli.rb +224 -32
- data/lib/hecks/cli/project_diagrams.rb +4 -3
- data/lib/hecks/cli/project_glossary.rb +44 -0
- data/lib/hecks/cli/reference.rb +46 -0
- data/lib/hecks/cli/refresh_projections.rb +44 -0
- data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
- data/lib/hecks/cli/release.rb +70 -0
- data/lib/hecks/cli/release_gem.rb +59 -0
- data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
- data/lib/hecks/cli/rspec_shard_files.rb +66 -0
- data/lib/hecks/cli/run.rb +3 -3
- data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
- data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
- data/lib/hecks/cli/shape.rb +70 -0
- data/lib/hecks/cli/smoke_http.rb +230 -0
- data/lib/hecks/cli/smoke_test.rb +5 -3
- data/lib/hecks/cli/spec_example.rb +27 -0
- data/lib/hecks/cli/statements.rb +32 -0
- data/lib/hecks/cli/stores.rb +4 -5
- data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
- data/lib/hecks/cli.rb +201 -52
- data/lib/hecks/codemod.rb +324 -0
- data/lib/hecks/corpus.rb +423 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +591 -23
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -4
- data/lib/hecks/deploy/oidc.json +82 -2
- data/lib/hecks/doc/reference.rb +351 -0
- data/lib/hecks/doors/cli_door.rb +196 -0
- data/lib/hecks/doors/cli_runner.rb +297 -0
- data/lib/hecks/{facade → doors}/command_request.rb +1 -1
- data/lib/hecks/{facade → doors}/handle.rb +2 -2
- data/lib/hecks/{facade → doors}/json_door.rb +4 -4
- data/lib/hecks/doors/launcher_options.rb +129 -0
- data/lib/hecks/{cli → doors}/mcp_door.rb +7 -7
- data/lib/hecks/doors/mcp_door_scope.rb +97 -0
- data/lib/hecks/{facade/surface → doors/ruby_door}/aggregate_door.rb +8 -3
- data/lib/hecks/{facade/surface → doors/ruby_door}/chapter.rb +3 -3
- data/lib/hecks/{facade/surface.rb → doors/ruby_door.rb} +36 -5
- data/lib/hecks/doors.rb +61 -0
- data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +1 -1
- data/lib/hecks/embryonaut_bluebook.rb +1 -1
- data/lib/hecks/engine_agreement.rb +156 -0
- data/lib/hecks/facade.rb +24 -37
- data/lib/hecks/forms/app.rb +6 -6
- data/lib/hecks/forms/banking_presentation.rb +50 -0
- data/lib/hecks/forms/field_shape.rb +2 -1
- data/lib/hecks/forms/port_argument.rb +1 -1
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
- data/lib/hecks/fuzzing/combination_miner.rb +86 -0
- data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
- data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
- data/lib/hecks/fuzzing/differential.rb +156 -0
- data/lib/hecks/fuzzing/domain_generator.rb +615 -0
- data/lib/hecks/fuzzing/era_boundary.rb +71 -0
- data/lib/hecks/fuzzing/form_census.rb +136 -0
- data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
- data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
- data/lib/hecks/fuzzing/outside_world.rb +45 -0
- data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
- data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
- data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
- data/lib/hecks/fuzzing/properties/guards.rb +190 -0
- data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
- data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
- data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
- data/lib/hecks/fuzzing/properties/querying.rb +175 -0
- data/lib/hecks/fuzzing/properties.rb +162 -0
- data/lib/hecks/fuzzing/qa_settings.rb +123 -0
- data/lib/hecks/fuzzing/replay.rb +505 -0
- data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
- data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
- data/lib/hecks/fuzzing/self_consistency.rb +339 -0
- data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
- data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
- data/lib/hecks/fuzzing/shrinker.rb +166 -0
- data/lib/hecks/fuzzing/structural_skips.rb +33 -0
- data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
- data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
- data/lib/hecks/fuzzing/value_generator.rb +216 -0
- data/lib/hecks/fuzzing.rb +23 -0
- data/lib/hecks/grammar/evolve.rb +336 -0
- data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
- data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
- data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
- data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
- data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
- data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
- data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
- data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
- data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
- data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
- data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
- data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
- data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
- data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
- data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
- data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
- data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
- data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
- data/lib/hecks/hecks/adapters/git.adapter +7 -0
- data/lib/hecks/hecks/adapters/git.rb +102 -0
- data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
- data/lib/hecks/hecks/adapters/host_http.rb +65 -0
- data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
- data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
- data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
- data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
- data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
- data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
- data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
- data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
- data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
- data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
- data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
- data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
- data/lib/hecks/hecks/adapters/local_files.rb +46 -0
- data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
- data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
- data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
- data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
- data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
- data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
- data/lib/hecks/hecks/adapters/shell.adapter +7 -0
- data/lib/hecks/hecks/adapters/shell.rb +49 -0
- data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
- data/lib/hecks/hecks/adapters/terminal.rb +74 -0
- data/lib/hecks/hecks/codebase.behaviors +172 -0
- data/lib/hecks/hecks/codebase.bluebook +2453 -0
- data/lib/hecks/hecks/context_map.hecksagon +13 -0
- data/lib/hecks/hecks/custodian.behaviors +179 -0
- data/lib/hecks/hecks/custodian.bluebook +1847 -0
- data/lib/hecks/hecks/deploy.behaviors +74 -0
- data/lib/hecks/hecks/deploy.world +12 -0
- data/lib/hecks/hecks/environments/memory.world +10 -0
- data/lib/hecks/hecks/governance.world +7 -0
- data/lib/hecks/hecks/hecks.behaviors +62 -0
- data/lib/hecks/hecks/hecks.bluebook +124 -0
- data/lib/hecks/hecks/hecks.hecksagon +390 -0
- data/lib/hecks/hecks/hecks.world +42 -0
- data/lib/hecks/kernel_capabilities.rb +194 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +11 -0
- data/lib/hecks/language/bluebook/query.bluebook +7 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +4 -4
- data/lib/hecks/language/hecksagon/domain_port.bluebook +10 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +20 -0
- data/lib/hecks/mcp_stdio_guard.rb +2 -2
- data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
- data/lib/hecks/persistence_legacy_fixture.rb +113 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +8 -5
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +4 -1
- data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +15 -2
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +32 -15
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +15 -5
- data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +1 -1
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +43 -24
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
- data/lib/hecks/ports/persistence/state_codec.rb +24 -5
- data/lib/hecks/projection_files.rb +285 -0
- data/lib/hecks/projections/bootstrap_table.rb +1 -1
- data/lib/hecks/projections/deploy/fargate.rb +5 -5
- data/lib/hecks/projections/deploy/lambda.rb +43 -32
- data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
- data/lib/hecks/projections/deploy/preview/template.rb +1 -1
- data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
- data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
- data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
- data/lib/hecks/projections/deploy/shared.rb +1 -1
- data/lib/hecks/projections/diagrams.rb +3 -3
- data/lib/hecks/projections/model/deviations.rb +1 -1
- data/lib/hecks/projections/parser_table.rb +4 -4
- data/lib/hecks/projections/reference.rb +2 -3
- data/lib/hecks/projections/rust_vocabulary.rb +1 -1
- data/lib/hecks/projector/cli_projector.rb +106 -37
- data/lib/hecks/projector.rb +1 -1
- data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
- data/lib/hecks/quality_control/adapters/agent.rb +58 -0
- data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
- data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
- data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
- data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
- data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
- data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
- data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
- data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
- data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
- data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
- data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
- data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
- data/lib/hecks/quality_control/cli/child.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
- data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
- data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
- data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
- data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
- data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
- data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
- data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
- data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
- data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
- data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
- data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
- data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
- data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
- data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
- data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
- data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
- data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
- data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
- data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
- data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
- data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
- data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
- data/lib/hecks/query_ir.rb +346 -0
- data/lib/hecks/query_ir_mcp.rb +198 -0
- data/lib/hecks/release/runner/ci_publisher.rb +2 -2
- data/lib/hecks/release/runner/clean_tree.rb +42 -0
- data/lib/hecks/release/runner/console.rb +6 -0
- data/lib/hecks/release/runner/gem_publisher.rb +14 -7
- data/lib/hecks/release/runner/npm_publisher.rb +6 -36
- data/lib/hecks/release/runner/preflight.rb +26 -2
- data/lib/hecks/release/runner/published.rb +8 -26
- data/lib/hecks/release/runner/tagger.rb +30 -15
- data/lib/hecks/release/runner.rb +57 -6
- data/lib/hecks/router/namespace_installer.rb +3 -3
- data/lib/hecks/runtime/adapter_lookup.rb +124 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +4 -0
- data/lib/hecks/runtime/dependency_planning.rb +20 -2
- data/lib/hecks/runtime/dispatcher.rb +53 -3
- data/lib/hecks/runtime/interpreting.rb +3 -0
- data/lib/hecks/runtime/loader.rb +65 -12
- data/lib/hecks/runtime/outbox.rb +1 -1
- data/lib/hecks/runtime/policy_interpreter.rb +5 -2
- data/lib/hecks/runtime/port_operation_interpreter.rb +2 -10
- data/lib/hecks/runtime/query_interpreter.rb +77 -0
- data/lib/hecks/runtime/reaction_outcome.rb +89 -0
- data/lib/hecks/runtime/refusal_wording.rb +23 -1
- data/lib/hecks/runtime/registry/verification.rb +163 -4
- data/lib/hecks/runtime/registry.rb +57 -3
- data/lib/hecks/runtime/remote_dispatcher.rb +31 -2
- data/lib/hecks/runtime/value/coercion.rb +23 -135
- data/lib/hecks/runtime/value/field_checks.rb +172 -0
- data/lib/hecks/runtime/value.rb +4 -1
- data/lib/hecks/runtime.rb +20 -6
- data/lib/hecks/rust_build/conformance.rb +158 -0
- data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
- data/lib/hecks/rust_build/coverage.rb +218 -0
- data/lib/hecks/rust_build/native_build.rb +124 -0
- data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
- data/lib/hecks/rust_build/project_rust.rb +332 -0
- data/lib/hecks/rust_build/wasm.rb +105 -0
- data/lib/hecks/rust_build/wasm_browser.rb +113 -0
- data/lib/hecks/rust_build.rb +144 -0
- data/lib/hecks/storehouse.rb +16 -16
- data/lib/hecks/tenancy/bluebook/tenancy.bluebook +2 -2
- data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +1 -1
- data/lib/hecks/three_zero/forms.yml +127 -0
- data/lib/hecks/three_zero.rb +12 -0
- data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
- data/lib/hecks/tools/comment_style.rb +1070 -0
- data/lib/hecks/tools/corpus_report.rb +87 -0
- data/lib/hecks/tools/deploy_recipe.rb +255 -0
- data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
- data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
- data/lib/hecks/tools/era_projection_backfill.rb +94 -0
- data/lib/hecks/tools/era_reattest.rb +146 -0
- data/lib/hecks/tools/evolve_run.rb +189 -0
- data/lib/hecks/tools/fuzz_sweep.rb +373 -0
- data/lib/hecks/tools/heki_compaction.rb +100 -0
- data/lib/hecks/tools/hoist_local_givens.rb +246 -0
- data/lib/hecks/tools/journal_compaction.rb +89 -0
- data/lib/hecks/tools/oidc_manifests.rb +70 -0
- data/lib/hecks/tools/query_ir_run.rb +81 -0
- data/lib/hecks/tools/regeneration_run.rb +166 -0
- data/lib/hecks/tools/rust_comment_style.rb +642 -0
- data/lib/hecks/tools/sequence_script.rb +62 -0
- data/lib/hecks/tools/tail_merge.rb +117 -0
- data/lib/hecks/tools/tenant_provisioning.rb +142 -0
- data/lib/hecks/tools/translation_audit.rb +208 -0
- data/lib/hecks/tools/translation_scaffold.rb +131 -0
- data/lib/hecks/tools.rb +86 -0
- data/lib/hecks/version.rb +1 -1
- data/lib/hecks.rb +32 -15
- data/qa/settings.yml +66 -0
- data/rust/.cargo/config.toml +6 -0
- data/rust/.gitignore +2 -0
- data/rust/Cargo.lock +54 -0
- data/rust/Cargo.toml +61 -0
- data/rust/build/.cargo/config.toml +3 -0
- data/rust/build/.gitignore +1 -0
- data/rust/build/Cargo.lock +7 -0
- data/rust/build/Cargo.toml +19 -0
- data/rust/build/src/build_artifact.rs +47 -0
- data/rust/build/src/cargo_sync.rs +248 -0
- data/rust/build/src/json.rs +421 -0
- data/rust/build/src/lineage_pass.rs +285 -0
- data/rust/build/src/main.rs +51 -0
- data/rust/build/src/optional_pass.rs +150 -0
- data/rust/build/src/pipeline.rs +264 -0
- data/rust/build/src/reserved_names.rs +76 -0
- data/rust/build/src/resolve.rs +124 -0
- data/rust/build/src/root.rs +25 -0
- data/rust/build/src/sidecars.rs +73 -0
- data/rust/build/src/subprocess.rs +51 -0
- data/rust/build/src/tmp.rs +31 -0
- data/rust/codegen/.cargo/config.toml +3 -0
- data/rust/codegen/.gitignore +1 -0
- data/rust/codegen/Cargo.lock +7 -0
- data/rust/codegen/Cargo.toml +20 -0
- data/rust/codegen/src/attr.rs +32 -0
- data/rust/codegen/src/bridging.rs +481 -0
- data/rust/codegen/src/commands.rs +1226 -0
- data/rust/codegen/src/constraints.rs +109 -0
- data/rust/codegen/src/dependency_planning.rs +209 -0
- data/rust/codegen/src/domain_generator.rs +1288 -0
- data/rust/codegen/src/exemplar.rs +230 -0
- data/rust/codegen/src/expr_emitter.rs +87 -0
- data/rust/codegen/src/fielded.rs +192 -0
- data/rust/codegen/src/hecks_naming.rs +33 -0
- data/rust/codegen/src/json.rs +335 -0
- data/rust/codegen/src/json_codec.rs +697 -0
- data/rust/codegen/src/literal.rs +207 -0
- data/rust/codegen/src/main.rs +290 -0
- data/rust/codegen/src/manifest.rs +227 -0
- data/rust/codegen/src/mutations.rs +784 -0
- data/rust/codegen/src/naming.rs +286 -0
- data/rust/codegen/src/ports.rs +208 -0
- data/rust/codegen/src/prelude.rs +116 -0
- data/rust/codegen/src/queries.rs +786 -0
- data/rust/codegen/src/reactions.rs +532 -0
- data/rust/codegen/src/read_models.rs +697 -0
- data/rust/codegen/src/reference_specs.rs +40 -0
- data/rust/codegen/src/registry.rs +966 -0
- data/rust/codegen/src/reserved_names.rs +76 -0
- data/rust/codegen/src/shared.rs +93 -0
- data/rust/codegen/src/skip_reason.rs +25 -0
- data/rust/codegen/src/types.rs +362 -0
- data/rust/host/.cargo/config.toml +3 -0
- data/rust/host/.gitignore +1 -0
- data/rust/host/Cargo.lock +4297 -0
- data/rust/host/Cargo.toml +61 -0
- data/rust/host/HECKS_RELEASE +1 -0
- data/rust/host/rds-ca-bundle.pem +2736 -0
- data/rust/host/src/api.rs +1596 -0
- data/rust/host/src/approval.rs +652 -0
- data/rust/host/src/auth.rs +1287 -0
- data/rust/host/src/bin/expr_harness.rs +46 -0
- data/rust/host/src/bin/lineage_harness.rs +119 -0
- data/rust/host/src/bin/mint_harness.rs +135 -0
- data/rust/host/src/checkout.rs +265 -0
- data/rust/host/src/dispatch.rs +1443 -0
- data/rust/host/src/expr_json.rs +1117 -0
- data/rust/host/src/field_hints.rs +52 -0
- data/rust/host/src/ir.rs +733 -0
- data/rust/host/src/journal.rs +874 -0
- data/rust/host/src/lambda_client.rs +378 -0
- data/rust/host/src/log.rs +147 -0
- data/rust/host/src/main.rs +474 -0
- data/rust/host/src/mint.rs +1865 -0
- data/rust/host/src/payments/keystore.rs +330 -0
- data/rust/host/src/payments/tests.rs +1400 -0
- data/rust/host/src/payments.rs +767 -0
- data/rust/host/src/presentation.rs +698 -0
- data/rust/host/src/presentation_write.rs +1431 -0
- data/rust/host/src/query_step.rs +149 -0
- data/rust/host/src/rate_limit.rs +904 -0
- data/rust/host/src/reference_transform.rs +241 -0
- data/rust/host/src/reference_validate.rs +338 -0
- data/rust/host/src/resend.rs +296 -0
- data/rust/host/src/secrets.rs +106 -0
- data/rust/host/src/server.rs +663 -0
- data/rust/host/src/storage_shape.rs +175 -0
- data/rust/host/src/test_pg.rs +40 -0
- data/rust/host/src/ui_schema.rs +1351 -0
- data/rust/host/src/wasm_runner.rs +191 -0
- data/rust/host/src/web/newsletter/cooldown.rs +126 -0
- data/rust/host/src/web/newsletter/tests.rs +104 -0
- data/rust/host/src/web/newsletter.rs +310 -0
- data/rust/host/src/web/newsletter_send.rs +357 -0
- data/rust/host/src/web/registrations.rs +1505 -0
- data/rust/host/src/web.rs +2937 -0
- data/rust/lsp/.gitignore +1 -0
- data/rust/lsp/Cargo.lock +7 -0
- data/rust/lsp/Cargo.toml +16 -0
- data/rust/lsp/README.md +133 -0
- data/rust/lsp/src/diagnostics.rs +165 -0
- data/rust/lsp/src/json.rs +385 -0
- data/rust/lsp/src/main.rs +399 -0
- data/rust/lsp/src/outline.rs +177 -0
- data/rust/lsp/src/rpc.rs +67 -0
- data/rust/parser/.cargo/config.toml +5 -0
- data/rust/parser/.gitignore +1 -0
- data/rust/parser/Cargo.lock +7 -0
- data/rust/parser/Cargo.toml +21 -0
- data/rust/parser/src/build/closed_sets.rs +27 -0
- data/rust/parser/src/build/identity.rs +276 -0
- data/rust/parser/src/build/mod.rs +12 -0
- data/rust/parser/src/build/naming.rs +141 -0
- data/rust/parser/src/build/pattern_subset.rs +161 -0
- data/rust/parser/src/build/query_derive.rs +72 -0
- data/rust/parser/src/build/query_inference.rs +269 -0
- data/rust/parser/src/build/query_options.rs +100 -0
- data/rust/parser/src/build/read_model.rs +94 -0
- data/rust/parser/src/build/references.rs +32 -0
- data/rust/parser/src/canonical.rs +114 -0
- data/rust/parser/src/diag.rs +55 -0
- data/rust/parser/src/emit.rs +953 -0
- data/rust/parser/src/expr/ast_json.rs +147 -0
- data/rust/parser/src/expr/evaluator.rs +81 -0
- data/rust/parser/src/expr/mod.rs +84 -0
- data/rust/parser/src/expr/resolver.rs +497 -0
- data/rust/parser/src/ir.rs +387 -0
- data/rust/parser/src/keywords.rs +585 -0
- data/rust/parser/src/lex.rs +662 -0
- data/rust/parser/src/main.rs +252 -0
- data/rust/parser/src/parse/aggregate.rs +612 -0
- data/rust/parser/src/parse/chapter.rs +517 -0
- data/rust/parser/src/parse/command.rs +637 -0
- data/rust/parser/src/parse/domain_port.rs +127 -0
- data/rust/parser/src/parse/entity.rs +527 -0
- data/rust/parser/src/parse/file.rs +67 -0
- data/rust/parser/src/parse/hecksagon.rs +231 -0
- data/rust/parser/src/parse/lifecycle.rs +162 -0
- data/rust/parser/src/parse/mod.rs +1262 -0
- data/rust/parser/src/parse/policy.rs +87 -0
- data/rust/parser/src/parse/process_manager.rs +305 -0
- data/rust/parser/src/parse/query.rs +100 -0
- data/rust/parser/src/parse/read_model.rs +214 -0
- data/rust/parser/src/parse/value_object.rs +250 -0
- data/rust/parser/src/ruby_value.rs +422 -0
- data/rust/project/bridging.rb +257 -0
- data/rust/project/commands.rb +877 -0
- data/rust/project/constraints.rb +86 -0
- data/rust/project/dependency_planning.rb +178 -0
- data/rust/project/domain_generator.rb +980 -0
- data/rust/project/exemplar.rb +148 -0
- data/rust/project/expr_emitter.rb +72 -0
- data/rust/project/fielded.rb +141 -0
- data/rust/project/json_codec.rb +641 -0
- data/rust/project/mutations.rb +721 -0
- data/rust/project/naming.rb +205 -0
- data/rust/project/ports.rb +65 -0
- data/rust/project/queries.rb +493 -0
- data/rust/project/reactions.rb +317 -0
- data/rust/project/read_models.rb +690 -0
- data/rust/project/reference_specs.rb +27 -0
- data/rust/project/registry.rb +396 -0
- data/rust/project/skip_reason.rb +29 -0
- data/rust/project/types.rb +225 -0
- data/rust/project/write_if_changed.rb +83 -0
- data/rust/project.rb +30 -0
- data/rust/project_rust_pipeline.rb +383 -0
- data/rust/src/exemplar/commands.rs +279 -0
- data/rust/src/exemplar/constraints.rs +18 -0
- data/rust/src/exemplar/fielded.rs +280 -0
- data/rust/src/exemplar/json.rs +277 -0
- data/rust/src/exemplar/mod.rs +17 -0
- data/rust/src/exemplar/mutations.rs +80 -0
- data/rust/src/exemplar/queries.rs +33 -0
- data/rust/src/exemplar/reactions.rs +88 -0
- data/rust/src/exemplar/read_models.rs +48 -0
- data/rust/src/exemplar/registry.rs +166 -0
- data/rust/src/exemplar/types.rs +44 -0
- data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
- data/rust/src/kernel/attribute_shapes/list.rs +18 -0
- data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
- data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
- data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
- data/rust/src/kernel/cli.rs +585 -0
- data/rust/src/kernel/dispatch.rs +1090 -0
- data/rust/src/kernel/expr.rs +458 -0
- data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
- data/rust/src/kernel/expression_operators/comparison.rs +48 -0
- data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
- data/rust/src/kernel/expression_operators/logical.rs +13 -0
- data/rust/src/kernel/expression_operators/membership.rs +18 -0
- data/rust/src/kernel/expression_operators/mod.rs +68 -0
- data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
- data/rust/src/kernel/expression_operators/positional.rs +126 -0
- data/rust/src/kernel/expression_operators/presence.rs +101 -0
- data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
- data/rust/src/kernel/expression_operators/sized.rs +35 -0
- data/rust/src/kernel/expression_operators/text.rs +79 -0
- data/rust/src/kernel/expression_operators/to_string.rs +18 -0
- data/rust/src/kernel/json.rs +779 -0
- data/rust/src/kernel/mod.rs +133 -0
- data/rust/src/kernel/named_query.rs +219 -0
- data/rust/src/kernel/orchestrate.rs +1810 -0
- data/rust/src/kernel/pattern.rs +307 -0
- data/rust/src/kernel/query_comparators.rs +206 -0
- data/rust/src/kernel/query_ordering.rs +103 -0
- data/rust/src/kernel/read_model.rs +914 -0
- data/rust/src/kernel/reference_lookup.rs +149 -0
- data/rust/src/kernel/repository.rs +468 -0
- data/rust/src/kernel/routing.rs +612 -0
- data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
- data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
- data/rust/src/kernel/vocab/field_hint.rs +70 -0
- data/rust/src/kernel/vocab/mod.rs +20 -0
- data/rust/src/kernel/vocab/query_comparator.rs +65 -0
- data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
- data/rust/src/lib.rs +8 -0
- data/rust/src/main.rs +16 -0
- data/rust/web/.gitignore +1 -0
- data/rust/web/Cargo.lock +119 -0
- data/rust/web/Cargo.toml +18 -0
- data/rust/web/src/lib.rs +8 -0
- metadata +477 -12
- data/lib/hecks/facade/cli_door.rb +0 -96
- data/lib/hecks/facade/cli_runner.rb +0 -127
- data/lib/hecks/mcp_door_scope.rb +0 -95
data/rust/lsp/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/target
|
data/rust/lsp/Cargo.lock
ADDED
data/rust/lsp/Cargo.toml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "hecks_lsp"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
|
|
6
|
+
# Empty table: makes this crate its own workspace root instead of joining `rust`'s.
|
|
7
|
+
[workspace]
|
|
8
|
+
|
|
9
|
+
[[bin]]
|
|
10
|
+
name = "hecks-lsp"
|
|
11
|
+
path = "src/main.rs"
|
|
12
|
+
|
|
13
|
+
# No dependencies beyond std: a small synchronous local tool. LSP stdio framing is a few lines,
|
|
14
|
+
# and src/json.rs vendors a minimal JSON pair as rust/build/src/json.rs does.
|
|
15
|
+
# Revisit if it ever needs to serve concurrent requests.
|
|
16
|
+
[dependencies]
|
data/rust/lsp/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# hecks-lsp
|
|
2
|
+
|
|
3
|
+
A minimal Language Server Protocol front end for `.bluebook`/`.hecksagon`
|
|
4
|
+
files. It doesn't parse anything itself — it shells out to `rust/parser`'s
|
|
5
|
+
own `hecks-parse` binary and turns whatever that says into
|
|
6
|
+
`textDocument/publishDiagnostics` notifications. See `src/main.rs`'s and
|
|
7
|
+
`src/diagnostics.rs`'s own header comments for the reasoning; this file
|
|
8
|
+
is setup + roadmap.
|
|
9
|
+
|
|
10
|
+
## What it does today
|
|
11
|
+
|
|
12
|
+
- `initialize` / `initialized` / `shutdown` / `exit`
|
|
13
|
+
- `textDocument/didOpen` / `didChange` (full sync) / `didSave` / `didClose`
|
|
14
|
+
- On every one of those, stages the buffer to a scratch file and runs
|
|
15
|
+
`hecks-parse chapter --chapter <Name> <scratch file>`, where `<Name>`
|
|
16
|
+
is scraped from the buffer's own `Hecks.bluebook "Name"` /
|
|
17
|
+
`Hecks.hecksagon "Name"` line. A clean parse publishes an empty
|
|
18
|
+
diagnostics list; a failure publishes exactly one `Diagnostic`
|
|
19
|
+
(`rust/parser` stops at the first error, so there is never more than
|
|
20
|
+
one to report — see `diagnostics.rs`).
|
|
21
|
+
- Diagnostics carry the parser's real message and its `expected one of:
|
|
22
|
+
...` list, at `severity: Warning` when the cause is
|
|
23
|
+
`not_yet_implemented` (a real Stage 1 gap, not a bug in your file) and
|
|
24
|
+
`severity: Error` otherwise.
|
|
25
|
+
- `textDocument/documentSymbol` — an outline of every
|
|
26
|
+
`aggregate`/`entity`/`value_object`/`command`/`query`/`policy`/
|
|
27
|
+
`process_manager`/`read_model` in the open file, nested by `do`/`end`
|
|
28
|
+
depth. Sourced from a text scan of the buffer (`outline.rs`), not from
|
|
29
|
+
`hecks-parse`'s own IR — see that file's header for why (short version:
|
|
30
|
+
the IR carries no source line for anything, and often fails to build
|
|
31
|
+
at all under Stage 1's still-partial coverage, so this needed to work
|
|
32
|
+
independently of a parse succeeding).
|
|
33
|
+
- `textDocument/definition` — resolves the bare identifier under the
|
|
34
|
+
cursor (a `reference_to Customer` / `belongs_to Account` usage) to
|
|
35
|
+
wherever that aggregate/entity/value_object is actually declared,
|
|
36
|
+
first in the same file, then across sibling `.bluebook`/`.hecksagon`
|
|
37
|
+
files in the same directory (a chapter routinely spans several files —
|
|
38
|
+
`parse::chapter`'s own header — and the declaration is often in one of
|
|
39
|
+
them, not the file doing the referencing).
|
|
40
|
+
|
|
41
|
+
## What it doesn't do yet
|
|
42
|
+
|
|
43
|
+
- **`documentSymbol`/`definition` are text-scanned, not grammar-verified.**
|
|
44
|
+
Real, but a second, unverified idea of the grammar rather than a
|
|
45
|
+
projection of `syntax.bluebook` the way `rust/parser`'s own
|
|
46
|
+
`keywords.rs` is — see `outline.rs`'s header for the reasoning and its
|
|
47
|
+
one real failure mode (a buffer with unbalanced `do`/`end` mid-edit).
|
|
48
|
+
Only `aggregate`/`entity`/`value_object` names are valid `definition`
|
|
49
|
+
targets (`outline::is_reference_target`) — a `command`/`query` name
|
|
50
|
+
is never referenced by a bare identifier elsewhere in the corpus the
|
|
51
|
+
way a type name is, so it isn't one.
|
|
52
|
+
- **No column info.** `rust/parser`'s own `Diagnostic` only tracks a
|
|
53
|
+
line, so every diagnostic underlines the whole line. Real squiggle
|
|
54
|
+
precision needs `rust/parser` to track columns first — nothing to fix
|
|
55
|
+
here until then.
|
|
56
|
+
- **No completion, hover, or go-to-definition.** The parser's four gates
|
|
57
|
+
(`rust/parser/src/parse/mod.rs`: shape → word → body → argument)
|
|
58
|
+
already encode "what's legal at this point in the grammar" — that's
|
|
59
|
+
exactly what a completion engine needs, but it's not exposed as
|
|
60
|
+
anything this crate can call today. The clean way to add it, in
|
|
61
|
+
keeping with `rust/parser` staying a bin-only, subprocess-only sibling
|
|
62
|
+
(see `diagnostics.rs`'s header): add a new `hecks-parse` subcommand
|
|
63
|
+
(e.g. `hecks-parse complete --chapter <Name> <file> --line N --col N`)
|
|
64
|
+
that runs the same gates up to the cursor and prints the legal next
|
|
65
|
+
words as JSON, the same shape `run_coverage` already prints its list
|
|
66
|
+
in. Once that exists, wiring `textDocument/completion` here is a small
|
|
67
|
+
addition, not a redesign.
|
|
68
|
+
- **Only one diagnostic per document.** Inherited from `rust/parser`'s
|
|
69
|
+
own fail-fast design (`parse::chapter`'s doc comment: "Stops at the
|
|
70
|
+
FIRST diagnostic"). If that ever becomes a `Vec<Diagnostic>`, this
|
|
71
|
+
crate's `diagnostics::run` only needs to return `Vec<FileDiagnostic>`
|
|
72
|
+
instead of `Option<FileDiagnostic>` — `main.rs` already publishes
|
|
73
|
+
whatever list it's handed.
|
|
74
|
+
- **Single-file chapters only.** A chapter split across multiple
|
|
75
|
+
`.bluebook` files, or paired with a `.hecksagon` file
|
|
76
|
+
(`parse::chapter`'s own header describes both), is only ever checked
|
|
77
|
+
one file at a time here. Fine for every example under `examples/*/`
|
|
78
|
+
today; would need this crate to also track a project's file layout
|
|
79
|
+
(which files share a chapter name) to do better.
|
|
80
|
+
|
|
81
|
+
## Building it
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
cd rust/parser && cargo build # produces target/debug/hecks-parse
|
|
85
|
+
cd rust/lsp && cargo build # produces target/debug/hecks-lsp
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`hecks-lsp` looks for `hecks-parse` in this order: `$HECKS_PARSE_BIN`,
|
|
89
|
+
then `$PATH`, then `../parser/target/{debug,release}/hecks-parse`
|
|
90
|
+
relative to wherever it's launched from (the common case while both
|
|
91
|
+
crates are built side by side out of one checkout). If none of those
|
|
92
|
+
resolve, it still runs — every document just gets an empty diagnostics
|
|
93
|
+
list and one `window/logMessage` warning explaining why.
|
|
94
|
+
|
|
95
|
+
## Wiring it into an editor
|
|
96
|
+
|
|
97
|
+
**Neovim** (`nvim-lspconfig`, manual server since this isn't a published
|
|
98
|
+
server yet):
|
|
99
|
+
|
|
100
|
+
```lua
|
|
101
|
+
vim.api.nvim_create_autocmd("FileType", {
|
|
102
|
+
pattern = { "ruby" }, -- .bluebook/.hecksagon have no LSP-registered
|
|
103
|
+
-- filetype of their own yet; match on extension
|
|
104
|
+
-- instead if you've set one up, or broaden this
|
|
105
|
+
callback = function(args)
|
|
106
|
+
local fname = vim.api.nvim_buf_get_name(args.buf)
|
|
107
|
+
if not (fname:match("%.bluebook$") or fname:match("%.hecksagon$")) then
|
|
108
|
+
return
|
|
109
|
+
end
|
|
110
|
+
vim.lsp.start({
|
|
111
|
+
name = "hecks-lsp",
|
|
112
|
+
cmd = { "/absolute/path/to/rust/lsp/target/debug/hecks-lsp" },
|
|
113
|
+
root_dir = vim.fs.dirname(fname),
|
|
114
|
+
})
|
|
115
|
+
end,
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**VS Code**: `editors/vscode/` (repo root) is a minimal real extension —
|
|
120
|
+
see its own README for build/install steps. Not published to the
|
|
121
|
+
marketplace; installed locally (copy into your extensions directory, or
|
|
122
|
+
F5 an Extension Development Host). It contributes no syntax highlighting
|
|
123
|
+
grammar (a separate gap — see the top-level tooling report), just the
|
|
124
|
+
language client wiring.
|
|
125
|
+
|
|
126
|
+
## Testing it without an editor
|
|
127
|
+
|
|
128
|
+
`cargo test` covers the pure functions (`chapter_name` extraction,
|
|
129
|
+
`Diagnostic` line parsing, JSON round-tripping). For a full stdio
|
|
130
|
+
round-trip, speak Content-Length-framed JSON-RPC to the process
|
|
131
|
+
directly — `initialize` → `initialized` → `textDocument/didOpen` with a
|
|
132
|
+
real `.bluebook`'s text → read the `publishDiagnostics` notification
|
|
133
|
+
that comes back.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
//! Maps the first error from `hecks-parse chapter` on a buffer to an LSP diagnostic.
|
|
2
|
+
//! The parser reports a file and line only, so a diagnostic covers the whole line.
|
|
3
|
+
|
|
4
|
+
use std::path::{Path, PathBuf};
|
|
5
|
+
use std::process::Command;
|
|
6
|
+
|
|
7
|
+
pub struct FileDiagnostic {
|
|
8
|
+
pub line: usize, // 1-indexed
|
|
9
|
+
pub message: String,
|
|
10
|
+
pub expected: Vec<String>,
|
|
11
|
+
/// True when the grammar admits the construct but the parser does not build it yet.
|
|
12
|
+
pub not_yet_implemented: bool,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// Runs `hecks-parse chapter` on the file at `path` and returns at most one diagnostic.
|
|
16
|
+
///
|
|
17
|
+
/// `Ok(None)` means the parse succeeded or the buffer declares no chapter.
|
|
18
|
+
/// Runs the parser as a subprocess because `rust/parser` ships only a binary target.
|
|
19
|
+
pub fn run(hecks_parse: &Path, path: &Path, text: &str) -> Result<Option<FileDiagnostic>, String> {
|
|
20
|
+
let Some(name) = chapter_name(text) else {
|
|
21
|
+
return Ok(None);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let output = Command::new(hecks_parse)
|
|
25
|
+
.arg("chapter")
|
|
26
|
+
.arg("--chapter")
|
|
27
|
+
.arg(&name)
|
|
28
|
+
.arg(path)
|
|
29
|
+
.output()
|
|
30
|
+
.map_err(|e| format!("could not run {}: {e}", hecks_parse.display()))?;
|
|
31
|
+
|
|
32
|
+
if output.status.success() {
|
|
33
|
+
return Ok(None);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
37
|
+
let Some(first_line) = stderr.lines().next() else {
|
|
38
|
+
return Err(format!(
|
|
39
|
+
"{} exited with {:?} and no stderr",
|
|
40
|
+
hecks_parse.display(),
|
|
41
|
+
output.status.code()
|
|
42
|
+
));
|
|
43
|
+
};
|
|
44
|
+
Ok(parse_diagnostic_line(first_line, path))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// Finds the name in the first `Hecks.bluebook "Name"` or `Hecks.hecksagon "Name"` line.
|
|
48
|
+
// Hand-scanned because this crate takes no dependencies.
|
|
49
|
+
fn chapter_name(text: &str) -> Option<String> {
|
|
50
|
+
for line in text.lines() {
|
|
51
|
+
for needle in ["Hecks.bluebook \"", "Hecks.hecksagon \""] {
|
|
52
|
+
if let Some(after) = line.trim_start().strip_prefix(needle) {
|
|
53
|
+
if let Some(end) = after.find('"') {
|
|
54
|
+
return Some(after[..end].to_string());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
None
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// Parses `<file>:<line>: <message>` with an optional `(expected one of: a, b, c)` suffix.
|
|
63
|
+
// `path` is stripped as a known prefix so a colon inside the message cannot confuse the split.
|
|
64
|
+
fn parse_diagnostic_line(line: &str, path: &Path) -> Option<FileDiagnostic> {
|
|
65
|
+
let prefix = format!("{}:", path.display());
|
|
66
|
+
let rest = line.strip_prefix(&prefix)?;
|
|
67
|
+
let (line_no, rest) = rest.split_once(':')?;
|
|
68
|
+
let line_no: usize = line_no.trim().parse().ok()?;
|
|
69
|
+
let rest = rest.strip_prefix(' ').unwrap_or(rest);
|
|
70
|
+
|
|
71
|
+
let (message, expected) = match rest.rfind(" (expected one of: ") {
|
|
72
|
+
Some(idx) if rest.ends_with(')') => {
|
|
73
|
+
let message = &rest[..idx];
|
|
74
|
+
let list = &rest[idx + " (expected one of: ".len()..rest.len() - 1];
|
|
75
|
+
let expected = list.split(", ").map(str::to_string).collect();
|
|
76
|
+
(message.to_string(), expected)
|
|
77
|
+
}
|
|
78
|
+
_ => (rest.to_string(), Vec::new()),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Some(FileDiagnostic {
|
|
82
|
+
line: line_no,
|
|
83
|
+
not_yet_implemented: message.starts_with("not yet implemented:"),
|
|
84
|
+
message,
|
|
85
|
+
expected,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Finds `hecks-parse`: `HECKS_PARSE_BIN`, then `PATH`, then `../parser/target/{debug,release}`.
|
|
90
|
+
pub fn locate_hecks_parse() -> Option<PathBuf> {
|
|
91
|
+
if let Ok(explicit) = std::env::var("HECKS_PARSE_BIN") {
|
|
92
|
+
let p = PathBuf::from(explicit);
|
|
93
|
+
if p.is_file() {
|
|
94
|
+
return Some(p);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if let Ok(path) = which("hecks-parse") {
|
|
98
|
+
return Some(path);
|
|
99
|
+
}
|
|
100
|
+
for candidate in [
|
|
101
|
+
"../parser/target/debug/hecks-parse",
|
|
102
|
+
"../parser/target/release/hecks-parse",
|
|
103
|
+
] {
|
|
104
|
+
let p = PathBuf::from(candidate);
|
|
105
|
+
if p.is_file() {
|
|
106
|
+
return Some(p);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
None
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// Walks `PATH` for a file named `name`.
|
|
113
|
+
fn which(name: &str) -> Result<PathBuf, ()> {
|
|
114
|
+
let path_var = std::env::var_os("PATH").ok_or(())?;
|
|
115
|
+
for dir in std::env::split_paths(&path_var) {
|
|
116
|
+
let candidate = dir.join(name);
|
|
117
|
+
if candidate.is_file() {
|
|
118
|
+
return Ok(candidate);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
Err(())
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#[cfg(test)]
|
|
125
|
+
mod tests {
|
|
126
|
+
use super::*;
|
|
127
|
+
|
|
128
|
+
#[test]
|
|
129
|
+
fn finds_a_bluebook_chapter_name() {
|
|
130
|
+
let text = "Hecks.bluebook \"Pizzas\" do\nend\n";
|
|
131
|
+
assert_eq!(chapter_name(text), Some("Pizzas".to_string()));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#[test]
|
|
135
|
+
fn finds_a_hecksagon_chapter_name_when_indented() {
|
|
136
|
+
let text = " Hecks.hecksagon \"Banking\" do\nend\n";
|
|
137
|
+
assert_eq!(chapter_name(text), Some("Banking".to_string()));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#[test]
|
|
141
|
+
fn no_chapter_name_is_not_an_error() {
|
|
142
|
+
assert_eq!(chapter_name("# just a comment\n"), None);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
#[test]
|
|
146
|
+
fn parses_a_diagnostic_with_an_expected_list() {
|
|
147
|
+
let path = Path::new("/tmp/pizzas.bluebook");
|
|
148
|
+
let line = "/tmp/pizzas.bluebook:12: unknown word 'topping' in Aggregate (expected one of: attribute, command, query)";
|
|
149
|
+
let diag = parse_diagnostic_line(line, path).expect("parses");
|
|
150
|
+
assert_eq!(diag.line, 12);
|
|
151
|
+
assert_eq!(diag.message, "unknown word 'topping' in Aggregate");
|
|
152
|
+
assert_eq!(diag.expected, vec!["attribute", "command", "query"]);
|
|
153
|
+
assert!(!diag.not_yet_implemented);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#[test]
|
|
157
|
+
fn parses_a_not_yet_implemented_diagnostic_with_no_expected_list() {
|
|
158
|
+
let path = Path::new("/tmp/pizzas.bluebook");
|
|
159
|
+
let line = "/tmp/pizzas.bluebook:5: not yet implemented: Bluebook.report (Stage 1 — see spec/parser_coverage_spec.rb)";
|
|
160
|
+
let diag = parse_diagnostic_line(line, path).expect("parses");
|
|
161
|
+
assert_eq!(diag.line, 5);
|
|
162
|
+
assert!(diag.expected.is_empty());
|
|
163
|
+
assert!(diag.not_yet_implemented);
|
|
164
|
+
}
|
|
165
|
+
}
|