@onlooker-community/ecosystem 0.30.1 → 0.31.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.
Files changed (164) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.gitattributes +18 -0
  3. package/.release-please-manifest.json +17 -17
  4. package/CHANGELOG.md +14 -0
  5. package/package.json +2 -3
  6. package/plugins/archivist/.claude-plugin/plugin.json +1 -1
  7. package/plugins/archivist/CHANGELOG.md +14 -0
  8. package/plugins/archivist/README.md +4 -10
  9. package/plugins/archivist/config.json +0 -1
  10. package/plugins/archivist/scripts/hooks/archivist-extract.sh +10 -6
  11. package/plugins/archivist/scripts/hooks/archivist-inject.sh +12 -7
  12. package/plugins/archivist/scripts/lib/archivist-config.sh +0 -8
  13. package/plugins/archivist/scripts/lib/archivist-events.sh +6 -0
  14. package/plugins/assayer/.claude-plugin/plugin.json +1 -1
  15. package/plugins/assayer/CHANGELOG.md +14 -0
  16. package/plugins/assayer/README.md +4 -10
  17. package/plugins/assayer/config.json +0 -1
  18. package/plugins/assayer/scripts/hooks/assayer-stop.sh +11 -3
  19. package/plugins/assayer/scripts/lib/assayer-config.sh +0 -6
  20. package/plugins/assayer/scripts/lib/assayer-events.sh +6 -0
  21. package/plugins/bursar/.claude-plugin/plugin.json +1 -1
  22. package/plugins/bursar/CHANGELOG.md +14 -0
  23. package/plugins/bursar/README.md +3 -11
  24. package/plugins/bursar/config.json +0 -1
  25. package/plugins/bursar/scripts/hooks/bursar-session-end.sh +4 -6
  26. package/plugins/bursar/scripts/hooks/bursar-session-start.sh +3 -5
  27. package/plugins/bursar/scripts/lib/bursar-config.sh +1 -7
  28. package/plugins/bursar/scripts/lib/bursar-events.sh +6 -0
  29. package/plugins/cartographer/.claude-plugin/plugin.json +1 -1
  30. package/plugins/cartographer/CHANGELOG.md +14 -0
  31. package/plugins/cartographer/README.md +3 -10
  32. package/plugins/cartographer/config.json +0 -1
  33. package/plugins/cartographer/scripts/hooks/cartographer-post-write.sh +0 -2
  34. package/plugins/cartographer/scripts/hooks/cartographer-session-start.sh +0 -2
  35. package/plugins/cartographer/scripts/lib/cartographer-config.sh +0 -7
  36. package/plugins/cartographer/scripts/lib/cartographer-events.sh +6 -0
  37. package/plugins/cartographer/skills/cartographer/SKILL.md +0 -5
  38. package/plugins/compass/.claude-plugin/plugin.json +1 -1
  39. package/plugins/compass/CHANGELOG.md +14 -0
  40. package/plugins/compass/README.md +4 -10
  41. package/plugins/compass/config.json +0 -1
  42. package/plugins/compass/scripts/hooks/compass-bash-gate.sh +0 -4
  43. package/plugins/compass/scripts/hooks/compass-pre-tool-use.sh +0 -4
  44. package/plugins/compass/scripts/hooks/compass-record-write.sh +0 -4
  45. package/plugins/compass/scripts/hooks/compass-session-start.sh +1 -6
  46. package/plugins/compass/scripts/lib/compass-config.sh +0 -7
  47. package/plugins/compass/scripts/lib/compass-events.sh +6 -0
  48. package/plugins/counsel/.claude-plugin/plugin.json +1 -1
  49. package/plugins/counsel/CHANGELOG.md +14 -0
  50. package/plugins/counsel/README.md +6 -10
  51. package/plugins/counsel/config.json +0 -1
  52. package/plugins/counsel/scripts/hooks/counsel-session-start.sh +1 -7
  53. package/plugins/counsel/scripts/lib/counsel-config.sh +0 -6
  54. package/plugins/counsel/scripts/lib/counsel-events.sh +6 -0
  55. package/plugins/counsel/skills/counsel/SKILL.md +0 -5
  56. package/plugins/curator/.claude-plugin/plugin.json +1 -1
  57. package/plugins/curator/CHANGELOG.md +14 -0
  58. package/plugins/curator/README.md +1 -11
  59. package/plugins/curator/config.json +0 -1
  60. package/plugins/curator/scripts/hooks/curator-session-start.sh +10 -6
  61. package/plugins/curator/scripts/lib/curator-config.sh +0 -7
  62. package/plugins/curator/scripts/lib/curator-emit.sh +10 -0
  63. package/plugins/echo/.claude-plugin/plugin.json +1 -1
  64. package/plugins/echo/CHANGELOG.md +14 -0
  65. package/plugins/echo/README.md +3 -9
  66. package/plugins/echo/config.json +0 -1
  67. package/plugins/echo/scripts/hooks/echo-stop-gate.sh +11 -3
  68. package/plugins/echo/scripts/lib/echo-config.sh +0 -6
  69. package/plugins/echo/scripts/lib/echo-events.sh +6 -0
  70. package/plugins/governor/.claude-plugin/plugin.json +1 -1
  71. package/plugins/governor/CHANGELOG.md +14 -0
  72. package/plugins/governor/README.md +4 -10
  73. package/plugins/governor/config.json +0 -1
  74. package/plugins/governor/scripts/hooks/governor-post-tool-use.sh +10 -5
  75. package/plugins/governor/scripts/hooks/governor-pre-tool-use.sh +10 -5
  76. package/plugins/governor/scripts/hooks/governor-session-start.sh +14 -9
  77. package/plugins/governor/scripts/hooks/governor-stop.sh +10 -5
  78. package/plugins/governor/scripts/lib/governor-config.sh +0 -7
  79. package/plugins/governor/scripts/lib/governor-events.sh +6 -0
  80. package/plugins/historian/.claude-plugin/plugin.json +1 -1
  81. package/plugins/historian/CHANGELOG.md +14 -0
  82. package/plugins/historian/README.md +3 -7
  83. package/plugins/historian/config.json +0 -1
  84. package/plugins/historian/scripts/hooks/historian-prompt-submit.sh +11 -6
  85. package/plugins/historian/scripts/hooks/historian-session-end.sh +10 -2
  86. package/plugins/historian/scripts/lib/historian-config.sh +0 -6
  87. package/plugins/historian/scripts/lib/historian-emit.sh +10 -0
  88. package/plugins/inspector/.claude-plugin/plugin.json +1 -1
  89. package/plugins/inspector/CHANGELOG.md +14 -0
  90. package/plugins/inspector/README.md +9 -5
  91. package/plugins/inspector/config.json +0 -1
  92. package/plugins/inspector/scripts/hooks/inspector-post-write.sh +0 -7
  93. package/plugins/inspector/scripts/lib/inspector-config.sh +0 -7
  94. package/plugins/inspector/scripts/lib/inspector-events.sh +6 -0
  95. package/plugins/librarian/.claude-plugin/plugin.json +1 -1
  96. package/plugins/librarian/CHANGELOG.md +14 -0
  97. package/plugins/librarian/README.md +5 -9
  98. package/plugins/librarian/config.json +0 -1
  99. package/plugins/librarian/scripts/hooks/librarian-session-end.sh +10 -2
  100. package/plugins/librarian/scripts/hooks/librarian-session-start.sh +10 -6
  101. package/plugins/librarian/scripts/lib/librarian-config.sh +0 -8
  102. package/plugins/librarian/scripts/lib/librarian-emit.sh +10 -0
  103. package/plugins/lineage/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lineage/CHANGELOG.md +14 -1
  105. package/plugins/lineage/README.md +3 -12
  106. package/plugins/lineage/config.json +0 -1
  107. package/plugins/lineage/scripts/hooks/lineage-post-tool-use.sh +0 -1
  108. package/plugins/lineage/scripts/lib/lineage-config.sh +0 -7
  109. package/plugins/lineage/scripts/lib/lineage-events.sh +6 -0
  110. package/plugins/lineage/skills/lineage/SKILL.md +1 -4
  111. package/plugins/scribe/.claude-plugin/plugin.json +1 -1
  112. package/plugins/scribe/CHANGELOG.md +14 -0
  113. package/plugins/scribe/README.md +4 -12
  114. package/plugins/scribe/config.json +0 -1
  115. package/plugins/scribe/scripts/hooks/scribe-capture.sh +0 -4
  116. package/plugins/scribe/scripts/hooks/scribe-session-start.sh +2 -7
  117. package/plugins/scribe/scripts/hooks/scribe-stop.sh +0 -5
  118. package/plugins/scribe/scripts/lib/scribe-config.sh +1 -8
  119. package/plugins/scribe/scripts/lib/scribe-events.sh +6 -0
  120. package/plugins/scribe/scripts/lib/scribe-extract.sh +16 -12
  121. package/plugins/tribunal/.claude-plugin/plugin.json +1 -1
  122. package/plugins/tribunal/CHANGELOG.md +14 -0
  123. package/plugins/tribunal/README.md +7 -1
  124. package/plugins/tribunal/config.json +0 -1
  125. package/plugins/tribunal/scripts/hooks/tribunal-stop-gate.sh +13 -14
  126. package/plugins/tribunal/scripts/lib/tribunal-config.sh +0 -8
  127. package/plugins/tribunal/scripts/lib/tribunal-events.sh +6 -0
  128. package/plugins/warden/.claude-plugin/plugin.json +1 -1
  129. package/plugins/warden/CHANGELOG.md +14 -0
  130. package/plugins/warden/README.md +3 -12
  131. package/plugins/warden/config.json +0 -1
  132. package/plugins/warden/scripts/hooks/warden-post-tool-use.sh +0 -4
  133. package/plugins/warden/scripts/hooks/warden-pre-tool-use.sh +0 -4
  134. package/plugins/warden/scripts/hooks/warden-session-start.sh +1 -6
  135. package/plugins/warden/scripts/lib/warden-config.sh +1 -8
  136. package/plugins/warden/scripts/lib/warden-events.sh +6 -0
  137. package/renovate.json +34 -0
  138. package/test/bats/archivist-config-files.bats +2 -2
  139. package/test/bats/archivist-config.bats +0 -25
  140. package/test/bats/archivist-inject.bats +1 -13
  141. package/test/bats/assayer-config.bats +0 -13
  142. package/test/bats/assayer-stop-hook.bats +3 -17
  143. package/test/bats/bursar-config.bats +0 -25
  144. package/test/bats/bursar-session-end.bats +0 -20
  145. package/test/bats/bursar-session-start.bats +1 -18
  146. package/test/bats/cartographer-config.bats +0 -25
  147. package/test/bats/compass-config.bats +1 -26
  148. package/test/bats/compass-gate.bats +1 -3
  149. package/test/bats/curator-session-start.bats +2 -12
  150. package/test/bats/echo-config.bats +0 -24
  151. package/test/bats/echo-stop-hook.bats +3 -15
  152. package/test/bats/governor-config.bats +0 -36
  153. package/test/bats/historian-prompt-submit.bats +1 -8
  154. package/test/bats/historian-session-end.bats +4 -14
  155. package/test/bats/inspector-config.bats +0 -13
  156. package/test/bats/inspector-post-write-hook.bats +10 -17
  157. package/test/bats/librarian-session-end.bats +0 -11
  158. package/test/bats/librarian-session-start.bats +1 -11
  159. package/test/bats/lineage-config.bats +0 -25
  160. package/test/bats/lineage-post-tool-use.bats +1 -7
  161. package/test/bats/scribe-extract.bats +6 -6
  162. package/test/bats/tribunal-config.bats +0 -25
  163. package/test/bats/warden-config.bats +0 -25
  164. package/test/bats/warden-scanner.bats +1 -1
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.1](https://github.com/onlooker-community/ecosystem/compare/librarian-v0.4.0...librarian-v0.4.1) (2026-08-01)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **plugins:** glob-discover ecosystem root so sub-plugins work from cache :relieved: ([#110](https://github.com/onlooker-community/ecosystem/issues/110)) ([3639240](https://github.com/onlooker-community/ecosystem/commit/3639240383e1b820e5d8ea42639e0b863ef0d90e))
9
+
10
+ ## [0.4.0](https://github.com/onlooker-community/ecosystem/compare/librarian-v0.3.0...librarian-v0.4.0) (2026-07-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **plugins:** installation enables plugins — remove per-plugin 'enabled' config key ([#108](https://github.com/onlooker-community/ecosystem/issues/108)) ([45e4e6b](https://github.com/onlooker-community/ecosystem/commit/45e4e6bd29a0a7545dbd5007bf3f09600e1be391))
16
+
3
17
  ## [0.3.0](https://github.com/onlooker-community/ecosystem/compare/librarian-v0.2.0...librarian-v0.3.0) (2026-06-24)
4
18
 
5
19
 
@@ -15,17 +15,13 @@ Librarian is a sibling plugin to [`ecosystem`](../../) and assumes the Onlooker
15
15
 
16
16
  ## Activation
17
17
 
18
- Librarian is **off by default**. Enable per-project in `.claude/settings.json`:
19
-
20
- ```json
21
- {
22
- "librarian": {
23
- "enabled": true
24
- }
25
- }
18
+ Install Librarian from the marketplace:
19
+
20
+ ```
21
+ /plugin install librarian@onlooker-community
26
22
  ```
27
23
 
28
- Or globally in `~/.claude/settings.json`. See [`config.json`](config.json) for the full set of tunable defaults.
24
+ Installing the plugin enables it. See [`config.json`](config.json) for the full set of tunable defaults.
29
25
 
30
26
  ## Storage layout
31
27
 
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "librarian",
3
3
  "storage_path": "~/.onlooker",
4
4
  "librarian": {
5
- "enabled": false,
6
5
  "auto_promote": false,
7
6
  "auto_promote_threshold": 0.85,
8
7
  "memory_store_path": "${HOME}/.claude/projects/${CLAUDE_PROJECT_ENCODED}/memory",
@@ -7,7 +7,6 @@
7
7
  #
8
8
  # Hook contract:
9
9
  # - Always exits 0. Never blocks session shutdown.
10
- # - No-ops when librarian.enabled is not true.
11
10
  # - No-ops when no project key (no git context) or no archivist artifacts.
12
11
  # - Classifier failures degrade gracefully: the affected candidate is
13
12
  # dropped, the rest of the scan proceeds.
@@ -26,6 +25,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
26
25
  _ECOSYSTEM_ROOT="$_candidate"
27
26
  fi
28
27
  fi
28
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
29
+ # works regardless of which ecosystem version is installed.
30
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
31
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
32
+ if [[ -f "$_candidate" ]]; then
33
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
34
+ break
35
+ fi
36
+ done
37
+ fi
29
38
 
30
39
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
31
40
  # shellcheck disable=SC1091
@@ -56,7 +65,6 @@ SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // ""' 2>/dev/null) || SE
56
65
  [[ -z "$SESSION_ID" ]] && SESSION_ID="unknown"
57
66
 
58
67
  librarian_config_load "$(librarian_project_repo_root "$CWD")"
59
- librarian_config_enabled || exit 0
60
68
 
61
69
  PROJECT_KEY=$(librarian_project_key "$CWD")
62
70
  [[ -z "$PROJECT_KEY" ]] && exit 0
@@ -11,7 +11,6 @@
11
11
  # Hook contract:
12
12
  # - Always exits 0. Never blocks session start.
13
13
  # - Emits valid hookSpecificOutput JSON, even when nothing to say.
14
- # - No-ops when librarian.enabled is not true.
15
14
  # - No-ops when there is no project key (no git context).
16
15
 
17
16
  set -uo pipefail
@@ -26,6 +25,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
26
25
  _ECOSYSTEM_ROOT="$_candidate"
27
26
  fi
28
27
  fi
28
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
29
+ # works regardless of which ecosystem version is installed.
30
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
31
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
32
+ if [[ -f "$_candidate" ]]; then
33
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
34
+ break
35
+ fi
36
+ done
37
+ fi
29
38
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
30
39
  # shellcheck disable=SC1091
31
40
  CLAUDE_PLUGIN_ROOT="$_ECOSYSTEM_ROOT" source "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh"
@@ -59,11 +68,6 @@ CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // ""' 2>/dev/null) || CWD=""
59
68
  REPO_ROOT=$(librarian_project_repo_root "$CWD")
60
69
  librarian_config_load "$REPO_ROOT"
61
70
 
62
- if ! librarian_config_enabled; then
63
- _emit ""
64
- exit 0
65
- fi
66
-
67
71
  PROJECT_KEY=$(librarian_project_key "$CWD")
68
72
  if [[ -z "$PROJECT_KEY" ]]; then
69
73
  _emit ""
@@ -9,7 +9,6 @@
9
9
  # Exposes:
10
10
  # librarian_config_load <repo_root> # populates _LIBRARIAN_CONFIG (JSON)
11
11
  # librarian_config_get <jq-path> # echoes string value (empty if unset)
12
- # librarian_config_enabled # 0 if librarian.enabled is true
13
12
  # librarian_config_auto_promote # 0 if librarian.auto_promote is true
14
13
  #
15
14
  # Settings overlay only touches the `librarian.*` subtree of settings.json so
@@ -59,13 +58,6 @@ librarian_config_get() {
59
58
  printf '%s' "$_LIBRARIAN_CONFIG" | jq -r "${path} // empty" 2>/dev/null
60
59
  }
61
60
 
62
- # Returns 0 if librarian.enabled is true, 1 otherwise.
63
- librarian_config_enabled() {
64
- local v
65
- v=$(librarian_config_get '.librarian.enabled')
66
- [[ "$v" == "true" ]]
67
- }
68
-
69
61
  # Returns 0 if librarian.auto_promote is true, 1 otherwise.
70
62
  librarian_config_auto_promote() {
71
63
  local v
@@ -21,6 +21,16 @@ _librarian_resolve_event_js() {
21
21
  ecosystem_root="$candidate"
22
22
  fi
23
23
  fi
24
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
25
+ # works regardless of which ecosystem version is installed.
26
+ if [[ -z "$ecosystem_root" ]]; then
27
+ for candidate in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
28
+ if [[ -f "$candidate" ]]; then
29
+ ecosystem_root="$(cd "$(dirname "$(dirname "$candidate")")" && pwd)"
30
+ break
31
+ fi
32
+ done
33
+ fi
24
34
 
25
35
  if [[ -n "$ecosystem_root" ]]; then
26
36
  printf '%s/scripts/lib/onlooker-event.mjs' "$ecosystem_root"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lineage",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Per-change provenance for the Onlooker ecosystem. Records session/turn metadata plus a secret-redacted, size-capped snippet for every Edit/Write/MultiEdit at PostToolUse, then answers \"why does this line exist?\" via /lineage by joining change records to historian-preserved transcripts. Emits lineage.* events for audit. Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,9 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.1](https://github.com/onlooker-community/ecosystem/compare/lineage-v0.2.0...lineage-v0.2.1) (2026-08-01)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **plugins:** glob-discover ecosystem root so sub-plugins work from cache :relieved: ([#110](https://github.com/onlooker-community/ecosystem/issues/110)) ([3639240](https://github.com/onlooker-community/ecosystem/commit/3639240383e1b820e5d8ea42639e0b863ef0d90e))
9
+
10
+ ## [0.2.0](https://github.com/onlooker-community/ecosystem/compare/lineage-v0.1.0...lineage-v0.2.0) (2026-07-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **plugins:** installation enables plugins — remove per-plugin 'enabled' config key ([#108](https://github.com/onlooker-community/ecosystem/issues/108)) ([45e4e6b](https://github.com/onlooker-community/ecosystem/commit/45e4e6bd29a0a7545dbd5007bf3f09600e1be391))
16
+
3
17
  ## [0.1.0](https://github.com/onlooker-community/ecosystem/compare/lineage-v0.0.1...lineage-v0.1.0) (2026-06-12)
4
18
 
5
19
 
6
20
  ### Features
7
21
 
8
22
  * **lineage:** introduce per-change provenance plugin ([#83](https://github.com/onlooker-community/ecosystem/issues/83)) ([86b00d3](https://github.com/onlooker-community/ecosystem/commit/86b00d3d7393e2b63c5b04d60692fc89f202bf6c))
9
-
@@ -49,18 +49,11 @@ the substrate's turn counter.
49
49
 
50
50
  ## Activation
51
51
 
52
- Lineage is **off by default**. Enable it per-project in `.claude/settings.json`:
52
+ Install the plugin in Claude from the marketplace with:
53
53
 
54
- ```json
55
- {
56
- "lineage": {
57
- "enabled": true
58
- }
59
- }
60
54
  ```
61
-
62
- Or globally in `~/.claude/settings.json`. While disabled, the hook skips silently
63
- and no ledger is written.
55
+ /plugin install lineage@onlooker-community
56
+ ```
64
57
 
65
58
  ## Configuration
66
59
 
@@ -69,7 +62,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
69
62
  ```json
70
63
  {
71
64
  "lineage": {
72
- "enabled": false,
73
65
  "max_snippet_chars": 4000,
74
66
  "redact_secrets": true,
75
67
  "ignore_globs": ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/*.lock"],
@@ -80,7 +72,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
80
72
 
81
73
  | Key | Default | Description |
82
74
  |-----|---------|-------------|
83
- | `enabled` | `false` | Must be `true` for recording, querying, or event emission to run. |
84
75
  | `max_snippet_chars` | `4000` | Cap on the added-content snippet stored per change. |
85
76
  | `redact_secrets` | `true` | Scrub secret-shaped substrings (AWS/GitHub/Anthropic/OpenAI keys, bearer tokens, KEY=value secrets) before storing a snippet. |
86
77
  | `ignore_globs` | `[".git", "node_modules", "dist", "*.lock"]` | Paths matching these are not recorded. Supports `**/<dir>/**` (path segment) and `**/*.<ext>` (suffix) shapes. |
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "lineage",
3
3
  "storage_path": "~/.onlooker",
4
4
  "lineage": {
5
- "enabled": false,
6
5
  "max_snippet_chars": 4000,
7
6
  "redact_secrets": true,
8
7
  "ignore_globs": ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/*.lock"],
@@ -48,7 +48,6 @@ esac
48
48
  [[ -z "$CWD" ]] && CWD="$(pwd)"
49
49
  REPO_ROOT=$(lineage_project_repo_root "$CWD")
50
50
  lineage_config_load "$REPO_ROOT"
51
- lineage_config_enabled || _done
52
51
 
53
52
  PROJECT_KEY=$(lineage_project_key "$CWD")
54
53
  [[ -z "$PROJECT_KEY" ]] && _done
@@ -10,7 +10,6 @@
10
10
  # lineage_config_load <repo_root> # populates _LINEAGE_CONFIG (JSON)
11
11
  # lineage_config_get <jq-path> # echoes string value (empty if unset)
12
12
  # lineage_config_get_json <jq-path> # echoes JSON value (null if unset)
13
- # lineage_config_enabled # 0 if lineage.enabled is true
14
13
  # lineage_config_max_snippet_chars # echoes the snippet cap (default 4000)
15
14
  # lineage_config_redact_enabled # 0 unless redact_secrets is false
16
15
  # lineage_config_prompt_source # echoes the prompt-source strategy
@@ -69,12 +68,6 @@ lineage_config_get_json() {
69
68
  printf '%s' "$_LINEAGE_CONFIG" | jq -c "${path}" 2>/dev/null
70
69
  }
71
70
 
72
- lineage_config_enabled() {
73
- local v
74
- v=$(lineage_config_get '.lineage.enabled')
75
- [[ "$v" == "true" ]]
76
- }
77
-
78
71
  lineage_config_max_snippet_chars() {
79
72
  local v
80
73
  v=$(lineage_config_get '.lineage.max_snippet_chars')
@@ -24,6 +24,12 @@ _lineage_event_js_path() {
24
24
  for c in "${candidates[@]}"; do
25
25
  [[ -f "$c" ]] && { printf '%s' "$c"; return 0; }
26
26
  done
27
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
28
+ # works regardless of which ecosystem version is installed.
29
+ local mjs
30
+ for mjs in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
31
+ [[ -f "$mjs" ]] && { printf '%s' "$mjs"; return 0; }
32
+ done
27
33
  return 1
28
34
  }
29
35
 
@@ -29,10 +29,7 @@ source "$PLUGIN_ROOT/scripts/lib/lineage-query.sh"
29
29
 
30
30
  REPO_ROOT=$(lineage_project_repo_root "$(pwd)")
31
31
  lineage_config_load "$REPO_ROOT"
32
- if ! lineage_config_enabled; then
33
- echo "Lineage is disabled. Set lineage.enabled=true in .claude/settings.json to enable."
34
- exit 0
35
- fi
32
+
36
33
  PROJECT_KEY=$(lineage_project_key "$(pwd)")
37
34
  if [[ -z "$PROJECT_KEY" ]]; then
38
35
  echo "No project key — lineage needs a git repository (remote or root) to scope its ledger."
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scribe",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Intent documentation from agent activity. Captures why changes were made — problem context, decisions, tradeoffs — and distills them into readable artifacts at session end.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.1](https://github.com/onlooker-community/ecosystem/compare/scribe-v0.4.0...scribe-v0.4.1) (2026-08-01)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **plugins:** glob-discover ecosystem root so sub-plugins work from cache :relieved: ([#110](https://github.com/onlooker-community/ecosystem/issues/110)) ([3639240](https://github.com/onlooker-community/ecosystem/commit/3639240383e1b820e5d8ea42639e0b863ef0d90e))
9
+
10
+ ## [0.4.0](https://github.com/onlooker-community/ecosystem/compare/scribe-v0.3.0...scribe-v0.4.0) (2026-07-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **plugins:** installation enables plugins — remove per-plugin 'enabled' config key ([#108](https://github.com/onlooker-community/ecosystem/issues/108)) ([45e4e6b](https://github.com/onlooker-community/ecosystem/commit/45e4e6bd29a0a7545dbd5007bf3f09600e1be391))
16
+
3
17
  ## [0.3.0](https://github.com/onlooker-community/ecosystem/compare/scribe-v0.2.1...scribe-v0.3.0) (2026-06-24)
4
18
 
5
19
 
@@ -14,21 +14,15 @@ Scribe is a sibling plugin to [`ecosystem`](../../) and assumes the Onlooker obs
14
14
  | `UserPromptSubmit` | On the first turn of a session (when `captured_prompt` is still null), stores the prompt text — truncated to `capture.prompt_max_chars` — as the problem-statement seed. Subsequent turns are ignored, since the full transcript is available at Stop time. |
15
15
  | `Stop` | Reads the full session transcript, runs a single Haiku extraction pass via `claude -p` to identify the problem, decisions, tradeoffs, constraints, and out-of-scope items, formats the result as a Markdown intent document, and writes it under `~/.onlooker/scribe/<project-key>/`. Emits `scribe.distill.complete`. |
16
16
 
17
- The Stop hook silently skips when the session has fewer than `capture.min_turns` user turns, when `scribe.enabled` is false, or when no readable `transcript_path` is present in the hook input. Every hook always exits 0 — Scribe never blocks a session.
17
+ The Stop hook silently skips when the session has fewer than `capture.min_turns` user turns or when no readable `transcript_path` is present in the hook input. Every hook always exits 0 — Scribe never blocks a session.
18
18
 
19
19
  ## Activation
20
20
 
21
- Scribe is **on by default**. Disable it per-project in `.claude/settings.json`:
21
+ Install the plugin in Claude from the marketplace with:
22
22
 
23
- ```json
24
- {
25
- "scribe": {
26
- "enabled": false
27
- }
28
- }
29
23
  ```
30
-
31
- Or globally in `~/.claude/settings.json`.
24
+ /plugin install scribe@onlooker-community
25
+ ```
32
26
 
33
27
  ## Configuration
34
28
 
@@ -37,7 +31,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
37
31
  ```json
38
32
  {
39
33
  "scribe": {
40
- "enabled": true,
41
34
  "evaluator": {
42
35
  "model": "claude-haiku-4-5-20251001",
43
36
  "timeout": 60,
@@ -59,7 +52,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
59
52
 
60
53
  | Key | Default | Description |
61
54
  |-----|---------|-------------|
62
- | `enabled` | `true` | Must be `true` for any capture or distillation to run. |
63
55
  | `evaluator.model` | `claude-haiku-4-5-20251001` | Model used for the intent-extraction pass. Haiku is fast and cheap; the extraction prompt is structured and does not require deep reasoning. |
64
56
  | `evaluator.timeout` | `60` | Wall-clock timeout in seconds passed to the `timeout` command around the `claude -p` call. |
65
57
  | `evaluator.max_tokens` | `2048` | Token ceiling for the extraction response. |
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "scribe": {
3
- "enabled": true,
4
3
  "evaluator": {
5
4
  "model": "claude-haiku-4-5-20251001",
6
5
  "timeout": 60,
@@ -33,10 +33,6 @@ _done() { exit 0; }
33
33
 
34
34
  scribe_config_load "$CWD"
35
35
 
36
- if ! scribe_config_enabled; then
37
- _done
38
- fi
39
-
40
36
  ONLOOKER_DIR="${ONLOOKER_DIR:-${HOME}/.onlooker}"
41
37
  STATE_FILE="${ONLOOKER_DIR}/scribe/sessions/${SESSION_ID}.json"
42
38
 
@@ -2,9 +2,8 @@
2
2
  # Scribe SessionStart hook.
3
3
  #
4
4
  # Fires at every session start. Responsibilities:
5
- # 1. Skip silently when scribe.enabled is false.
6
- # 2. Create storage directories.
7
- # 3. Initialize session state file:
5
+ # 1. Create storage directories.
6
+ # 2. Initialize session state file:
8
7
  # - captured_prompt: null (populated by scribe-capture.sh on first turn)
9
8
  # - captured_at: null
10
9
  #
@@ -30,10 +29,6 @@ _done() { exit 0; }
30
29
 
31
30
  scribe_config_load "$CWD"
32
31
 
33
- if ! scribe_config_enabled; then
34
- _done
35
- fi
36
-
37
32
  export _HOOK_SESSION_ID="$SESSION_ID"
38
33
 
39
34
  ONLOOKER_DIR="${ONLOOKER_DIR:-${HOME}/.onlooker}"
@@ -7,7 +7,6 @@
7
7
  # ~/.onlooker/scribe/<project_key>/<date>-<session>.md.
8
8
  #
9
9
  # Skip conditions (all silent):
10
- # - scribe.enabled is false
11
10
  # - no transcript_path in hook input, or file is unreadable
12
11
  # - session has fewer turns than scribe.capture.min_turns
13
12
  #
@@ -46,10 +45,6 @@ _done() { exit 0; }
46
45
 
47
46
  scribe_config_load "$CWD"
48
47
 
49
- if ! scribe_config_enabled; then
50
- _done
51
- fi
52
-
53
48
  if [[ -z "$TRANSCRIPT_PATH" || ! -f "$TRANSCRIPT_PATH" ]]; then
54
49
  _done
55
50
  fi
@@ -10,7 +10,6 @@
10
10
  # scribe_config_load <repo_root> # populates _SCRIBE_CONFIG (JSON)
11
11
  # scribe_config_get <jq-path> # echoes string value (empty if unset)
12
12
  # scribe_config_get_json <jq-path> # echoes JSON value (null if unset)
13
- # scribe_config_enabled # 0 if scribe.enabled is true
14
13
 
15
14
  _SCRIBE_CONFIG="{}"
16
15
 
@@ -63,10 +62,4 @@ scribe_config_get() {
63
62
  scribe_config_get_json() {
64
63
  local path="$1"
65
64
  printf '%s' "$_SCRIBE_CONFIG" | jq -c "${path}" 2>/dev/null
66
- }
67
-
68
- scribe_config_enabled() {
69
- local v
70
- v=$(scribe_config_get '.scribe.enabled')
71
- [[ "$v" == "true" ]]
72
- }
65
+ }
@@ -24,6 +24,12 @@ _scribe_event_js_path() {
24
24
  for c in "${candidates[@]}"; do
25
25
  [[ -f "$c" ]] && { printf '%s' "$c"; return 0; }
26
26
  done
27
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
28
+ # works regardless of which ecosystem version is installed.
29
+ local mjs
30
+ for mjs in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
31
+ [[ -f "$mjs" ]] && { printf '%s' "$mjs"; return 0; }
32
+ done
27
33
  return 1
28
34
  }
29
35
 
@@ -59,9 +59,13 @@ scribe_count_turns() {
59
59
  local line
60
60
  while IFS= read -r line; do
61
61
  [[ -z "$line" ]] && continue
62
- local role
63
- role=$(printf '%s' "$line" | jq -r '.role // empty' 2>/dev/null) || continue
64
- [[ "$role" == "user" ]] && count=$((count + 1))
62
+ local entry_type
63
+ entry_type=$(printf '%s' "$line" | jq -r '.type // empty' 2>/dev/null) || continue
64
+ [[ "$entry_type" == "user" ]] || continue
65
+ # Only count real user prompts (string content), not tool results (array content)
66
+ local content_type
67
+ content_type=$(printf '%s' "$line" | jq -r '.message.content | type' 2>/dev/null) || continue
68
+ [[ "$content_type" == "string" ]] && count=$((count + 1))
65
69
  done < "$transcript_path"
66
70
 
67
71
  printf '%s' "$count"
@@ -79,21 +83,21 @@ scribe_extract_intent() {
79
83
 
80
84
  local transcript_content
81
85
  transcript_content=$(jq -r '
82
- select(.role != null) |
83
- if .role == "user" then
86
+ select(.type == "user" or .type == "assistant") |
87
+ if .type == "user" then
84
88
  "[User]\n" + (
85
- if (.content | type) == "array" then
86
- [.content[] | select(.type == "text") | .text] | join("\n")
89
+ if (.message.content | type) == "array" then
90
+ [.message.content[] | select(.type == "text") | .text] | join("\n")
87
91
  else
88
- (.content // "")
92
+ (.message.content // "")
89
93
  end
90
94
  )
91
- elif .role == "assistant" then
95
+ elif .type == "assistant" then
92
96
  "[Assistant]\n" + (
93
- if (.content | type) == "array" then
94
- [.content[] | select(.type == "text") | .text] | join("\n")
97
+ if (.message.content | type) == "array" then
98
+ [.message.content[] | select(.type == "text") | .text] | join("\n")
95
99
  else
96
- (.content // "")
100
+ (.message.content // "")
97
101
  end
98
102
  )
99
103
  else empty end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tribunal",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Multi-agent execution with LLM-as-a-Judge quality gates. An Actor performs work; a jury of typed Judges scores it against a project-overridable rubric; a Meta-Judge reviews the jury for bias; the gate decides accept, retry, or exhaust. Grounded in LLM-as-a-Judge (Zheng et al. 2023) and LLM-as-a-Meta-Judge (Wu et al. 2024). Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.1.0...tribunal-v1.1.1) (2026-08-01)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **plugins:** glob-discover ecosystem root so sub-plugins work from cache :relieved: ([#110](https://github.com/onlooker-community/ecosystem/issues/110)) ([3639240](https://github.com/onlooker-community/ecosystem/commit/3639240383e1b820e5d8ea42639e0b863ef0d90e))
9
+
10
+ ## [1.1.0](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.0.1...tribunal-v1.1.0) (2026-07-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **plugins:** installation enables plugins — remove per-plugin 'enabled' config key ([#108](https://github.com/onlooker-community/ecosystem/issues/108)) ([45e4e6b](https://github.com/onlooker-community/ecosystem/commit/45e4e6bd29a0a7545dbd5007bf3f09600e1be391))
16
+
3
17
  ## [1.0.1](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.0.0...tribunal-v1.0.1) (2026-05-25)
4
18
 
5
19
 
@@ -34,7 +34,13 @@ The gate uses `majority` policy with `weighted_mean` aggregation, so one strong
34
34
 
35
35
  ## Configuration
36
36
 
37
- Tribunal is enabled by default; the Stop hook is opt-in. Override per-project in your project's `.claude/settings.json`:
37
+ Install the plugin in Claude from the marketplace with:
38
+
39
+ ```
40
+ /plugin install tribunal@onlooker-community
41
+ ```
42
+
43
+ The Stop hook is opt-in. Override per-project in your project's `.claude/settings.json`:
38
44
 
39
45
  ```json
40
46
  {
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "tribunal",
3
3
  "storage_path": "~/.onlooker",
4
4
  "tribunal": {
5
- "enabled": true,
6
5
  "stop_hook": {
7
6
  "enabled": false,
8
7
  "skip_if_no_file_changes": true
@@ -1,14 +1,8 @@
1
1
  #!/usr/bin/env bash
2
2
  # Tribunal Stop-gate hook.
3
3
  #
4
- # Triggered by Stop. Off by default — gated on tribunal.stop_hook.enabled in
5
- # config. When enabled, runs a single-judge advisory pass on the just-finished
6
- # session's last turn and writes a verdict for review on the next session.
7
- #
8
- # Why advisory only: by the time Stop fires the main agent loop has already
9
- # ended. We cannot retry the Actor or re-run the work. The hook records what
10
- # the Standard Judge would have said so a human (or a follow-up SessionStart
11
- # hook in v0.2) can see whether the turn would have passed the gate.
4
+ # Triggered by Stop.
5
+ # runs a single-judge advisory pass on the just-finished session's last turn and writes a verdict for review on the next session.
12
6
  #
13
7
  # Hook contract:
14
8
  # - Always exits 0. Never blocks Stop.
@@ -30,6 +24,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
30
24
  _ECOSYSTEM_ROOT="$_candidate"
31
25
  fi
32
26
  fi
27
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
28
+ # works regardless of which ecosystem version is installed.
29
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
30
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
31
+ if [[ -f "$_candidate" ]]; then
32
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
33
+ break
34
+ fi
35
+ done
36
+ fi
33
37
 
34
38
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
35
39
  # shellcheck disable=SC1091
@@ -64,10 +68,6 @@ _done() {
64
68
  REPO_ROOT=$(tribunal_project_repo_root "$CWD")
65
69
  tribunal_config_load "$REPO_ROOT"
66
70
 
67
- if ! tribunal_config_stop_hook_enabled; then
68
- _done
69
- fi
70
-
71
71
  PROJECT_KEY=$(tribunal_project_key "$CWD")
72
72
  if [[ -z "$PROJECT_KEY" || -z "$REPO_ROOT" ]]; then
73
73
  _done
@@ -77,8 +77,7 @@ if [[ -z "$TRANSCRIPT_PATH" || ! -f "$TRANSCRIPT_PATH" ]]; then
77
77
  _done
78
78
  fi
79
79
 
80
- # Skip if no files were modified since the last commit AND the user enabled
81
- # skip_if_no_file_changes (default true).
80
+ # Skip if no files were modified since the last commit AND skip_if_no_file_changes is true.
82
81
  SKIP_IF_CLEAN=$(tribunal_config_get '.tribunal.stop_hook.skip_if_no_file_changes')
83
82
  if [[ "$SKIP_IF_CLEAN" == "true" ]]; then
84
83
  if git -C "$REPO_ROOT" diff --quiet 2>/dev/null && git -C "$REPO_ROOT" diff --cached --quiet 2>/dev/null; then