textus 0.55.1 → 0.56.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/CHANGELOG.md +175 -2768
- data/README.md +17 -18
- data/lib/textus/artifact.rb +8 -0
- data/lib/textus/errors.rb +2 -39
- data/lib/textus/human.rb +7 -0
- data/lib/textus/infra/adapters/concurrency_adapter.rb +15 -0
- data/lib/textus/infra/clock.rb +7 -0
- data/lib/textus/infra/database.rb +127 -0
- data/lib/textus/infra/file_system.rb +54 -0
- data/lib/textus/infra/locks.rb +50 -0
- data/lib/textus/infra/port/clock.rb +18 -0
- data/lib/textus/infra/port/publisher.rb +71 -0
- data/lib/textus/infra/port/sentinel.rb +25 -0
- data/lib/textus/infra/port/sentinel_store.rb +93 -0
- data/lib/textus/infra/store/audit_log.rb +42 -0
- data/lib/textus/infra/store/base.rb +25 -0
- data/lib/textus/infra/store/cursor_store.rb +27 -0
- data/lib/textus/infra/store/entry_index.rb +31 -0
- data/lib/textus/infra/store/envelope/meta.rb +63 -0
- data/lib/textus/infra/store/file_store.rb +23 -0
- data/lib/textus/infra/store/index/builder.rb +28 -0
- data/lib/textus/infra/store/index/lookup.rb +23 -0
- data/lib/textus/infra/store/link_store.rb +43 -0
- data/lib/textus/infra/store/workflow_queue.rb +54 -0
- data/lib/textus/infra/store.rb +29 -0
- data/lib/textus/ingest.rb +8 -0
- data/lib/textus/lanes/artifact/cache.rb +35 -0
- data/lib/textus/lanes/artifact/handlers.rb +29 -0
- data/lib/textus/lanes/artifact/lifecycle.rb +23 -0
- data/lib/textus/lanes/artifact/verbs.rb +18 -0
- data/lib/textus/lanes/ingest/dedup.rb +17 -0
- data/lib/textus/lanes/ingest/entry_types/asset.rb +45 -0
- data/lib/textus/lanes/ingest/entry_types/link.rb +16 -0
- data/lib/textus/lanes/ingest/entry_types/text.rb +17 -0
- data/lib/textus/lanes/ingest/entry_types.rb +25 -0
- data/lib/textus/lanes/ingest/handlers.rb +54 -0
- data/lib/textus/lanes/ingest/index_rebuilder.rb +13 -0
- data/lib/textus/lanes/ingest/key_builder.rb +33 -0
- data/lib/textus/lanes/ingest/resolver.rb +21 -0
- data/lib/textus/lanes/knowledge/freeform.rb +15 -0
- data/lib/textus/lanes/knowledge/handlers.rb +53 -0
- data/lib/textus/lanes/knowledge/runner.rb +45 -0
- data/lib/textus/lanes/knowledge/verbs.rb +16 -0
- data/lib/textus/lanes/scratchpad/handlers.rb +164 -0
- data/lib/textus/lanes/scratchpad/verbs.rb +73 -0
- data/lib/textus/{gate → protocol}/binder.rb +2 -10
- data/lib/textus/protocol/boot/catalog.rb +34 -0
- data/lib/textus/protocol/boot/context.rb +124 -0
- data/lib/textus/protocol/boot/protocol.rb +33 -0
- data/lib/textus/protocol/boot.rb +42 -0
- data/lib/textus/protocol/builder/domain.rb +17 -0
- data/lib/textus/protocol/builder/infrastructure.rb +17 -0
- data/lib/textus/protocol/builder/runtime.rb +46 -0
- data/lib/textus/protocol/builder.rb +11 -0
- data/lib/textus/protocol/container.rb +22 -0
- data/lib/textus/protocol/diff.rb +170 -0
- data/lib/textus/protocol/entry_constraint.rb +54 -0
- data/lib/textus/protocol/envelope.rb +70 -0
- data/lib/textus/protocol/format/base.rb +80 -0
- data/lib/textus/protocol/format/bash.rb +10 -0
- data/lib/textus/protocol/format/javascript.rb +10 -0
- data/lib/textus/protocol/format/json.rb +82 -0
- data/lib/textus/protocol/format/markdown.rb +53 -0
- data/lib/textus/protocol/format/python.rb +10 -0
- data/lib/textus/protocol/format/ruby.rb +10 -0
- data/lib/textus/protocol/format/script.rb +55 -0
- data/lib/textus/protocol/format/text.rb +48 -0
- data/lib/textus/protocol/format/yaml.rb +105 -0
- data/lib/textus/protocol/format.rb +73 -0
- data/lib/textus/protocol/freshness/ttl_evaluator.rb +61 -0
- data/lib/textus/protocol/gate.rb +61 -0
- data/lib/textus/protocol/handlers/command_context.rb +19 -0
- data/lib/textus/protocol/handlers/concern.rb +15 -0
- data/lib/textus/protocol/handlers/ops/audit_filter.rb +37 -0
- data/lib/textus/protocol/handlers/ops/bulk_planner.rb +38 -0
- data/lib/textus/protocol/handlers/ops/data_mv.rb +49 -0
- data/lib/textus/protocol/handlers/ops/git_blame.rb +65 -0
- data/lib/textus/protocol/handlers/ops/pulse_coordinator.rb +37 -0
- data/lib/textus/protocol/handlers/ops/source_expander.rb +41 -0
- data/lib/textus/protocol/handlers/query_context.rb +41 -0
- data/lib/textus/protocol/handlers/read.rb +67 -0
- data/lib/textus/protocol/handlers/system.rb +93 -0
- data/lib/textus/protocol/handlers/write.rb +57 -0
- data/lib/textus/protocol/init.rb +143 -0
- data/lib/textus/protocol/key/grammar.rb +35 -0
- data/lib/textus/protocol/key/matching.rb +23 -0
- data/lib/textus/protocol/key/path.rb +23 -0
- data/lib/textus/protocol/key.rb +25 -0
- data/lib/textus/protocol/lane.rb +12 -0
- data/lib/textus/{store/geometry.rb → protocol/layout.rb} +32 -22
- data/lib/textus/protocol/links/resolver.rb +33 -0
- data/lib/textus/protocol/links/uri_rewriter.rb +30 -0
- data/lib/textus/protocol/links.rb +10 -0
- data/lib/textus/protocol/manifest/data.rb +90 -0
- data/lib/textus/protocol/manifest/entry/base.rb +95 -0
- data/lib/textus/protocol/manifest/entry/leaf.rb +19 -0
- data/lib/textus/protocol/manifest/entry/nested.rb +19 -0
- data/lib/textus/protocol/manifest/entry/parser.rb +71 -0
- data/lib/textus/protocol/manifest/entry/publish.rb +209 -0
- data/lib/textus/protocol/manifest/entry.rb +10 -0
- data/lib/textus/protocol/manifest/policy/publish_target.rb +36 -0
- data/lib/textus/protocol/manifest/policy.rb +69 -0
- data/lib/textus/protocol/manifest/resolver.rb +156 -0
- data/lib/textus/protocol/manifest/schema/contract.rb +53 -0
- data/lib/textus/protocol/manifest/schema/validator.rb +52 -0
- data/lib/textus/protocol/manifest/schema.rb +40 -0
- data/lib/textus/protocol/manifest.rb +62 -0
- data/lib/textus/protocol/produce/render/context.rb +43 -0
- data/lib/textus/protocol/produce/render.rb +44 -0
- data/lib/textus/protocol/schema/registry.rb +44 -0
- data/lib/textus/protocol/schema/tools.rb +104 -0
- data/lib/textus/protocol/schema.rb +117 -0
- data/lib/textus/protocol/session/bridge.rb +11 -0
- data/lib/textus/protocol/session/context.rb +5 -0
- data/lib/textus/protocol/session.rb +87 -0
- data/lib/textus/protocol/store_engine/delete.rb +37 -0
- data/lib/textus/protocol/store_engine/move.rb +109 -0
- data/lib/textus/protocol/store_engine/pipeline.rb +61 -0
- data/lib/textus/protocol/store_engine/put.rb +104 -0
- data/lib/textus/protocol/store_engine.rb +86 -0
- data/lib/textus/protocol/v4.rb +25 -0
- data/lib/textus/protocol/verb_registry/arg_spec.rb +19 -0
- data/lib/textus/protocol/verb_registry/core_verbs.rb +164 -0
- data/lib/textus/protocol/verb_registry/verb_spec.rb +42 -0
- data/lib/textus/protocol/verb_registry.rb +42 -0
- data/lib/textus/surface/cli/group/{rule.rb → web.rb} +2 -2
- data/lib/textus/surface/cli/runner.rb +25 -25
- data/lib/textus/surface/cli/sources.rb +1 -3
- data/lib/textus/surface/cli/verb/get.rb +3 -6
- data/lib/textus/surface/cli/verb/init.rb +1 -1
- data/lib/textus/surface/cli/verb/put.rb +8 -6
- data/lib/textus/surface/cli/verb/web_serve.rb +22 -0
- data/lib/textus/surface/cli.rb +25 -6
- data/lib/textus/surface/dispatch.rb +17 -0
- data/lib/textus/surface/mcp/adapters/mcp_adapter.rb +28 -0
- data/lib/textus/surface/mcp/catalog.rb +26 -62
- data/lib/textus/surface/mcp/cursor_manager.rb +22 -0
- data/lib/textus/surface/mcp/drift_annotation.rb +19 -0
- data/lib/textus/surface/mcp/errors.rb +0 -10
- data/lib/textus/surface/mcp/server.rb +46 -46
- data/lib/textus/surface/watcher.rb +18 -12
- data/lib/textus/surface/web.rb +50 -0
- data/lib/textus/value/call.rb +1 -1
- data/lib/textus/{core → value}/duration.rb +1 -4
- data/lib/textus/value/etag.rb +7 -7
- data/lib/textus/value/payload.rb +7 -0
- data/lib/textus/version.rb +1 -1
- data/lib/textus/workflow/consumer.rb +39 -0
- data/lib/textus/workflow/dsl/lifecycle.rb +32 -0
- data/lib/textus/workflow/dsl/pattern_matcher.rb +20 -0
- data/lib/textus/workflow/dsl/step_builder.rb +56 -0
- data/lib/textus/workflow/dsl.rb +111 -21
- data/lib/textus/workflow/event_emitter.rb +21 -0
- data/lib/textus/workflow/publisher.rb +59 -0
- data/lib/textus/workflow/registry.rb +31 -8
- data/lib/textus/workflow/runner.rb +25 -61
- data/lib/textus/workflow/scheduler.rb +45 -0
- data/lib/textus/workflow/step_executor.rb +78 -0
- data/lib/textus/workflow/step_helpers.rb +102 -0
- data/lib/textus/workflow.rb +2 -5
- data/lib/textus.rb +16 -80
- metadata +167 -183
- data/SPEC.md +0 -908
- data/docs/architecture/README.md +0 -273
- data/docs/reference/conventions.md +0 -138
- data/lib/textus/action/accept.rb +0 -46
- data/lib/textus/action/audit.rb +0 -94
- data/lib/textus/action/base.rb +0 -42
- data/lib/textus/action/blame.rb +0 -79
- data/lib/textus/action/boot.rb +0 -15
- data/lib/textus/action/data_mv.rb +0 -58
- data/lib/textus/action/deps.rb +0 -19
- data/lib/textus/action/doctor.rb +0 -17
- data/lib/textus/action/drain.rb +0 -31
- data/lib/textus/action/enqueue.rb +0 -37
- data/lib/textus/action/get.rb +0 -34
- data/lib/textus/action/ingest.rb +0 -199
- data/lib/textus/action/jobs.rb +0 -27
- data/lib/textus/action/key_delete.rb +0 -26
- data/lib/textus/action/key_delete_prefix.rb +0 -35
- data/lib/textus/action/key_mv.rb +0 -122
- data/lib/textus/action/key_mv_prefix.rb +0 -48
- data/lib/textus/action/list.rb +0 -28
- data/lib/textus/action/propose.rb +0 -42
- data/lib/textus/action/published.rb +0 -22
- data/lib/textus/action/pulse.rb +0 -49
- data/lib/textus/action/put.rb +0 -38
- data/lib/textus/action/rdeps.rb +0 -24
- data/lib/textus/action/reject.rb +0 -28
- data/lib/textus/action/rule_explain.rb +0 -81
- data/lib/textus/action/rule_lint.rb +0 -62
- data/lib/textus/action/rule_list.rb +0 -38
- data/lib/textus/action/schema_envelope.rb +0 -22
- data/lib/textus/action/uid.rb +0 -19
- data/lib/textus/action/where.rb +0 -21
- data/lib/textus/boot.rb +0 -202
- data/lib/textus/contract/arg.rb +0 -10
- data/lib/textus/contract/dsl.rb +0 -88
- data/lib/textus/contract/spec.rb +0 -25
- data/lib/textus/contract.rb +0 -12
- data/lib/textus/core/freshness/evaluator.rb +0 -150
- data/lib/textus/core/freshness/verdict.rb +0 -34
- data/lib/textus/core/freshness.rb +0 -11
- data/lib/textus/core/retention/sweep.rb +0 -57
- data/lib/textus/core/retention.rb +0 -11
- data/lib/textus/core/sentinel.rb +0 -30
- data/lib/textus/doctor/check/audit_log.rb +0 -34
- data/lib/textus/doctor/check/generator_drift.rb +0 -29
- data/lib/textus/doctor/check/illegal_keys.rb +0 -60
- data/lib/textus/doctor/check/manifest_files.rb +0 -25
- data/lib/textus/doctor/check/notebook_sources.rb +0 -50
- data/lib/textus/doctor/check/orphaned_publish_targets.rb +0 -35
- data/lib/textus/doctor/check/proposal_targets.rb +0 -45
- data/lib/textus/doctor/check/protocol_version.rb +0 -47
- data/lib/textus/doctor/check/publish_tree_index_overlap.rb +0 -48
- data/lib/textus/doctor/check/raw_asset_paths.rb +0 -50
- data/lib/textus/doctor/check/rule_ambiguity.rb +0 -49
- data/lib/textus/doctor/check/schema_parse_error.rb +0 -28
- data/lib/textus/doctor/check/schema_violations.rb +0 -28
- data/lib/textus/doctor/check/schemas.rb +0 -26
- data/lib/textus/doctor/check/sentinels.rb +0 -60
- data/lib/textus/doctor/check/stale_reviewed_stamp.rb +0 -54
- data/lib/textus/doctor/check/templates.rb +0 -29
- data/lib/textus/doctor/check/unowned_schema_fields.rb +0 -40
- data/lib/textus/doctor/check.rb +0 -41
- data/lib/textus/doctor/validator.rb +0 -93
- data/lib/textus/doctor.rb +0 -54
- data/lib/textus/format/base.rb +0 -49
- data/lib/textus/format/json.rb +0 -102
- data/lib/textus/format/markdown.rb +0 -80
- data/lib/textus/format/shared.rb +0 -17
- data/lib/textus/format/text.rb +0 -55
- data/lib/textus/format/yaml.rb +0 -125
- data/lib/textus/format.rb +0 -46
- data/lib/textus/gate/auth.rb +0 -212
- data/lib/textus/gate.rb +0 -92
- data/lib/textus/init.rb +0 -157
- data/lib/textus/jobs.rb +0 -9
- data/lib/textus/key/distance.rb +0 -55
- data/lib/textus/key/grammar.rb +0 -33
- data/lib/textus/key/matching.rb +0 -24
- data/lib/textus/key/path.rb +0 -28
- data/lib/textus/manifest/capabilities.rb +0 -29
- data/lib/textus/manifest/data.rb +0 -102
- data/lib/textus/manifest/entry/base.rb +0 -105
- data/lib/textus/manifest/entry/ignore_matcher.rb +0 -46
- data/lib/textus/manifest/entry/leaf.rb +0 -17
- data/lib/textus/manifest/entry/nested.rb +0 -37
- data/lib/textus/manifest/entry/parser.rb +0 -99
- data/lib/textus/manifest/entry/produced.rb +0 -36
- data/lib/textus/manifest/entry/publish/mode.rb +0 -45
- data/lib/textus/manifest/entry/publish/none.rb +0 -14
- data/lib/textus/manifest/entry/publish/subtree_mirror.rb +0 -73
- data/lib/textus/manifest/entry/publish/template.rb +0 -16
- data/lib/textus/manifest/entry/publish/to_paths.rb +0 -76
- data/lib/textus/manifest/entry/publish/tree.rb +0 -50
- data/lib/textus/manifest/entry/publish.rb +0 -45
- data/lib/textus/manifest/entry/validators/format_matrix.rb +0 -21
- data/lib/textus/manifest/entry/validators/ignore.rb +0 -28
- data/lib/textus/manifest/entry/validators/publish.rb +0 -30
- data/lib/textus/manifest/entry/validators.rb +0 -18
- data/lib/textus/manifest/entry.rb +0 -8
- data/lib/textus/manifest/policy/matcher.rb +0 -51
- data/lib/textus/manifest/policy/publish_target.rb +0 -34
- data/lib/textus/manifest/policy/react.rb +0 -30
- data/lib/textus/manifest/policy/retention.rb +0 -29
- data/lib/textus/manifest/policy/source.rb +0 -30
- data/lib/textus/manifest/policy.rb +0 -95
- data/lib/textus/manifest/resolver.rb +0 -118
- data/lib/textus/manifest/rules.rb +0 -86
- data/lib/textus/manifest/schema/contract.rb +0 -61
- data/lib/textus/manifest/schema/keys.rb +0 -90
- data/lib/textus/manifest/schema/semantics/cross_field.rb +0 -53
- data/lib/textus/manifest/schema/semantics/invariants.rb +0 -125
- data/lib/textus/manifest/schema/semantics/migration.rb +0 -83
- data/lib/textus/manifest/schema/semantics.rb +0 -27
- data/lib/textus/manifest/schema/validator.rb +0 -48
- data/lib/textus/manifest/schema/vocabulary.rb +0 -25
- data/lib/textus/manifest/schema.rb +0 -30
- data/lib/textus/manifest.rb +0 -65
- data/lib/textus/meta.rb +0 -54
- data/lib/textus/port/audit_log.rb +0 -268
- data/lib/textus/port/build_lock.rb +0 -64
- data/lib/textus/port/clock.rb +0 -10
- data/lib/textus/port/publisher.rb +0 -60
- data/lib/textus/port/sentinel_store.rb +0 -83
- data/lib/textus/port/storage/file_stat.rb +0 -19
- data/lib/textus/port/storage/file_store.rb +0 -26
- data/lib/textus/port/store.rb +0 -93
- data/lib/textus/port/watcher_lock.rb +0 -48
- data/lib/textus/produce/engine.rb +0 -50
- data/lib/textus/produce/render.rb +0 -20
- data/lib/textus/schema/tools.rb +0 -115
- data/lib/textus/schema.rb +0 -100
- data/lib/textus/schemas.rb +0 -54
- data/lib/textus/store/compositor.rb +0 -34
- data/lib/textus/store/container.rb +0 -43
- data/lib/textus/store/cursor.rb +0 -26
- data/lib/textus/store/envelope/reader.rb +0 -43
- data/lib/textus/store/envelope/writer.rb +0 -195
- data/lib/textus/store/index/builder.rb +0 -74
- data/lib/textus/store/index/lookup.rb +0 -60
- data/lib/textus/store/jobs/base.rb +0 -13
- data/lib/textus/store/jobs/index.rb +0 -15
- data/lib/textus/store/jobs/materialize.rb +0 -15
- data/lib/textus/store/jobs/plan.rb +0 -11
- data/lib/textus/store/jobs/planner.rb +0 -104
- data/lib/textus/store/jobs/queue.rb +0 -154
- data/lib/textus/store/jobs/registry.rb +0 -19
- data/lib/textus/store/jobs/retention.rb +0 -50
- data/lib/textus/store/jobs/sweep.rb +0 -21
- data/lib/textus/store/jobs/worker.rb +0 -64
- data/lib/textus/store/session.rb +0 -37
- data/lib/textus/store.rb +0 -99
- data/lib/textus/surface/cli/verb/doctor.rb +0 -19
- data/lib/textus/surface/cli/verb/schema_diff.rb +0 -17
- data/lib/textus/surface/cli/verb/schema_init.rb +0 -21
- data/lib/textus/surface/cli/verb/schema_migrate.rb +0 -21
- data/lib/textus/surface/mcp.rb +0 -8
- data/lib/textus/surface/projector.rb +0 -27
- data/lib/textus/surface/role_scope.rb +0 -34
- data/lib/textus/value/command.rb +0 -16
- data/lib/textus/value/envelope.rb +0 -89
- data/lib/textus/value/result.rb +0 -26
- data/lib/textus/workflow/collector.rb +0 -27
- data/lib/textus/workflow/context.rb +0 -5
- data/lib/textus/workflow/loader.rb +0 -17
- data/lib/textus/workflow/pattern.rb +0 -18
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
|
+
require "erb"
|
|
6
|
+
|
|
7
|
+
module Textus
|
|
8
|
+
module Workflow
|
|
9
|
+
module StepHelpers
|
|
10
|
+
def fetch_json(url, headers: {})
|
|
11
|
+
uri = URI(url)
|
|
12
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
13
|
+
http.use_ssl = uri.scheme == "https"
|
|
14
|
+
http.open_timeout = 5
|
|
15
|
+
http.read_timeout = 30
|
|
16
|
+
|
|
17
|
+
request = Net::HTTP::Get.new(uri)
|
|
18
|
+
headers.each { |k, v| request[k] = v }
|
|
19
|
+
request["Accept"] ||= "application/json"
|
|
20
|
+
|
|
21
|
+
response = http.request(request)
|
|
22
|
+
raise "HTTP #{response.code} for #{url}" unless response.is_a?(Net::HTTPOK)
|
|
23
|
+
|
|
24
|
+
JSON.parse(response.body)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def render_template(name, data)
|
|
28
|
+
path = @container.layout.template_path(name)
|
|
29
|
+
raise "template not found: #{name}" unless File.exist?(path)
|
|
30
|
+
|
|
31
|
+
template = File.read(path)
|
|
32
|
+
ctx = Textus::Protocol::Produce::Render::Context.new(
|
|
33
|
+
container: @container, call: @call,
|
|
34
|
+
key: @ctx&.key, entry: @ctx&.entry
|
|
35
|
+
)
|
|
36
|
+
renderer = Textus::Protocol::Produce::Render.new(template, ctx)
|
|
37
|
+
renderer.bytes_for(data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def merge_hashes(*hashes)
|
|
41
|
+
hashes.reduce({}) { |acc, h| deep_merge(acc, h) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def pluck(source, *keys)
|
|
45
|
+
source.slice(*keys)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_naming(entries, pattern:, code:, fix:)
|
|
49
|
+
entries.filter_map do |entry|
|
|
50
|
+
key = entry_value(entry, :key)
|
|
51
|
+
path = entry_value(entry, :path)
|
|
52
|
+
name = path && !path.to_s.empty? ? File.basename(path.to_s) : key.to_s.split(".").last
|
|
53
|
+
next if pattern.match?(name)
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
"code" => code,
|
|
57
|
+
"level" => "warning",
|
|
58
|
+
"subject" => key,
|
|
59
|
+
"message" => "#{key} does not match the required naming pattern #{pattern.inspect}",
|
|
60
|
+
"fix" => fix,
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def entry_value(entry, key)
|
|
68
|
+
return entry.public_send(key) if !entry.is_a?(Hash) && entry.respond_to?(key)
|
|
69
|
+
return entry[key] if entry.is_a?(Hash) && entry.key?(key)
|
|
70
|
+
return entry[key.to_s] if entry.is_a?(Hash) && entry.key?(key.to_s)
|
|
71
|
+
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def deep_merge(left_hash, right_hash)
|
|
76
|
+
left_hash.merge(right_hash) do |_key, old_val, new_val|
|
|
77
|
+
if old_val.is_a?(Hash) && new_val.is_a?(Hash)
|
|
78
|
+
deep_merge(old_val, new_val)
|
|
79
|
+
else
|
|
80
|
+
new_val
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build_lanes(ctx)
|
|
86
|
+
data = ctx.manifest.data
|
|
87
|
+
policy = ctx.manifest.policy
|
|
88
|
+
data.declared_lane_kinds.map do |name, kind|
|
|
89
|
+
writers = policy.writers_for(name).map(&:to_s)
|
|
90
|
+
{ "name" => name.to_s, "kind" => kind.to_s,
|
|
91
|
+
"purpose" => data.lane_descs[name].to_s, "writers" => writers }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def build_roles(ctx)
|
|
96
|
+
ctx.manifest.data.role_caps.map do |role, caps|
|
|
97
|
+
{ "name" => role.to_s, "capabilities" => caps.map(&:to_s) }
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/textus/workflow.rb
CHANGED
|
@@ -12,17 +12,14 @@ module Textus
|
|
|
12
12
|
|
|
13
13
|
class NotFound < Textus::Error
|
|
14
14
|
def initialize(key)
|
|
15
|
-
super(:workflow_not_found, "no workflow matches key '#{key}'; add a .textus/workflows/*.rb file with
|
|
15
|
+
super(:workflow_not_found, "no workflow matches key '#{key}'; add a .textus/workflows/*.rb file with on: '#{key}'")
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.workflow(name, &)
|
|
21
|
-
collector = Workflow::Collector.current
|
|
22
|
-
raise "Textus.workflow called outside Workflow::Loader.load_all context" unless collector
|
|
23
|
-
|
|
24
21
|
defn = Workflow::DSL::Definition.new(name)
|
|
25
22
|
defn.instance_eval(&)
|
|
26
|
-
|
|
23
|
+
Workflow::DSL::Definition.register(defn)
|
|
27
24
|
end
|
|
28
25
|
end
|
data/lib/textus.rb
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
require "zeitwerk"
|
|
2
|
-
require "dry-monads"
|
|
3
2
|
require_relative "textus/version"
|
|
4
3
|
require_relative "textus/errors"
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
# Declare the MCP namespace before Zeitwerk encounters surface/mcp/errors.rb,
|
|
6
|
+
# which is pre-required below because its filename (errors.rb) does not match
|
|
7
|
+
# its constant name (ToolError) and cannot be managed by Zeitwerk.
|
|
8
|
+
module Textus
|
|
9
|
+
module Surface
|
|
10
|
+
module MCP
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
6
15
|
require_relative "textus/surface/mcp/errors"
|
|
7
16
|
|
|
17
|
+
require "sinatra/base"
|
|
18
|
+
|
|
8
19
|
loader = Zeitwerk::Loader.for_gem
|
|
9
20
|
loader.inflector.inflect(
|
|
10
21
|
"cli" => "CLI",
|
|
@@ -15,86 +26,11 @@ loader.inflector.inflect(
|
|
|
15
26
|
"dsl" => "DSL",
|
|
16
27
|
)
|
|
17
28
|
loader.ignore(File.expand_path("textus/errors.rb", __dir__))
|
|
18
|
-
loader.ignore(File.expand_path("textus/surface/mcp.rb", __dir__))
|
|
19
29
|
loader.ignore(File.expand_path("textus/surface/mcp/errors.rb", __dir__))
|
|
20
|
-
loader.ignore(File.expand_path("textus/workflow/errors.rb", __dir__))
|
|
21
|
-
# Scaffold sources copied verbatim into user stores by `textus init`. They are
|
|
22
|
-
# templates for user-owned step classes, not gem constants — Zeitwerk must not
|
|
23
|
-
# manage or eager-load them.
|
|
24
30
|
loader.ignore(File.expand_path("textus/init/templates", __dir__))
|
|
25
|
-
loader.ignore(File.expand_path("textus/
|
|
31
|
+
loader.ignore(File.expand_path("textus/protocol/init/templates", __dir__))
|
|
32
|
+
loader.ignore(File.expand_path("textus/protocol/verb_registry/verbs", __dir__))
|
|
26
33
|
loader.setup
|
|
27
34
|
loader.eager_load
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
Textus::Action::VERBS = {
|
|
31
|
-
put: Textus::Action::Put,
|
|
32
|
-
propose: Textus::Action::Propose,
|
|
33
|
-
key_delete: Textus::Action::KeyDelete,
|
|
34
|
-
key_mv: Textus::Action::KeyMv,
|
|
35
|
-
accept: Textus::Action::Accept,
|
|
36
|
-
reject: Textus::Action::Reject,
|
|
37
|
-
enqueue: Textus::Action::Enqueue,
|
|
38
|
-
get: Textus::Action::Get,
|
|
39
|
-
ingest: Textus::Action::Ingest,
|
|
40
|
-
list: Textus::Action::List,
|
|
41
|
-
where: Textus::Action::Where,
|
|
42
|
-
uid: Textus::Action::Uid,
|
|
43
|
-
blame: Textus::Action::Blame,
|
|
44
|
-
audit: Textus::Action::Audit,
|
|
45
|
-
# materialize, refresh, sweep are Worker-only — not in VERBS
|
|
46
|
-
deps: Textus::Action::Deps,
|
|
47
|
-
rdeps: Textus::Action::Rdeps,
|
|
48
|
-
pulse: Textus::Action::Pulse,
|
|
49
|
-
rule_explain: Textus::Action::RuleExplain,
|
|
50
|
-
rule_list: Textus::Action::RuleList,
|
|
51
|
-
published: Textus::Action::Published,
|
|
52
|
-
schema_show: Textus::Action::SchemaEnvelope,
|
|
53
|
-
doctor: Textus::Action::Doctor,
|
|
54
|
-
boot: Textus::Action::Boot,
|
|
55
|
-
jobs: Textus::Action::Jobs,
|
|
56
|
-
data_mv: Textus::Action::DataMv,
|
|
57
|
-
key_mv_prefix: Textus::Action::KeyMvPrefix,
|
|
58
|
-
key_delete_prefix: Textus::Action::KeyDeletePrefix,
|
|
59
|
-
drain: Textus::Action::Drain,
|
|
60
|
-
rule_lint: Textus::Action::RuleLint,
|
|
61
|
-
}.freeze
|
|
62
|
-
|
|
63
|
-
# Derive CLI_VERBS after VERBS is available.
|
|
64
|
-
Textus::Boot::CLI_VERBS = Textus::Boot.build_cli_verbs.freeze
|
|
65
|
-
|
|
66
|
-
# Dynamic verb methods on Store (deferred after VERBS is defined).
|
|
67
|
-
Textus::Action::VERBS.each_key do |verb|
|
|
68
|
-
Textus::Store.define_method(verb) do |*args, role: Textus::Value::Role::DEFAULT, **kwargs|
|
|
69
|
-
as(role).public_send(verb, *args, **kwargs)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
Textus::Surface::RoleScope.define_method(verb) do |*args, **kwargs|
|
|
73
|
-
klass = Textus::Action::VERBS[verb]
|
|
74
|
-
inputs = if klass.respond_to?(:contract?) && klass.contract?
|
|
75
|
-
Textus::Gate::Binder.inputs_from_ordered(klass.contract, args, kwargs)
|
|
76
|
-
else
|
|
77
|
-
kwargs.transform_keys(&:to_sym)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
role_value = if klass.respond_to?(:contract?) && klass.contract? &&
|
|
81
|
-
klass.contract.args.any? { |a| a.name == :role }
|
|
82
|
-
inputs[:role]
|
|
83
|
-
else
|
|
84
|
-
@role
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
@container.gate.dispatch(spec: klass.contract, inputs: inputs, role: role_value, correlation_id: @correlation_id)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
module Textus
|
|
92
|
-
def self.workflow(name, &)
|
|
93
|
-
collector = Workflow::Collector.current
|
|
94
|
-
raise "Textus.workflow called outside Workflow::Loader.load_all context" unless collector
|
|
95
|
-
|
|
96
|
-
defn = Workflow::DSL::Definition.new(name)
|
|
97
|
-
defn.instance_eval(&)
|
|
98
|
-
collector.register(defn)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
36
|
+
Textus::Protocol::Boot::CLI_VERBS = Textus::Protocol::Boot::Catalog.build.freeze
|