textus 0.8.0 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91be0acd415a4b41d96e896015dfd19e58fc7867d007332456499ec5ceb8a6aa
4
- data.tar.gz: 576d361ebba900b33b2f612b1a0a51d0373cb4a5e1fbd503e43c2bb248ca9306
3
+ metadata.gz: e4b96d4cff83e901df4b2871b57f9c86d071b11126fd42e8fc5563abf45ce810
4
+ data.tar.gz: 6afa20a10f7ddee98b5b4adbf6eb87218725b5eb1c3f7b181b8bcb462d4fff74
5
5
  SHA512:
6
- metadata.gz: c551c60809be1eefc0d964092adc62a8555cb6f0df3585e775fd2fda1549f1e7d811fb2bfeec992dd3ce872dccb16fd9300a66314d5e51e8f24a98b57f29da5b
7
- data.tar.gz: c96ec13692d6366a916b125266afb70aabcca439594db4e8fd1b434f1db1a88e216938cbf64bc69e64bcfef241ca7314664398c656f1d7333a7480a7d02852f9
6
+ metadata.gz: 83825a241b91ac10c2024ebdf04ec0f1bb753b8deeded27894fbbbff84f3f654ad6cc4c0faa2bbfcf940b989bc0393d832ae90af837039814fe51e5f7e4c4515
7
+ data.tar.gz: 57079b174111a5e89637140d53ca83f5c9b0c5f777c270be9833174c3dd11c7f4d8b8039ef30c69c6f85e1dfb9d78c89dab3eb99cd517b32e1cf7af2ce7ded7a
data/CHANGELOG.md CHANGED
@@ -8,6 +8,27 @@ The **gem version** (`0.x.y`) is distinct from the **protocol version**
8
8
  (currently `textus/2`, embedded in every envelope as `protocol`). The protocol
9
9
  is additive within a major; a new major would change the wire string.
10
10
 
11
+ ## 0.8.1 — Terminology cleanup (2026-05-21)
12
+
13
+ ### Breaking — intro output
14
+ - `textus intro` JSON: the `"extensions"` key is renamed to `"hooks"`. Consumers
15
+ reading `env["extensions"]` must switch to `env["hooks"]`. Wire protocol
16
+ remains `textus/2`; envelope shape on read/write is unchanged.
17
+
18
+ ### Internal Ruby renames
19
+ - `Textus::Store#load_extensions` → `Textus::Store#load_hooks`.
20
+ - `Textus::Intro.extensions_for` → `Textus::Intro.hooks_for`.
21
+ - Error string `"failed loading extension <file>"` → `"failed loading hook <file>"`.
22
+
23
+ ### Fixed
24
+ - `textus doctor` `:check`-hook failure hint pointed to `.textus/extensions/`,
25
+ which has never existed in 0.6+. Now correctly points to `.textus/hooks/`.
26
+
27
+ ### Docs
28
+ - SPEC.md §5.10: "single extension verb" → "single hook verb".
29
+ - Scaffolded `.textus/hooks/README.md` no longer mixes "hook" and "extension"
30
+ terminology.
31
+
11
32
  ## 0.8.0 — Folder restructure & Zeitwerk autoload (2026-05-21)
12
33
 
13
34
  ### Breaking — internal Ruby renames
data/README.md CHANGED
@@ -45,7 +45,7 @@ You get `.textus/` with all five zone directories, baseline schemas, an empty au
45
45
  audit.log # append-only NDJSON, every write
46
46
  schemas/ # YAML field shapes per entry family
47
47
  templates/ # mustache templates for derived entries
48
- extensions/ # one .rb per action / reducer / hook / doctor_check
48
+ hooks/ # one .rb per hook
49
49
  sentinels/ # publish bookkeeping
50
50
  zones/
51
51
  canon/ # human-only — identity, voice, decisions
@@ -77,8 +77,8 @@ For the full shape — Claude plugin with agents, skills, commands, pending walk
77
77
  - **Per-leaf publishing.** Nested entries declare `publish_each: "skills/{basename}/SKILL.md"`. Every leaf byte-copies to its consumer location on `textus build`. No more hand-mirrored `agents/` / `skills/` / `commands/` directories.
78
78
  - **Stable identity (`uid:`).** 16-char hex, auto-minted on first `put`, preserved across writes and moves. `textus key mv old.key new.key` renames in place — uid survives, audit row records `from_key`, `to_key`, `uid`. Reorganising a tree no longer breaks references.
79
79
  - **Strict key grammar.** `/^[a-z0-9][a-z0-9-]*$/`, max 8 segments × 64 chars. `textus key migrate --dry-run|--write` rewrites existing stores with illegal segments deterministically.
80
- - **`textus intro`.** One-shot store orientation: zones with writers + purposes, entry families with schemas and publish targets, loaded extensions, write flows per role, the full CLI verb table. The boot signal for any agent — one tool call and it knows your store.
81
- - **`textus doctor`.** Health check across 9 categories: missing schemas/templates, broken extensions, illegal nested keys, sentinel drift, audit log readability, unowned schema fields, schema violations, and missing manifest files. Returns `ok: true` only when nothing is wrong; warnings and info don't flip the bit.
80
+ - **`textus intro`.** One-shot store orientation: zones with writers + purposes, entry families with schemas and publish targets, loaded hooks, write flows per role, the full CLI verb table. The boot signal for any agent — one tool call and it knows your store.
81
+ - **`textus doctor`.** Health check across 9 categories: missing schemas/templates, broken hooks, illegal nested keys, sentinel drift, audit log readability, unowned schema fields, schema violations, and missing manifest files. Returns `ok: true` only when nothing is wrong; warnings and info don't flip the bit.
82
82
  - **Actionable hints on every error.** `UnknownKey` carries ranked "did you mean" suggestions. `WriteForbidden` names the role that *would* be allowed. `BadFrontmatter` tells you exactly what to rename. Printed to stderr alongside the JSON envelope on stdout.
83
83
 
84
84
  Symlink-mode publish was removed; publish is `FileUtils.cp` + sentinel. Sentinels for published files live under `.textus/sentinels/<target_rel>.textus-managed.json` so consumer directories stay clean. Legacy sibling sentinels auto-migrate on next publish.
@@ -91,7 +91,7 @@ All verbs accept `--format=json` and return the envelope defined in SPEC §8. Wr
91
91
 
92
92
  | Verb | Purpose |
93
93
  |---|---|
94
- | `intro` | Store orientation: zones, entries, extensions, write flows, CLI map |
94
+ | `intro` | Store orientation: zones, entries, hooks, write flows, CLI map |
95
95
  | `list [--prefix=K] [--zone=Z]` | Enumerate keys |
96
96
  | `where K` | Resolve a key to its filesystem path |
97
97
  | `get K` | Full envelope (frontmatter, body, uid, etag, format) |
data/SPEC.md CHANGED
@@ -365,7 +365,7 @@ Reducers are RPC hooks on the `:reduce` event. See §5.10.
365
365
 
366
366
  ### 5.10 Hooks
367
367
 
368
- textus has a single extension verb: `Textus.hook(event, name, **opts) { ... }`. The EVENTS table below defines every extension point. Files in `.textus/hooks/*.rb` are `load`ed at `Store#initialize` in lexical order.
368
+ textus has a single hook verb: `Textus.hook(event, name, **opts) { ... }`. The EVENTS table below defines every extension point. Files in `.textus/hooks/*.rb` are `load`ed at `Store#initialize` in lexical order.
369
369
 
370
370
  | Event | Mode | Args | Return | Failure |
371
371
  |----------|---------|-----------------------------------|---------------|---------|
data/lib/textus/doctor.rb CHANGED
@@ -67,7 +67,7 @@ module Textus
67
67
  rescue StandardError => e
68
68
  out << fail_issue(name, code: "doctor_check.failed",
69
69
  message: "#{e.class}: #{e.message}",
70
- fix: "fix the doctor_check block in .textus/extensions/")
70
+ fix: "fix the :check hook in .textus/hooks/")
71
71
  end
72
72
  end
73
73
  out
data/lib/textus/init.rb CHANGED
@@ -31,7 +31,7 @@ module Textus
31
31
  File.write(File.join(target_root, "hooks", "README.md"), <<~MD)
32
32
  # Hooks
33
33
 
34
- Drop one Ruby file per hook. All extensions register through one DSL.
34
+ Drop one Ruby file per hook. All hooks register through one DSL.
35
35
  Every handler receives `store:` as its first kwarg, then event-specific args.
36
36
 
37
37
  ```ruby
data/lib/textus/intro.rb CHANGED
@@ -2,7 +2,7 @@ module Textus
2
2
  # Read-only "what's in this store and how do I use it" envelope.
3
3
  # A single call gives an agent the working model of a textus-managed
4
4
  # project: zones and their write authority, entries and their flags,
5
- # registered extensions, write flows, and the CLI verb catalog.
5
+ # registered hooks, write flows, and the CLI verb catalog.
6
6
  #
7
7
  # Intro is side-effect-free.
8
8
  module Intro
@@ -53,7 +53,7 @@ module Textus
53
53
  "store_root" => store.root,
54
54
  "zones" => zones_for(store),
55
55
  "entries" => entries_for(store),
56
- "extensions" => extensions_for(store),
56
+ "hooks" => hooks_for(store),
57
57
  "write_flows" => WRITE_FLOWS.dup,
58
58
  "cli_verbs" => CLI_VERBS.map(&:dup),
59
59
  "docs" => { "spec" => "SPEC.md", "example" => "examples/claude-plugin/" },
@@ -87,7 +87,7 @@ module Textus
87
87
  end
88
88
  end
89
89
 
90
- def self.extensions_for(store)
90
+ def self.hooks_for(store)
91
91
  reg = store.registry
92
92
  sections = {}
93
93
  Hooks::Registry::EVENTS.each do |event, spec|
data/lib/textus/store.rb CHANGED
@@ -42,12 +42,12 @@ module Textus
42
42
  @bus = Hooks::Dispatcher.new(audit_log: audit_log)
43
43
  @registry = Hooks::Registry.new(dispatcher: @bus)
44
44
  @schemas = {}
45
- load_extensions
45
+ load_hooks
46
46
  @reader = Reader.new(self)
47
47
  @writer = Writer.new(self)
48
48
  end
49
49
 
50
- def load_extensions
50
+ def load_hooks
51
51
  Textus.with_registry(@registry) do
52
52
  Hooks::Builtin.register_all
53
53
  dir = File.join(@root, "hooks")
@@ -57,7 +57,7 @@ module Textus
57
57
  begin
58
58
  load(f)
59
59
  rescue StandardError, ScriptError => e
60
- raise UsageError.new("failed loading extension #{File.basename(f)}: #{e.class}: #{e.message}")
60
+ raise UsageError.new("failed loading hook #{File.basename(f)}: #{e.class}: #{e.message}")
61
61
  end
62
62
  end
63
63
  end
@@ -1,4 +1,4 @@
1
1
  module Textus
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  PROTOCOL = "textus/2"
4
4
  end
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.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick