kobako 0.15.0-aarch64-linux → 0.16.0-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00df75af1fd85b3c4d3729d456148a282ab904f26162e6930ecd8ad003bcd9df
4
- data.tar.gz: 34533660556ce44eddbc76831b973ed10217e5a3801affbb5b7a991e15069c3a
3
+ metadata.gz: e913ffb24d91b9fa9da48c73682cea2f988a8cb0e1260cb225a4771ba78e8dc6
4
+ data.tar.gz: 53bb553c8ad0c9aa6ceab60804c177ca7bd7c9a2748afc432824d5f1558dd079
5
5
  SHA512:
6
- metadata.gz: 34250f5db8642efbab2654993df69316be3cdb581bafacc07ac6993e072ea5addf3c04bae86d41ad5412c182b3f22e9aa158b9e9cb27d86571a7cf01ad38a674
7
- data.tar.gz: ac5d4d68b447714f78412acd554c842cbd52f8bfab46794ffa7fabe1dcc6a169bb4d04a3caf10e88bf16ff41b4312ab30626687ee46b31530514b5fa4ac93242
6
+ metadata.gz: f644ac3b93d75565dd83e299315f2149c9835b29f479b60dc6d7059e94fac9c0590969e0c472af907539916f9217452bc2b406e35df8bbd740622a7adc7b86b8
7
+ data.tar.gz: c68877ffb43417a9c8484d2beed4f328d76abc055bffe3a43a65ddfd10b7a7b940cb2a7230a281dfd70e8a6a95f04febac93e995e4f86f19e15490fea29d6bea
@@ -1 +1 @@
1
- {".":"0.15.0","wasm/kobako-core":"0.9.0","wasm/kobako-mruby":"0.9.0","wasm/kobako-io":"0.9.0","wasm/kobako-json":"0.9.0","wasm/kobako-regexp":"0.9.0","wasm/kobako-baker":"0.9.0","crates/kobako-codec":"0.9.0","crates/kobako-runtime":"0.9.0","crates/kobako-wasmtime":"0.9.0","crates/kobako":"0.9.0"}
1
+ {".":"0.16.0","wasm/kobako-core":"0.10.0","wasm/kobako-mruby":"0.10.0","wasm/kobako-io":"0.10.0","wasm/kobako-json":"0.10.0","wasm/kobako-regexp":"0.10.0","wasm/kobako-baker":"0.10.0","crates/kobako-codec":"0.10.0","crates/kobako-runtime":"0.10.0","crates/kobako-wasmtime":"0.10.0","crates/kobako":"0.10.0"}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.16.0](https://github.com/elct9620/kobako/compare/v0.15.0...v0.16.0) (2026-07-12)
4
+
5
+
6
+ ### Features
7
+
8
+ * **sandbox:** add the Extension install mechanism ([ad8e4da](https://github.com/elct9620/kobako/commit/ad8e4da703e4ceee85959663d77bb1e26c26791a))
9
+ * **sdk:** add the Extension install mechanism to the Rust host SDK ([4043f76](https://github.com/elct9620/kobako/commit/4043f764b7038619a30c16542ed38d566e4a72a9))
10
+ * **tasks:** break each module down by language in stats:<slug> ([b496e3c](https://github.com/elct9620/kobako/commit/b496e3cb23150f8f073cc1b972978cfbebfbb1e6))
11
+ * **tasks:** report code sizes per publishable module in stats:all ([f554930](https://github.com/elct9620/kobako/commit/f554930e669a82bed0c7305c5cbbab96c3ae79da))
12
+ * **tasks:** split impl vs inline test per module in stats:all ([cefa38d](https://github.com/elct9620/kobako/commit/cefa38d96ff79509b947269ea5c361ead0610bfa))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **tasks:** count Rust inline tests in the stats code-to-test ratio ([134c970](https://github.com/elct9620/kobako/commit/134c9704a5a9bb6fb01c1aa7968f907d1436e5f2))
18
+
3
19
  ## [0.15.0](https://github.com/elct9620/kobako/compare/v0.14.0...v0.15.0) (2026-07-11)
4
20
 
5
21
 
data/README.md CHANGED
@@ -69,7 +69,7 @@ The host embeds the sandbox and owns the SPEC wire codec. Choose by your host la
69
69
  | Frontend | Package | Add it | Best for |
70
70
  |----------|---------|--------|----------|
71
71
  | Ruby gem | `kobako` (RubyGems) | `gem install kobako` | A Ruby host — Services, Handles, snippets, and pooling out of the box |
72
- | Rust SDK | `kobako` (crates.io) | `kobako = "0.8"` | A Rust host — the same behavior contract behind an idiomatic Rust API |
72
+ | Rust SDK | `kobako` (crates.io) | `kobako = "0.9"` | A Rust host — the same behavior contract behind an idiomatic Rust API |
73
73
  | Low-level crates | `kobako-wasmtime` + `kobako-runtime` + `kobako-codec` | Cargo deps | A custom host, or driving the wire directly in another language |
74
74
 
75
75
  The Rust crates are documented on [crates.io](https://crates.io/crates/kobako); the Ruby gem is this README. Two runnable Rust hosts show the choice: [`plugin-rs`](examples/plugin-rs) builds on the SDK, and [`wire-rs`](examples/wire-rs) assembles a host by hand on the low-level crates.
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/elct9620/kobako/compare/kobako-runtime-v0.9.0...kobako-runtime-v0.10.0) (2026-07-12)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **kobako-runtime:** Synchronize kobako crates versions
9
+
3
10
  ## [0.9.0](https://github.com/elct9620/kobako/compare/kobako-runtime-v0.8.0...kobako-runtime-v0.9.0) (2026-07-11)
4
11
 
5
12
 
@@ -26,7 +26,7 @@ map the neutral types onto their own language surface.
26
26
 
27
27
  ```toml
28
28
  [dependencies]
29
- kobako-runtime = "0.9.0" # x-release-please-version
29
+ kobako-runtime = "0.10.0" # x-release-please-version
30
30
  ```
31
31
 
32
32
  ## License
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/elct9620/kobako/compare/kobako-wasmtime-v0.9.0...kobako-wasmtime-v0.10.0) (2026-07-12)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **kobako-wasmtime:** Synchronize kobako crates versions
9
+
3
10
  ## [0.9.0](https://github.com/elct9620/kobako/compare/kobako-wasmtime-v0.8.0...kobako-wasmtime-v0.9.0) (2026-07-11)
4
11
 
5
12
 
@@ -24,7 +24,7 @@ SDK consumes the same surface.
24
24
 
25
25
  ```toml
26
26
  [dependencies]
27
- kobako-wasmtime = "0.9.0" # x-release-please-version
27
+ kobako-wasmtime = "0.10.0" # x-release-please-version
28
28
  ```
29
29
 
30
30
  ## License
data/data/kobako.wasm CHANGED
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kobako
4
+ module Catalog
5
+ # Kobako::Catalog::Extensions — per-Sandbox registry of installed
6
+ # Extensions. Composes each Extension onto the sibling registries at
7
+ # install time (its +source+ into +Catalog::Snippets+, its +backend+
8
+ # path into +Catalog::Services+), asserts declared dependencies are
9
+ # present when the Sandbox seals, and resolves each callable-backed
10
+ # path to a fresh object at the start of every invocation.
11
+ #
12
+ # Sealing and the reject-after-install guard are governed by the owning
13
+ # Sandbox through +Catalog::Services#sealed?+, the shared seal signal;
14
+ # this registry only records entries and enforces the Extension-shape
15
+ # and dependency rules.
16
+ class Extensions
17
+ def initialize
18
+ @entries = [] # : Array[untyped]
19
+ @asserted = false
20
+ end
21
+
22
+ # Install +extension+: validate its shape, register its +source+ as a
23
+ # preloaded snippet, and — when it carries a +backend+ — reserve the
24
+ # backend path in +services+. A callable provider reserves the path
25
+ # with a placeholder the per-invocation refresh replaces; a fixed
26
+ # provider binds its object directly. Raises +ArgumentError+ on a
27
+ # malformed Extension; a malformed +name+ or +backend.path+ surfaces
28
+ # through the +snippets+ / +services+ registration it routes to.
29
+ def install(extension, snippets:, services:)
30
+ validate!(extension)
31
+ snippets.register(code: extension.source, name: extension.name)
32
+ backend = extension.backend
33
+ services.bind(backend.path, initial_object(backend.provider)) if backend
34
+ @entries << extension
35
+ self
36
+ end
37
+
38
+ # Assert every installed Extension's +depends_on+ names a fellow
39
+ # installed Extension. Runs once, when the Sandbox first seals; an
40
+ # unmet dependency raises +ArgumentError+ naming the gap, before the
41
+ # guest runs. Idempotent across later invocations.
42
+ def seal!
43
+ return self if @asserted
44
+
45
+ @asserted = true
46
+ assert_dependencies!
47
+ self
48
+ end
49
+
50
+ # Resolve each callable-backed path to this invocation's object and
51
+ # refresh it behind its already-sealed path in +services+. Distinct
52
+ # providers yield distinct objects; one provider shared by several
53
+ # Extensions is invoked once and its result shared, so provider
54
+ # identity is resource identity. Fixed providers are left untouched —
55
+ # they stay the object bound at install.
56
+ def refresh_backends!(services)
57
+ resolved = {} # : Hash[untyped, untyped]
58
+ resolved.compare_by_identity
59
+ @entries.each { |extension| refresh_backend(extension, services, resolved) }
60
+ self
61
+ end
62
+
63
+ private
64
+
65
+ # Resolve one Extension's callable-backed path against the shared
66
+ # per-invocation +resolved+ cache (keyed by provider identity) and
67
+ # refresh it in +services+. A fixed provider is skipped — its object
68
+ # stays as bound at install.
69
+ def refresh_backend(extension, services, resolved)
70
+ backend = extension.backend
71
+ return unless backend
72
+
73
+ provider = backend.provider
74
+ return unless callable?(provider)
75
+
76
+ object = resolved.fetch(provider) { resolved[provider] = provider.call }
77
+ services.refresh(backend.path, object)
78
+ end
79
+
80
+ # Enforce the Extension-shape checks +#preload+ / +#bind+ do not: a
81
+ # mandatory String +source+ (the install/bind boundary) and a
82
+ # +backend+ that, when present, exposes +path+ and +provider+.
83
+ def validate!(extension)
84
+ source = extension.source
85
+ raise ArgumentError, "Extension #source must be a String, got #{source.class}" unless source.is_a?(String)
86
+
87
+ backend = extension.backend
88
+ return if backend.nil?
89
+ return if backend.respond_to?(:path) && backend.respond_to?(:provider)
90
+
91
+ raise ArgumentError, "Extension #backend must expose #path and #provider"
92
+ end
93
+
94
+ def assert_dependencies!
95
+ names = @entries.map(&:name)
96
+ @entries.each do |extension|
97
+ (extension.depends_on || []).each do |dependency|
98
+ next if names.include?(dependency)
99
+
100
+ raise ArgumentError,
101
+ "Extension #{extension.name.inspect} depends on #{dependency.inspect}, which is not installed"
102
+ end
103
+ end
104
+ end
105
+
106
+ def callable?(provider) = provider.respond_to?(:call)
107
+
108
+ # A callable provider reserves its path with a placeholder that the
109
+ # per-invocation refresh replaces before any dispatch; a fixed
110
+ # provider is the bound object itself.
111
+ def initial_object(provider) = callable?(provider) ? nil : provider
112
+ end
113
+ end
114
+ end
@@ -65,6 +65,18 @@ module Kobako
65
65
  @bindings[target_str]
66
66
  end
67
67
 
68
+ # Replace the object bound at an already-registered +path+ without the
69
+ # collision or seal checks +#bind+ applies. +Catalog::Extensions+ calls
70
+ # this during +begin_invocation!+ to swap a callable backend provider's
71
+ # per-invocation result behind a path whose Frame 1 membership was
72
+ # fixed at the seal. A path that was never registered is left untouched,
73
+ # so the sealed key set can never grow here.
74
+ def refresh(path, object)
75
+ key = path.to_s
76
+ @bindings[key] = object if @bindings.key?(key)
77
+ self
78
+ end
79
+
68
80
  # Encode the preamble as msgpack bytes for stdin Frame 1 delivery —
69
81
  # a flat array of the bound constant paths, in bind order:
70
82
  # +["MyService::KV", "File"]+. Routes through Kobako::Codec::Encoder
@@ -3,13 +3,15 @@
3
3
  require_relative "catalog/handles"
4
4
  require_relative "catalog/services"
5
5
  require_relative "catalog/snippets"
6
+ require_relative "catalog/extensions"
6
7
 
7
8
  module Kobako
8
9
  # Kobako::Catalog — Sandbox-level configuration and per-invocation
9
- # allocation tables. Houses the three host-side registries the Sandbox
10
- # owns: +Catalog::Services+ (path→Service binding registry),
11
- # +Catalog::Snippets+ (preloaded source / bytecode entries), and
12
- # +Catalog::Handles+ (per-invocation Handle ID allocator).
10
+ # allocation tables. Houses the host-side registries the Sandbox owns:
11
+ # +Catalog::Services+ (path→Service binding registry),
12
+ # +Catalog::Snippets+ (preloaded source / bytecode entries),
13
+ # +Catalog::Extensions+ (installed Extensions, composed onto Services /
14
+ # Snippets), and +Catalog::Handles+ (per-invocation Handle ID allocator).
13
15
  #
14
16
  # See {SPEC.md Refinement → Internal Concepts}[link:../../SPEC.md] for
15
17
  # how Catalog fits alongside Transport and Runtime.
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kobako
4
+ # Kobako::Extension — a guest idiom paired with an optional host backend,
5
+ # installed on a Sandbox via +Sandbox#install+. It composes the existing
6
+ # +#preload+ (the guest +source+) and +#bind+ (the +backend+) verbs into
7
+ # one setup unit, so guest code sees a native-style constant whose pure
8
+ # methods run in-guest and whose privileged methods dispatch to the
9
+ # backend.
10
+ #
11
+ # The four readers form the contract +#install+ duck-types on:
12
+ #
13
+ # * +name+ — a Symbol matching +/\A[A-Z]\w*\z/+, the preloaded snippet's
14
+ # canonical backtrace name and the +depends_on+ match key. Independent
15
+ # of any bound path.
16
+ # * +source+ — the mruby idiom as a String; always present, since an
17
+ # Extension always carries a guest idiom. A host object with no idiom
18
+ # is bound with +#bind+ directly.
19
+ # * +backend+ — an +Extension::Backend+ or +nil+ for a pure-guest
20
+ # Extension.
21
+ # * +depends_on+ — Symbol names of Extensions that must also be
22
+ # installed, checked for presence at the first invocation.
23
+ #
24
+ # +Kobako::Extension+ is the bundled value type; any object exposing the
25
+ # four readers is equally valid, so a Host App or gem may supply its own.
26
+ class Extension < Data.define(:name, :source, :backend, :depends_on)
27
+ # Kobako::Extension::Backend — the host attachment of an Extension,
28
+ # pairing +path+ (the constant path the backend binds at, single-segment
29
+ # +"File"+ or nested +"MyApp::Store"+, spelling the guest constant the
30
+ # idiom routes to) with +provider+ (the source of the bound object).
31
+ #
32
+ # A +provider+ that is not itself callable is the bound object, resolved
33
+ # once for the Sandbox's life; a callable provider is invoked once per
34
+ # invocation to yield that invocation's object, so a fresh object backs
35
+ # the path every invocation. Callability is the sole discriminator — a
36
+ # fixed backend that is itself callable is supplied through a
37
+ # non-callable wrapper.
38
+ class Backend < Data.define(:path, :provider)
39
+ end
40
+
41
+ # +backend+ and +depends_on+ default to absent so the common
42
+ # pure-idiom and single-backend shapes stay terse.
43
+ def initialize(name:, source:, backend: nil, depends_on: [])
44
+ super
45
+ end
46
+ end
47
+ end
@@ -48,29 +48,21 @@ module Kobako
48
48
  # so use +#stdout_truncated?+ to observe overflow. Populated on every
49
49
  # outcome — including a rescued +TrapError+, after which it holds the
50
50
  # bytes written before the trap fired — mirroring +#usage+.
51
- def stdout
52
- @stdout_capture.bytes
53
- end
51
+ def stdout = @stdout_capture.bytes
54
52
 
55
53
  # Returns the bytes the guest wrote to stderr during the most recent
56
54
  # invocation as a UTF-8 String, clipped at +stderr_limit+. Empty before
57
55
  # any invocation. Mirror of +#stdout+.
58
- def stderr
59
- @stderr_capture.bytes
60
- end
56
+ def stderr = @stderr_capture.bytes
61
57
 
62
58
  # Returns +true+ iff stdout capture during the most recent invocation
63
59
  # exceeded +stdout_limit+. Resets to +false+ at the start of the next
64
60
  # invocation.
65
- def stdout_truncated?
66
- @stdout_capture.truncated?
67
- end
61
+ def stdout_truncated? = @stdout_capture.truncated?
68
62
 
69
63
  # Returns +true+ iff stderr capture during the most recent invocation
70
64
  # exceeded +stderr_limit+. Mirror of +#stdout_truncated?+.
71
- def stderr_truncated?
72
- @stderr_capture.truncated?
73
- end
65
+ def stderr_truncated? = @stderr_capture.truncated?
74
66
 
75
67
  # Returns the +Kobako::Usage+ value object for the most recent
76
68
  # invocation. Carries +wall_time+ (Float seconds the guest export call spent
@@ -102,6 +94,7 @@ module Kobako
102
94
  @handler = Catalog::Handles.new
103
95
  @services = Kobako::Catalog::Services.new(handler: @handler)
104
96
  @snippets = Catalog::Snippets.new
97
+ @extensions = Catalog::Extensions.new
105
98
  @runtime = build_runtime!
106
99
  install_dispatch_proc!
107
100
  reset_invocation_state!
@@ -121,6 +114,22 @@ module Kobako
121
114
  self
122
115
  end
123
116
 
117
+ # Install one or more Extensions — each a guest idiom (+source+) paired
118
+ # with an optional host +backend+, composed onto the Sandbox through
119
+ # +#preload+ and +#bind+. An Extension is any object exposing
120
+ # +name+ / +source+ / +backend+ / +depends_on+; +Kobako::Extension+ is
121
+ # the bundled value type. Returns +self+.
122
+ #
123
+ # Raises +ArgumentError+ for a malformed Extension, a call after the
124
+ # first invocation seals registration, or — at that first invocation —
125
+ # an unmet +depends_on+.
126
+ def install(*extensions)
127
+ raise ArgumentError, "cannot install after first Sandbox invocation" if @services.sealed?
128
+
129
+ extensions.each { |extension| @extensions.install(extension, snippets: @snippets, services: @services) }
130
+ self
131
+ end
132
+
124
133
  # Register a snippet on this Sandbox in one of two forms:
125
134
  #
126
135
  # * +preload(code: source, name: Name)+ — +source+ is mruby source
@@ -241,14 +250,18 @@ module Kobako
241
250
  end
242
251
  end
243
252
 
244
- # Per-invocation prologue. Seals the Service / snippet registries on
245
- # first call (idempotent) and zeros the per-invocation capability
253
+ # Per-invocation prologue. Seals the Service / snippet / Extension
254
+ # registries on first call (idempotent asserting Extension
255
+ # dependencies then), refreshes each callable Extension backend to this
256
+ # invocation's fresh object, and zeros the per-invocation capability
246
257
  # state — capture buffers, truncation predicates, and the
247
258
  # +Catalog::Handles+ counter — before the guest runs. The
248
259
  # +Catalog::Handles+ itself is held as +@handler+ and never exposed
249
260
  # beyond this class — it is not part of the Host App's surface.
250
261
  def begin_invocation!
251
262
  @services.seal!
263
+ @extensions.seal!
264
+ @extensions.refresh_backends!(@services)
252
265
  @handler.reset!
253
266
  reset_invocation_state!
254
267
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kobako
4
- VERSION = "0.15.0"
4
+ VERSION = "0.16.0"
5
5
  end
data/lib/kobako.rb CHANGED
@@ -10,6 +10,7 @@ rescue LoadError
10
10
  end
11
11
 
12
12
  require_relative "kobako/errors"
13
+ require_relative "kobako/extension"
13
14
  require_relative "kobako/transport"
14
15
  require_relative "kobako/catalog"
15
16
  require_relative "kobako/runtime"
@@ -0,0 +1,25 @@
1
+ module Kobako
2
+ module Catalog
3
+ class Extensions
4
+ def initialize: () -> void
5
+
6
+ def install: (untyped extension, snippets: Kobako::Catalog::Snippets, services: Kobako::Catalog::Services) -> self
7
+
8
+ def seal!: () -> self
9
+
10
+ def refresh_backends!: (Kobako::Catalog::Services services) -> self
11
+
12
+ private
13
+
14
+ def refresh_backend: (untyped extension, Kobako::Catalog::Services services, Hash[untyped, untyped] resolved) -> void
15
+
16
+ def validate!: (untyped extension) -> void
17
+
18
+ def assert_dependencies!: () -> void
19
+
20
+ def callable?: (untyped provider) -> bool
21
+
22
+ def initial_object: (untyped provider) -> untyped
23
+ end
24
+ end
25
+ end
@@ -9,6 +9,8 @@ module Kobako
9
9
 
10
10
  def lookup: (Symbol | String target) -> untyped
11
11
 
12
+ def refresh: (Symbol | String path, untyped object) -> self
13
+
12
14
  def encode: () -> String
13
15
 
14
16
  def seal!: () -> self
@@ -0,0 +1,20 @@
1
+ module Kobako
2
+ class Extension < Data
3
+ attr_reader name: Symbol
4
+ attr_reader source: String
5
+ attr_reader backend: Kobako::Extension::Backend?
6
+ attr_reader depends_on: Array[Symbol]
7
+
8
+ def self.new: (name: Symbol, source: String, ?backend: Kobako::Extension::Backend?, ?depends_on: Array[Symbol]) -> Kobako::Extension
9
+
10
+ def initialize: (name: Symbol, source: String, ?backend: Kobako::Extension::Backend?, ?depends_on: Array[Symbol]) -> void
11
+
12
+ class Backend < Data
13
+ attr_reader path: String
14
+ attr_reader provider: untyped
15
+
16
+ def self.new: (path: String, provider: untyped) -> Kobako::Extension::Backend
17
+ | (String path, untyped provider) -> Kobako::Extension::Backend
18
+ end
19
+ end
20
+ end
@@ -31,6 +31,8 @@ module Kobako
31
31
 
32
32
  def bind: (Symbol | String path, untyped object) -> Kobako::Sandbox
33
33
 
34
+ def install: (*untyped extensions) -> Kobako::Sandbox
35
+
34
36
  def preload: (code: String, name: Symbol | String) -> Kobako::Sandbox
35
37
  | (binary: String) -> Kobako::Sandbox
36
38
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kobako
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Aotokitsuruya
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-11 00:00:00.000000000 Z
11
+ date: 2026-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -50,6 +50,7 @@ files:
50
50
  - lib/kobako/4.0/kobako.so
51
51
  - lib/kobako/capture.rb
52
52
  - lib/kobako/catalog.rb
53
+ - lib/kobako/catalog/extensions.rb
53
54
  - lib/kobako/catalog/handles.rb
54
55
  - lib/kobako/catalog/services.rb
55
56
  - lib/kobako/catalog/snippets.rb
@@ -62,6 +63,7 @@ files:
62
63
  - lib/kobako/codec/state.rb
63
64
  - lib/kobako/codec/utils.rb
64
65
  - lib/kobako/errors.rb
66
+ - lib/kobako/extension.rb
65
67
  - lib/kobako/fault.rb
66
68
  - lib/kobako/handle.rb
67
69
  - lib/kobako/outcome.rb
@@ -88,6 +90,7 @@ files:
88
90
  - sig/kobako.rbs
89
91
  - sig/kobako/capture.rbs
90
92
  - sig/kobako/catalog.rbs
93
+ - sig/kobako/catalog/extensions.rbs
91
94
  - sig/kobako/catalog/handles.rbs
92
95
  - sig/kobako/catalog/services.rbs
93
96
  - sig/kobako/catalog/snippets.rbs
@@ -100,6 +103,7 @@ files:
100
103
  - sig/kobako/codec/state.rbs
101
104
  - sig/kobako/codec/utils.rbs
102
105
  - sig/kobako/errors.rbs
106
+ - sig/kobako/extension.rbs
103
107
  - sig/kobako/fault.rbs
104
108
  - sig/kobako/handle.rbs
105
109
  - sig/kobako/outcome.rbs