textus 0.45.1 → 0.47.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 +29 -0
- data/README.md +53 -26
- data/SPEC.md +15 -14
- data/docs/architecture/README.md +6 -25
- data/lib/textus/boot.rb +1 -0
- data/lib/textus/builder/pipeline.rb +11 -42
- data/lib/textus/builder/renderer/markdown.rb +4 -8
- data/lib/textus/cli/verb/build.rb +1 -10
- data/lib/textus/cli/verb/init.rb +3 -1
- data/lib/textus/cli.rb +29 -1
- data/lib/textus/container.rb +3 -15
- data/lib/textus/contract/resources/build_lock.rb +17 -0
- data/lib/textus/dispatcher.rb +1 -0
- data/lib/textus/doctor/check/orphaned_publish_targets.rb +1 -1
- data/lib/textus/doctor/check/sentinels.rb +1 -1
- data/lib/textus/domain/policy/predicates/fresh_within.rb +6 -5
- data/lib/textus/envelope/io/writer.rb +34 -0
- data/lib/textus/etag.rb +23 -0
- data/lib/textus/hooks/catalog.rb +1 -0
- data/lib/textus/init/templates/orientation_reducer.rb +17 -0
- data/lib/textus/init.rb +67 -4
- data/lib/textus/layout.rb +8 -0
- data/lib/textus/maintenance/key_delete_prefix.rb +5 -4
- data/lib/textus/maintenance/key_mv_prefix.rb +14 -4
- data/lib/textus/maintenance/migrate.rb +5 -4
- data/lib/textus/maintenance/rule_lint.rb +1 -1
- data/lib/textus/maintenance/zone_mv.rb +5 -4
- data/lib/textus/mcp/server.rb +14 -4
- data/lib/textus/ports/publisher.rb +3 -2
- data/lib/textus/ports/sentinel_store.rb +8 -7
- data/lib/textus/projection.rb +4 -3
- data/lib/textus/read/audit.rb +1 -1
- data/lib/textus/read/blame.rb +1 -1
- data/lib/textus/read/boot.rb +1 -1
- data/lib/textus/read/capabilities.rb +70 -0
- data/lib/textus/read/deps.rb +1 -1
- data/lib/textus/read/doctor.rb +1 -1
- data/lib/textus/read/freshness.rb +1 -1
- data/lib/textus/read/get.rb +1 -1
- data/lib/textus/read/list.rb +1 -1
- data/lib/textus/read/published.rb +1 -1
- data/lib/textus/read/pulse.rb +4 -4
- data/lib/textus/read/rdeps.rb +1 -1
- data/lib/textus/read/rule_explain.rb +1 -1
- data/lib/textus/read/rule_list.rb +1 -1
- data/lib/textus/read/schema_envelope.rb +1 -1
- data/lib/textus/read/uid.rb +1 -1
- data/lib/textus/read/where.rb +1 -1
- data/lib/textus/session.rb +6 -5
- data/lib/textus/store.rb +48 -25
- data/lib/textus/version.rb +1 -1
- data/lib/textus/write/accept.rb +1 -1
- data/lib/textus/write/build.rb +19 -7
- data/lib/textus/write/delete.rb +1 -1
- data/lib/textus/write/fetch_all.rb +1 -1
- data/lib/textus/write/fetch_worker.rb +1 -1
- data/lib/textus/write/mv.rb +1 -1
- data/lib/textus/write/propose.rb +1 -1
- data/lib/textus/write/put.rb +1 -1
- data/lib/textus/write/reject.rb +1 -1
- data/lib/textus/write/retention_sweep.rb +1 -1
- metadata +4 -1
data/lib/textus/read/list.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :list
|
|
7
7
|
summary "List keys filtered by zone and/or prefix."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
arg :prefix, String, description: "restrict to keys starting with this dotted prefix, e.g. 'knowledge.runbooks'"
|
|
10
10
|
arg :zone, String, description: "restrict to one zone by name (see `boot` zones); combine with prefix to narrow further"
|
|
11
11
|
view(:cli) { |rows| { "entries" => rows } }
|
data/lib/textus/read/pulse.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Textus
|
|
|
11
11
|
|
|
12
12
|
verb :pulse
|
|
13
13
|
summary "Delta since cursor — changed entries, stale, pending proposals, doctor summary."
|
|
14
|
-
surfaces :cli, :
|
|
14
|
+
surfaces :cli, :mcp
|
|
15
15
|
around :cursor
|
|
16
16
|
arg :since, Integer, session_default: :cursor, description: "audit seq to diff from; defaults to the session cursor"
|
|
17
17
|
|
|
@@ -33,7 +33,7 @@ module Textus
|
|
|
33
33
|
"stale" => freshness_rows.select { |r| r[:status] == :stale }.map { |r| r[:key] },
|
|
34
34
|
"pending_review" => review_keys,
|
|
35
35
|
"doctor" => doctor_summary,
|
|
36
|
-
"
|
|
36
|
+
"contract_etag" => contract_etag,
|
|
37
37
|
"next_due_at" => soonest_due(freshness_rows),
|
|
38
38
|
"hook_errors" => hook_errors_since(since),
|
|
39
39
|
}
|
|
@@ -76,8 +76,8 @@ module Textus
|
|
|
76
76
|
}
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def
|
|
80
|
-
|
|
79
|
+
def contract_etag
|
|
80
|
+
Textus::Etag.for_contract(@root)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def hook_errors_since(seq)
|
data/lib/textus/read/rdeps.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :rdeps
|
|
7
7
|
summary "List the derived entries that depend on a key (reverse deps / impact set)."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
arg :key, String, required: true, positional: true,
|
|
10
10
|
description: "dotted key whose dependents (what would be stranded if it moved) you want"
|
|
11
11
|
|
|
@@ -11,7 +11,7 @@ module Textus
|
|
|
11
11
|
|
|
12
12
|
verb :rule_explain
|
|
13
13
|
summary "Effective rules for a key. Lean {fetch, guard} by default; detail: true adds matched blocks + guard predicates."
|
|
14
|
-
surfaces :cli, :
|
|
14
|
+
surfaces :cli, :mcp
|
|
15
15
|
cli "rule explain"
|
|
16
16
|
arg :key, String, required: true, positional: true,
|
|
17
17
|
description: "dotted key whose effective rules you want (fetch ttl/action, write guard, ...)"
|
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :schema_show
|
|
7
7
|
summary "Return the schema (field shape) for an entry's family, by key."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
cli "schema show"
|
|
10
10
|
arg :key, String, required: true, positional: true,
|
|
11
11
|
description: "any key in the family whose schema you want; returns required/optional fields and their types"
|
data/lib/textus/read/uid.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :uid
|
|
7
7
|
summary "Return the stable UID of an entry without reading its body."
|
|
8
|
-
surfaces :cli
|
|
8
|
+
surfaces :cli
|
|
9
9
|
cli "key uid"
|
|
10
10
|
arg :key, String, required: true, positional: true, description: "entry key"
|
|
11
11
|
view(:cli) { |uid, inputs| { "key" => inputs[:key], "uid" => uid } }
|
data/lib/textus/read/where.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :where
|
|
7
7
|
summary "Resolve a key to its zone, owner, and path without reading the body."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
arg :key, String, required: true, positional: true,
|
|
10
10
|
description: "dotted key to locate (returns zone, owner, path; does not read content)"
|
|
11
11
|
|
data/lib/textus/session.rb
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
module Textus
|
|
2
2
|
# The agent session: per-connection (MCP), per-process (CLI), or per-loop
|
|
3
|
-
# (Ruby) orientation state — the audit cursor plus the
|
|
3
|
+
# (Ruby) orientation state — the audit cursor plus the contract etag and
|
|
4
4
|
# propose_zone captured at boot. Immutable Data value; advance_cursor
|
|
5
|
-
# returns a new instance. ADR 0036.
|
|
6
|
-
Session = Data.define(:role, :cursor, :propose_zone, :
|
|
5
|
+
# returns a new instance. ADR 0036; contract_etag widened in ADR 0074.
|
|
6
|
+
Session = Data.define(:role, :cursor, :propose_zone, :contract_etag) do
|
|
7
7
|
def advance_cursor(new_cursor) = with(cursor: new_cursor)
|
|
8
8
|
|
|
9
9
|
def check_etag!(observed_etag)
|
|
10
|
-
return if observed_etag ==
|
|
10
|
+
return if observed_etag == contract_etag
|
|
11
11
|
|
|
12
12
|
raise Textus::MCP::ContractDrift.new(
|
|
13
|
-
"
|
|
13
|
+
"contract changed (manifest/hooks/schemas were #{short_etag(contract_etag)}, " \
|
|
14
|
+
"now #{short_etag(observed_etag)}); re-run boot",
|
|
14
15
|
)
|
|
15
16
|
end
|
|
16
17
|
|
data/lib/textus/store.rb
CHANGED
|
@@ -2,52 +2,50 @@ require "fileutils"
|
|
|
2
2
|
|
|
3
3
|
module Textus
|
|
4
4
|
class Store
|
|
5
|
-
attr_reader :
|
|
5
|
+
attr_reader :container
|
|
6
|
+
|
|
7
|
+
# Readers are derived from the Container's schema, so the field set lives
|
|
8
|
+
# in exactly one place (Container's Data.define). A new capability added
|
|
9
|
+
# there is automatically exposed on the Store.
|
|
10
|
+
Textus::Container.members.each do |field|
|
|
11
|
+
define_method(field) { @container.public_send(field) }
|
|
12
|
+
end
|
|
6
13
|
|
|
7
14
|
def self.discover(start_dir = Dir.pwd, root: nil)
|
|
8
15
|
explicit = root || ENV.fetch("TEXTUS_ROOT", nil)
|
|
9
16
|
return discover_explicit(explicit) if explicit
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
ascend_for_store(File.expand_path(start_dir)) ||
|
|
19
|
+
raise(IoError.new("no .textus directory found from #{start_dir}"))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private_class_method def self.ascend_for_store(dir)
|
|
12
23
|
loop do
|
|
13
24
|
candidate = File.join(dir, ".textus")
|
|
14
|
-
return new(candidate) if
|
|
25
|
+
return new(candidate) if store_dir?(candidate)
|
|
15
26
|
|
|
16
27
|
parent = File.dirname(dir)
|
|
17
|
-
|
|
28
|
+
return nil if parent == dir
|
|
18
29
|
|
|
19
30
|
dir = parent
|
|
20
31
|
end
|
|
21
|
-
raise IoError.new("no .textus directory found from #{start_dir}")
|
|
22
32
|
end
|
|
23
33
|
|
|
24
34
|
private_class_method def self.discover_explicit(root_arg)
|
|
25
35
|
abs = File.expand_path(root_arg)
|
|
26
|
-
raise IoError.new("no textus store at #{abs}") unless
|
|
36
|
+
raise IoError.new("no textus store at #{abs}") unless store_dir?(abs)
|
|
27
37
|
|
|
28
38
|
new(abs)
|
|
29
39
|
end
|
|
30
40
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
@manifest = Manifest.load(@root)
|
|
34
|
-
@schemas = Schemas.new(File.join(@root, "schemas"))
|
|
35
|
-
@file_store = Ports::Storage::FileStore.new
|
|
36
|
-
@audit_log = Ports::AuditLog.new(
|
|
37
|
-
@root,
|
|
38
|
-
max_size: @manifest.data.audit_config[:max_size],
|
|
39
|
-
keep: @manifest.data.audit_config[:keep],
|
|
40
|
-
)
|
|
41
|
-
@events = Hooks::EventBus.new
|
|
42
|
-
@rpc = Hooks::RpcRegistry.new
|
|
43
|
-
Ports::AuditSubscriber.new(@audit_log).attach(@events)
|
|
44
|
-
Hooks::Builtin.register_all(events: @events, rpc: @rpc)
|
|
45
|
-
Hooks::Loader.new(events: @events, rpc: @rpc).load_dir(File.join(@root, "hooks"))
|
|
46
|
-
@events.publish(:store_loaded, ctx: Hooks::Context.new(scope: as(Role::DEFAULT)))
|
|
41
|
+
private_class_method def self.store_dir?(dir)
|
|
42
|
+
File.directory?(dir) && File.exist?(File.join(dir, "manifest.yaml"))
|
|
47
43
|
end
|
|
48
44
|
|
|
49
|
-
def
|
|
50
|
-
@container
|
|
45
|
+
def initialize(root)
|
|
46
|
+
@container = build_container(File.expand_path(root))
|
|
47
|
+
bootstrap_hooks
|
|
48
|
+
events.publish(:store_loaded, ctx: Hooks::Context.new(scope: as(Role::DEFAULT)))
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
# Build an agent Session oriented at the current cursor/manifest — the
|
|
@@ -57,7 +55,7 @@ module Textus
|
|
|
57
55
|
role: role,
|
|
58
56
|
cursor: audit_log.latest_seq,
|
|
59
57
|
propose_zone: manifest.policy.propose_zone_for(role),
|
|
60
|
-
|
|
58
|
+
contract_etag: Textus::Etag.for_contract(root),
|
|
61
59
|
)
|
|
62
60
|
end
|
|
63
61
|
|
|
@@ -70,5 +68,30 @@ module Textus
|
|
|
70
68
|
as(role).public_send(verb, *args, **kwargs)
|
|
71
69
|
end
|
|
72
70
|
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def build_container(root)
|
|
75
|
+
manifest = Manifest.load(root)
|
|
76
|
+
Container.new(
|
|
77
|
+
root: root,
|
|
78
|
+
manifest: manifest,
|
|
79
|
+
schemas: Schemas.new(File.join(root, "schemas")),
|
|
80
|
+
file_store: Ports::Storage::FileStore.new,
|
|
81
|
+
audit_log: Ports::AuditLog.new(
|
|
82
|
+
root,
|
|
83
|
+
max_size: manifest.data.audit_config[:max_size],
|
|
84
|
+
keep: manifest.data.audit_config[:keep],
|
|
85
|
+
),
|
|
86
|
+
events: Hooks::EventBus.new,
|
|
87
|
+
rpc: Hooks::RpcRegistry.new,
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def bootstrap_hooks
|
|
92
|
+
Ports::AuditSubscriber.new(audit_log).attach(events)
|
|
93
|
+
Hooks::Builtin.register_all(events: events, rpc: rpc)
|
|
94
|
+
Hooks::Loader.new(events: events, rpc: rpc).load_dir(File.join(root, "hooks"))
|
|
95
|
+
end
|
|
73
96
|
end
|
|
74
97
|
end
|
data/lib/textus/version.rb
CHANGED
data/lib/textus/write/accept.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :accept
|
|
7
7
|
summary "apply a queued proposal to its target zone; requires the author capability"
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
cli "accept"
|
|
10
10
|
arg :pending_key, String, required: true, positional: true, description: "the queued proposal's key"
|
|
11
11
|
|
data/lib/textus/write/build.rb
CHANGED
|
@@ -14,8 +14,9 @@ module Textus
|
|
|
14
14
|
|
|
15
15
|
verb :build
|
|
16
16
|
summary "materialize derived entries; publish_to and publish_tree fan out copies"
|
|
17
|
-
surfaces :cli, :
|
|
17
|
+
surfaces :cli, :mcp
|
|
18
18
|
cli "build"
|
|
19
|
+
around :build_lock
|
|
19
20
|
arg :prefix, String, required: false, description: "limit the build to keys under this prefix"
|
|
20
21
|
|
|
21
22
|
def initialize(container:, call:)
|
|
@@ -25,10 +26,21 @@ module Textus
|
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def call(prefix: nil)
|
|
29
|
+
build_role = @manifest.policy.actor_for("build") or
|
|
30
|
+
raise Textus::UsageError.new(
|
|
31
|
+
"no role holds the 'build' capability",
|
|
32
|
+
hint: "declare a role with `can: [build]` in .textus/manifest.yaml",
|
|
33
|
+
)
|
|
34
|
+
build_call = Textus::Call.build(
|
|
35
|
+
role: build_role,
|
|
36
|
+
correlation_id: @call.correlation_id,
|
|
37
|
+
dry_run: @call.dry_run,
|
|
38
|
+
)
|
|
39
|
+
|
|
28
40
|
built = []
|
|
29
41
|
leaves = []
|
|
30
42
|
pruned = []
|
|
31
|
-
context = build_context
|
|
43
|
+
context = build_context(build_call)
|
|
32
44
|
|
|
33
45
|
@manifest.data.entries.each do |mentry|
|
|
34
46
|
next if prefix && !entry_matches_prefix?(mentry, prefix)
|
|
@@ -49,11 +61,11 @@ module Textus
|
|
|
49
61
|
|
|
50
62
|
private
|
|
51
63
|
|
|
52
|
-
def build_context
|
|
64
|
+
def build_context(call)
|
|
53
65
|
Textus::Manifest::Entry::Base::PublishContext.new(
|
|
54
66
|
container: @container,
|
|
55
|
-
call:
|
|
56
|
-
reader: reader,
|
|
67
|
+
call: call,
|
|
68
|
+
reader: reader(call),
|
|
57
69
|
)
|
|
58
70
|
end
|
|
59
71
|
|
|
@@ -70,8 +82,8 @@ module Textus
|
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
|
|
73
|
-
def reader
|
|
74
|
-
|
|
85
|
+
def reader(call)
|
|
86
|
+
Textus::Read::Get.new(container: @container, call: call)
|
|
75
87
|
end
|
|
76
88
|
end
|
|
77
89
|
end
|
data/lib/textus/write/delete.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Textus
|
|
|
6
6
|
verb :delete
|
|
7
7
|
summary "Delete one entry by key. Single-key, lower blast radius than " \
|
|
8
8
|
"key_delete_prefix; guarded by an optional optimistic-concurrency etag. Returns {ok, key, deleted}."
|
|
9
|
-
surfaces :cli, :
|
|
9
|
+
surfaces :cli, :mcp
|
|
10
10
|
cli "key delete"
|
|
11
11
|
arg :key, String, required: true, positional: true,
|
|
12
12
|
description: "dotted entry key to delete"
|
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :fetch_all
|
|
7
7
|
summary "Fetch all stale quarantine entries, optionally scoped by zone/prefix."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
cli "fetch all"
|
|
10
10
|
arg :prefix, String, description: "only refresh stale entries whose key starts with this dotted prefix"
|
|
11
11
|
arg :zone, String, description: "only refresh stale entries in this quarantine zone (see `pulse` stale list)"
|
|
@@ -7,7 +7,7 @@ module Textus
|
|
|
7
7
|
|
|
8
8
|
verb :fetch
|
|
9
9
|
summary "Run a fetch action for one quarantine entry."
|
|
10
|
-
surfaces :cli, :
|
|
10
|
+
surfaces :cli, :mcp
|
|
11
11
|
arg :key, String, required: true, positional: true,
|
|
12
12
|
description: "quarantine-zone entry key to refresh using its declared intake action"
|
|
13
13
|
view { |outcome| { "outcome" => outcome.class.name.split("::").last.downcase } }
|
data/lib/textus/write/mv.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :mv
|
|
7
7
|
summary "Rename one entry (same zone + format). Refuses if the target exists. Single-key, lower blast radius than key_mv_prefix."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
cli "key mv"
|
|
10
10
|
arg :old_key, String, required: true, positional: true,
|
|
11
11
|
description: "current dotted key"
|
data/lib/textus/write/propose.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Textus
|
|
|
9
9
|
|
|
10
10
|
verb :propose
|
|
11
11
|
summary "Write a proposal to the role's propose_zone. Auto-prefixes the key."
|
|
12
|
-
surfaces :cli, :
|
|
12
|
+
surfaces :cli, :mcp
|
|
13
13
|
cli_stdin :json
|
|
14
14
|
arg :key, String, required: true, positional: true,
|
|
15
15
|
description: "key relative to propose_zone, e.g. 'decisions.feature-x'"
|
data/lib/textus/write/put.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Textus
|
|
|
5
5
|
|
|
6
6
|
verb :put
|
|
7
7
|
summary "Create or update an entry. Schema-validated. Returns {uid, etag}."
|
|
8
|
-
surfaces :cli, :
|
|
8
|
+
surfaces :cli, :mcp
|
|
9
9
|
arg :key, String, required: true, positional: true,
|
|
10
10
|
description: "dotted entry key, e.g. 'knowledge.project'; must resolve to a zone the role may write"
|
|
11
11
|
arg :meta, Hash, required: false, wire_name: :_meta,
|
data/lib/textus/write/reject.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Textus
|
|
|
11
11
|
|
|
12
12
|
verb :retain
|
|
13
13
|
summary "Apply each entry's retention policy; prune expired versions."
|
|
14
|
-
surfaces :cli
|
|
14
|
+
surfaces :cli
|
|
15
15
|
cli "retain"
|
|
16
16
|
arg :prefix, String, description: "restrict to keys starting with this dotted prefix"
|
|
17
17
|
arg :zone, String, description: "restrict to entries in this zone"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: textus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.47.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Patrick
|
|
@@ -147,6 +147,7 @@ files:
|
|
|
147
147
|
- lib/textus/contract.rb
|
|
148
148
|
- lib/textus/contract/around.rb
|
|
149
149
|
- lib/textus/contract/binder.rb
|
|
150
|
+
- lib/textus/contract/resources/build_lock.rb
|
|
150
151
|
- lib/textus/contract/resources/cursor.rb
|
|
151
152
|
- lib/textus/contract/sources.rb
|
|
152
153
|
- lib/textus/contract/view.rb
|
|
@@ -222,6 +223,7 @@ files:
|
|
|
222
223
|
- lib/textus/hooks/signature.rb
|
|
223
224
|
- lib/textus/init.rb
|
|
224
225
|
- lib/textus/init/templates/machine_intake.rb
|
|
226
|
+
- lib/textus/init/templates/orientation_reducer.rb
|
|
225
227
|
- lib/textus/key/distance.rb
|
|
226
228
|
- lib/textus/key/grammar.rb
|
|
227
229
|
- lib/textus/key/path.rb
|
|
@@ -282,6 +284,7 @@ files:
|
|
|
282
284
|
- lib/textus/read/audit.rb
|
|
283
285
|
- lib/textus/read/blame.rb
|
|
284
286
|
- lib/textus/read/boot.rb
|
|
287
|
+
- lib/textus/read/capabilities.rb
|
|
285
288
|
- lib/textus/read/deps.rb
|
|
286
289
|
- lib/textus/read/doctor.rb
|
|
287
290
|
- lib/textus/read/freshness.rb
|