@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,8 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # Echo Stop-gate hook.
3
3
  #
4
- # Triggered by Stop. Off by default gated on echo.enabled in config.
5
- # When enabled, detects which watched agent files changed in this session,
4
+ # Triggered by Stop. Detects which watched agent files changed in this session,
6
5
  # runs a single-judge advisory pass on each, and compares the score against a
7
6
  # stored baseline to report improved / degraded / neutral.
8
7
  #
@@ -30,6 +29,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
30
29
  _ECOSYSTEM_ROOT="$_candidate"
31
30
  fi
32
31
  fi
32
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
33
+ # works regardless of which ecosystem version is installed.
34
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
35
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
36
+ if [[ -f "$_candidate" ]]; then
37
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
38
+ break
39
+ fi
40
+ done
41
+ fi
33
42
 
34
43
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
35
44
  # shellcheck disable=SC1091
@@ -61,7 +70,6 @@ REPO_ROOT=$(echo_project_repo_root "$CWD")
61
70
  [[ -z "$REPO_ROOT" ]] && _done
62
71
 
63
72
  CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" echo_config_load "$REPO_ROOT"
64
- echo_config_enabled || _done
65
73
 
66
74
  PROJECT_KEY=$(echo_project_key "$CWD")
67
75
  [[ -z "$PROJECT_KEY" ]] && _done
@@ -61,12 +61,6 @@ echo_config_get_json() {
61
61
  fi
62
62
  }
63
63
 
64
- echo_config_enabled() {
65
- local val
66
- val=$(echo_config_get '.enabled')
67
- [[ "$val" == "true" ]]
68
- }
69
-
70
64
  echo_config_model() {
71
65
  local val
72
66
  val=$(echo_config_get '.evaluation.model')
@@ -18,6 +18,12 @@ _echo_event_js_path() {
18
18
  for c in "${candidates[@]}"; do
19
19
  [[ -f "$c" ]] && { printf '%s' "$c"; return 0; }
20
20
  done
21
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
22
+ # works regardless of which ecosystem version is installed.
23
+ local mjs
24
+ for mjs in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
25
+ [[ -f "$mjs" ]] && { printf '%s' "$mjs"; return 0; }
26
+ done
21
27
  return 1
22
28
  }
23
29
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "governor",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Resource governance and budget enforcement for the Onlooker ecosystem. Tracks per-session token and cost spend, gates Task spawns before they exceed a configurable budget ceiling, and emits governor.* events for audit. Named for the steam-engine governor — a device that regulates output. Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1](https://github.com/onlooker-community/ecosystem/compare/governor-v0.3.0...governor-v0.3.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.3.0](https://github.com/onlooker-community/ecosystem/compare/governor-v0.2.1...governor-v0.3.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.2.1](https://github.com/onlooker-community/ecosystem/compare/governor-v0.2.0...governor-v0.2.1) (2026-06-10)
4
18
 
5
19
 
@@ -42,17 +42,13 @@ The raw estimate is multiplied by `safety_margin` before the gate check. Cost is
42
42
 
43
43
  ## Activation
44
44
 
45
- Governor is **off by default**. Enable it per-project in `.claude/settings.json`:
45
+ Install Governor from the marketplace:
46
46
 
47
- ```json
48
- {
49
- "governor": {
50
- "enabled": true
51
- }
52
- }
47
+ ```
48
+ /plugin install governor@onlooker-community
53
49
  ```
54
50
 
55
- Or globally in `~/.claude/settings.json`. While disabled, every hook skips silently and no ledger is written.
51
+ Once installed, the plugin is active. No additional configuration is required to enable it.
56
52
 
57
53
  ## Configuration
58
54
 
@@ -61,7 +57,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
61
57
  ```json
62
58
  {
63
59
  "governor": {
64
- "enabled": false,
65
60
  "enforcement": "soft",
66
61
  "global_policy_path": "~/.onlooker/governance/global-policy.yaml",
67
62
  "session": {
@@ -80,7 +75,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
80
75
 
81
76
  | Key | Default | Description |
82
77
  |-----|---------|-------------|
83
- | `enabled` | `false` | Must be `true` for any tracking, gating, or event emission to run. |
84
78
  | `enforcement` | `"soft"` | `"soft"` tracks and emits events but never blocks on a budget overrun; `"hard"` blocks `Task` spawns once the budget is exceeded. A `ceiling_exceeded` overrun blocks in both modes. |
85
79
  | `global_policy_path` | `"~/.onlooker/governance/global-policy.yaml"` | Path checked at `SessionStart`. Missing file warns to stderr only — the session runs without a global ceiling. |
86
80
  | `session.tokens_default` | `100000` | Per-session token budget. Projecting past this triggers `budget_exceeded`. Overridable per session via the `ONLOOKER_SESSION_BUDGET_TOKENS` environment variable. |
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "governor",
3
3
  "storage_path": "~/.onlooker",
4
4
  "governor": {
5
- "enabled": false,
6
5
  "enforcement": "soft",
7
6
  "global_policy_path": "~/.onlooker/governance/global-policy.yaml",
8
7
  "session": {
@@ -6,7 +6,6 @@
6
6
  #
7
7
  # Hook contract:
8
8
  # - Always exits 0. Recording failure must never block the session.
9
- # - Skips silently when governor.enabled is false.
10
9
 
11
10
  set -uo pipefail
12
11
 
@@ -20,6 +19,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
20
19
  _ECOSYSTEM_ROOT="$_candidate"
21
20
  fi
22
21
  fi
22
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
23
+ # works regardless of which ecosystem version is installed.
24
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
25
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
26
+ if [[ -f "$_candidate" ]]; then
27
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
28
+ break
29
+ fi
30
+ done
31
+ fi
23
32
 
24
33
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
25
34
  # shellcheck disable=SC1091
@@ -52,10 +61,6 @@ CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // ""' 2>/dev/null) || CWD=""
52
61
 
53
62
  governor_config_load "$CWD"
54
63
 
55
- if ! governor_config_enabled; then
56
- _done
57
- fi
58
-
59
64
  # -----------------------------------------------------------------------
60
65
  # Extract hook fields.
61
66
  # -----------------------------------------------------------------------
@@ -18,7 +18,6 @@
18
18
  # - Exit 0 always.
19
19
  # - To block: write {"decision": "block", "reason": "..."} to stdout.
20
20
  # - To allow: write nothing (or {"decision": "allow"}) to stdout.
21
- # - Skips silently when governor.enabled is false.
22
21
 
23
22
  set -uo pipefail
24
23
 
@@ -32,6 +31,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
32
31
  _ECOSYSTEM_ROOT="$_candidate"
33
32
  fi
34
33
  fi
34
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
35
+ # works regardless of which ecosystem version is installed.
36
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
37
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
38
+ if [[ -f "$_candidate" ]]; then
39
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
40
+ break
41
+ fi
42
+ done
43
+ fi
35
44
 
36
45
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
37
46
  # shellcheck disable=SC1091
@@ -70,10 +79,6 @@ CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // ""' 2>/dev/null) || CWD=""
70
79
 
71
80
  governor_config_load "$CWD"
72
81
 
73
- if ! governor_config_enabled; then
74
- _allow
75
- fi
76
-
77
82
  # -----------------------------------------------------------------------
78
83
  # Read config.
79
84
  # -----------------------------------------------------------------------
@@ -2,11 +2,10 @@
2
2
  # Governor SessionStart hook.
3
3
  #
4
4
  # Fires at every session start. Responsibilities:
5
- # 1. Skip silently when governor.enabled is false.
6
- # 2. Create governance storage directories.
7
- # 3. Sweep stale lock files left by crashed prior sessions.
8
- # 4. Check global-policy.yaml exists (warn if missing, don't block).
9
- # 5. Emit governor.lock.stale_cleared for each stale lock removed.
5
+ # 1. Create governance storage directories.
6
+ # 2. Sweep stale lock files left by crashed prior sessions.
7
+ # 3. Check global-policy.yaml exists (warn if missing, don't block).
8
+ # 4. Emit governor.lock.stale_cleared for each stale lock removed.
10
9
  #
11
10
  # Hook contract:
12
11
  # - Always exits 0. Never blocks SessionStart.
@@ -24,6 +23,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
24
23
  _ECOSYSTEM_ROOT="$_candidate"
25
24
  fi
26
25
  fi
26
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
27
+ # works regardless of which ecosystem version is installed.
28
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
29
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
30
+ if [[ -f "$_candidate" ]]; then
31
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
32
+ break
33
+ fi
34
+ done
35
+ fi
27
36
 
28
37
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
29
38
  # shellcheck disable=SC1091
@@ -51,10 +60,6 @@ _done() { exit 0; }
51
60
 
52
61
  governor_config_load "$CWD"
53
62
 
54
- if ! governor_config_enabled; then
55
- _done
56
- fi
57
-
58
63
  # -----------------------------------------------------------------------
59
64
  # 1. Ensure storage directories exist.
60
65
  # -----------------------------------------------------------------------
@@ -6,7 +6,6 @@
6
6
  #
7
7
  # Hook contract:
8
8
  # - Always exits 0. Never blocks Stop.
9
- # - Skips silently when governor.enabled is false.
10
9
  # - Errors from ledger reads are swallowed; emits best-effort totals.
11
10
 
12
11
  set -uo pipefail
@@ -21,6 +20,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
21
20
  _ECOSYSTEM_ROOT="$_candidate"
22
21
  fi
23
22
  fi
23
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
24
+ # works regardless of which ecosystem version is installed.
25
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
26
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
27
+ if [[ -f "$_candidate" ]]; then
28
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
29
+ break
30
+ fi
31
+ done
32
+ fi
24
33
 
25
34
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
26
35
  # shellcheck disable=SC1091
@@ -51,10 +60,6 @@ CWD=$(printf '%s' "$INPUT" | jq -r '.cwd // ""' 2>/dev/null) || CWD=""
51
60
 
52
61
  governor_config_load "$CWD"
53
62
 
54
- if ! governor_config_enabled; then
55
- _done
56
- fi
57
-
58
63
  # -----------------------------------------------------------------------
59
64
  # Read session totals from the ledger.
60
65
  # -----------------------------------------------------------------------
@@ -10,7 +10,6 @@
10
10
  # governor_config_load <repo_root> # populates _GOVERNOR_CONFIG (JSON)
11
11
  # governor_config_get <jq-path> # echoes string value (empty if unset)
12
12
  # governor_config_get_json <jq-path> # echoes JSON value (null if unset)
13
- # governor_config_enabled # 0 if governor.enabled is true
14
13
  # governor_config_enforcement # echoes "soft" or "hard"
15
14
 
16
15
  _GOVERNOR_CONFIG="{}"
@@ -66,12 +65,6 @@ governor_config_get_json() {
66
65
  printf '%s' "$_GOVERNOR_CONFIG" | jq -c "${path}" 2>/dev/null
67
66
  }
68
67
 
69
- governor_config_enabled() {
70
- local v
71
- v=$(governor_config_get '.governor.enabled')
72
- [[ "$v" == "true" ]]
73
- }
74
-
75
68
  governor_config_enforcement() {
76
69
  local v
77
70
  v=$(governor_config_get '.governor.enforcement')
@@ -24,6 +24,12 @@ _governor_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
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "historian",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Episodic memory layer. At SessionEnd, chunks and sanitizes the session transcript and stores chunks under $ONLOOKER_DIR/historian/<project-key>/sessions/ (default $HOME/.onlooker). On UserPromptSubmit, embeds the prompt and performs similarity retrieval over stored chunks to surface relevant past context. Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1](https://github.com/onlooker-community/ecosystem/compare/historian-v0.3.0...historian-v0.3.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.3.0](https://github.com/onlooker-community/ecosystem/compare/historian-v0.2.1...historian-v0.3.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.2.1](https://github.com/onlooker-community/ecosystem/compare/historian-v0.2.0...historian-v0.2.1) (2026-06-28)
4
18
 
5
19
 
@@ -17,14 +17,10 @@ See [`docs/design.md`](docs/design.md) and [ADR-001](docs/adr/001-local-embeddin
17
17
 
18
18
  ## Activation
19
19
 
20
- Historian is **off by default**. Enable per-project in `.claude/settings.json`:
20
+ Install via the marketplace:
21
21
 
22
- ```json
23
- {
24
- "historian": {
25
- "enabled": true
26
- }
27
- }
22
+ ```
23
+ /plugin install historian@onlooker-community
28
24
  ```
29
25
 
30
26
  See [`config.json`](config.json) for the full set of tunable defaults.
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "historian",
3
3
  "storage_path": "~/.onlooker",
4
4
  "historian": {
5
- "enabled": false,
6
5
  "indexing": {
7
6
  "trigger": "SessionEnd",
8
7
  "min_transcript_chars_to_index": 1200,
@@ -17,7 +17,7 @@
17
17
  # Hook contract:
18
18
  # - Always exits 0. Never blocks the prompt.
19
19
  # - Emits valid hookSpecificOutput JSON even when nothing to inject.
20
- # - No-ops when historian.enabled is not true OR retrieval is disabled.
20
+ # - No-ops when retrieval is disabled.
21
21
  # - Lifecycle events: historian.retrieval.started fires when the rate
22
22
  # gate clears and we are about to embed. All outcomes flow through
23
23
  # historian.retrieval.complete with `outcome: surfaced | empty |
@@ -38,6 +38,16 @@ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
38
38
  _ECOSYSTEM_ROOT="$_candidate"
39
39
  fi
40
40
  fi
41
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
42
+ # works regardless of which ecosystem version is installed.
43
+ if [[ -z "$_ECOSYSTEM_ROOT" ]]; then
44
+ for _candidate in "${PLUGIN_ROOT}/../../ecosystem/"*/scripts/lib/validate-path.sh; do
45
+ if [[ -f "$_candidate" ]]; then
46
+ _ECOSYSTEM_ROOT="$(cd "$(dirname "$(dirname "$_candidate")")" && pwd)"
47
+ break
48
+ fi
49
+ done
50
+ fi
41
51
  if [[ -n "$_ECOSYSTEM_ROOT" && -f "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh" ]]; then
42
52
  # shellcheck disable=SC1091
43
53
  CLAUDE_PLUGIN_ROOT="$_ECOSYSTEM_ROOT" source "${_ECOSYSTEM_ROOT}/scripts/lib/validate-path.sh"
@@ -81,11 +91,6 @@ PROMPT=$(printf '%s' "$INPUT" | jq -r '.prompt // .user_message // .message // "
81
91
  REPO_ROOT=$(historian_project_repo_root "$CWD")
82
92
  historian_config_load "$REPO_ROOT"
83
93
 
84
- if ! historian_config_enabled; then
85
- _emit_context ""
86
- exit 0
87
- fi
88
-
89
94
  RETRIEVAL_ENABLED=$(historian_config_get '.historian.retrieval.enabled')
90
95
  if [[ "$RETRIEVAL_ENABLED" == "false" ]]; then
91
96
  _emit_context ""
@@ -8,7 +8,6 @@
8
8
  #
9
9
  # Hook contract:
10
10
  # - Always exits 0. Never blocks session shutdown.
11
- # - No-ops when historian.enabled is not true.
12
11
  # - No-ops when there is no project key, no transcript path, or the
13
12
  # transcript is shorter than min_transcript_chars_to_index.
14
13
  # - Indexing failures are fail-soft: an emitted historian.indexing.complete
@@ -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,7 +68,6 @@ TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/n
59
68
 
60
69
  REPO_ROOT=$(historian_project_repo_root "$CWD")
61
70
  historian_config_load "$REPO_ROOT"
62
- historian_config_enabled || exit 0
63
71
 
64
72
  PROJECT_KEY=$(historian_project_key "$CWD")
65
73
  [[ -z "$PROJECT_KEY" ]] && exit 0
@@ -9,7 +9,6 @@
9
9
  # Exposes:
10
10
  # historian_config_load <repo_root> # populates _HISTORIAN_CONFIG (JSON)
11
11
  # historian_config_get <jq-path> # echoes string value (empty if unset)
12
- # historian_config_enabled # 0 if historian.enabled is true
13
12
  #
14
13
  # Settings overlay only touches the `historian.*` subtree of settings.json.
15
14
 
@@ -59,8 +58,3 @@ historian_config_get() {
59
58
  | jq -r "${path} | if . == null then empty else . end" 2>/dev/null
60
59
  }
61
60
 
62
- historian_config_enabled() {
63
- local v
64
- v=$(historian_config_get '.historian.enabled')
65
- [[ "$v" == "true" ]]
66
- }
@@ -16,6 +16,16 @@ _historian_resolve_event_js() {
16
16
  ecosystem_root="$candidate"
17
17
  fi
18
18
  fi
19
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
20
+ # works regardless of which ecosystem version is installed.
21
+ if [[ -z "$ecosystem_root" ]]; then
22
+ for candidate in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
23
+ if [[ -f "$candidate" ]]; then
24
+ ecosystem_root="$(cd "$(dirname "$(dirname "$candidate")")" && pwd)"
25
+ break
26
+ fi
27
+ done
28
+ fi
19
29
 
20
30
  if [[ -n "$ecosystem_root" ]]; then
21
31
  printf '%s/scripts/lib/onlooker-event.mjs' "$ecosystem_root"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inspector",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Per-edit lint and typecheck gate. Runs the project's configured checks on just the touched file after every Write / Edit / MultiEdit, so the agent sees its own type errors before claiming success. Cheaper than proctor (which runs project-wide verification at Stop); complements assayer (which catches the agent lying about claims). Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1](https://github.com/onlooker-community/ecosystem/compare/inspector-v0.3.0...inspector-v0.3.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.3.0](https://github.com/onlooker-community/ecosystem/compare/inspector-v0.2.0...inspector-v0.3.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.2.0](https://github.com/onlooker-community/ecosystem/compare/inspector-v0.1.0...inspector-v0.2.0) (2026-06-15)
4
18
 
5
19
 
@@ -51,13 +51,18 @@ checks too. The agent sees this on its next turn.
51
51
 
52
52
  ## Activation
53
53
 
54
- Inspector ships disabled. Opt in per project (or globally) by adding the
55
- `inspector` block to `.claude/settings.json`:
54
+ Install the plugin from the marketplace:
55
+
56
+ ```
57
+ /plugin install inspector@onlooker-community
58
+ ```
59
+
60
+ Once installed, inspector is active. Configure it per project (or globally) by
61
+ adding the `inspector` block to `.claude/settings.json`:
56
62
 
57
63
  ```jsonc
58
64
  {
59
65
  "inspector": {
60
- "enabled": true,
61
66
  "checks": {
62
67
  ".ts": [{ "name": "biome", "kind": "lint", "argv": ["biome", "check", "${file}"] },
63
68
  { "name": "tsc", "kind": "typecheck", "argv": ["tsc", "--noEmit"] }],
@@ -87,7 +92,6 @@ A bare argv array (`["shellcheck", "${file}"]`) is also accepted as a shorthand
87
92
 
88
93
  | Field | Default | Meaning |
89
94
  |---|---|---|
90
- | `enabled` | `false` | Master switch. |
91
95
  | `timeout_seconds_per_check` | `10` | Wall-clock cap per check. Exceeded → `inspector.check.skipped` with `reason: "timeout"`. |
92
96
  | `total_timeout_seconds` | `30` | Wall-clock cap for the whole run. Remaining checks emit `.skipped` with `reason: "total_budget_exhausted"`. |
93
97
  | `output_excerpt_max_bytes` | `4096` | Cap on captured output, both in the event and shown to the agent. Excess is replaced with `…[truncated]`. |
@@ -108,7 +112,7 @@ All events are registered in `@onlooker-community/schema`.
108
112
  |---|---|---|
109
113
  | `inspector.check.passed` | A check returned exit 0 | `file_path`, `tool_name`, `check_name`, `check_kind`, `argv`, `duration_ms` |
110
114
  | `inspector.check.failed` | A check returned non-zero | `exit_code`, `issue_count` (best-effort, may be `null`), `output_excerpt`, `output_truncated` |
111
- | `inspector.check.skipped` | A check or whole file was not run | `reason`: one of `disabled`, `excluded_path`, `no_extension_match`, `not_in_repo`, `tool_missing`, `timeout`, `total_budget_exhausted` |
115
+ | `inspector.check.skipped` | A check or whole file was not run | `reason`: one of `excluded_path`, `no_extension_match`, `not_in_repo`, `tool_missing`, `timeout`, `total_budget_exhausted` |
112
116
  | `inspector.run.completed` | Once per hook fire after all checks | `checks_run`, `checks_passed`, `checks_failed`, `checks_skipped`, `duration_ms` |
113
117
 
114
118
  Downstream consumers that just want "did this edit produce broken code?" read
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "inspector",
3
3
  "storage_path": "~/.onlooker",
4
4
  "inspector": {
5
- "enabled": false,
6
5
  "timeout_seconds_per_check": 10,
7
6
  "total_timeout_seconds": 30,
8
7
  "output_excerpt_max_bytes": 4096,
@@ -61,7 +61,6 @@ export INSPECTOR_PROJECT_KEY="$PROJECT_KEY"
61
61
  if [[ "$CANONICAL" != "$REPO_ROOT"/* && "$CANONICAL" != "$REPO_ROOT" ]]; then
62
62
  export INSPECTOR_FILE_RELATIVE="$CANONICAL"
63
63
  inspector_config_load "$REPO_ROOT"
64
- inspector_config_enabled || exit 0
65
64
  inspector_emit_whole_file_skipped "not_in_repo"
66
65
  exit 0
67
66
  fi
@@ -69,12 +68,6 @@ export INSPECTOR_FILE_RELATIVE="${CANONICAL#"$REPO_ROOT"/}"
69
68
 
70
69
  inspector_config_load "$REPO_ROOT"
71
70
 
72
- if ! inspector_config_enabled; then
73
- # Silent skip — do not even emit an event when disabled. Disabled means
74
- # "this plugin is dormant," not "this file was uninteresting."
75
- exit 0
76
- fi
77
-
78
71
  # Excluded path containment check.
79
72
  EXCLUDES=$(inspector_config_exclude_paths)
80
73
  if [[ -n "$EXCLUDES" && "$EXCLUDES" != "null" && "$EXCLUDES" != "[]" ]]; then
@@ -8,7 +8,6 @@
8
8
  #
9
9
  # Usage:
10
10
  # inspector_config_load <repo_root>
11
- # inspector_config_enabled
12
11
  # inspector_config_get ".inspector.timeout_seconds_per_check"
13
12
  # inspector_config_get_json ".inspector.exclude_paths"
14
13
  # inspector_config_checks_for_extension ".ts"
@@ -54,12 +53,6 @@ inspector_config_get_json() {
54
53
  printf '%s' "$_INSPECTOR_CONFIG" | jq -c "$path // empty" 2>/dev/null
55
54
  }
56
55
 
57
- inspector_config_enabled() {
58
- local v
59
- v=$(inspector_config_get '.inspector.enabled')
60
- [[ "$v" == "true" ]]
61
- }
62
-
63
56
  inspector_config_show_clean_runs() {
64
57
  local v
65
58
  v=$(inspector_config_get '.inspector.show_clean_runs')
@@ -23,6 +23,12 @@ _inspector_event_js_path() {
23
23
  for c in "${candidates[@]}"; do
24
24
  [[ -f "$c" ]] && { printf '%s' "$c"; return 0; }
25
25
  done
26
+ # Glob-discover the ecosystem plugin under the shared plugin cache parent;
27
+ # works regardless of which ecosystem version is installed.
28
+ local mjs
29
+ for mjs in "${plugin_root}/../../ecosystem/"*/scripts/lib/onlooker-event.mjs; do
30
+ [[ -f "$mjs" ]] && { printf '%s' "$mjs"; return 0; }
31
+ done
26
32
  return 1
27
33
  }
28
34
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "librarian",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Consolidation layer between archivist's per-session artifacts and the user's durable typed memory store. Detects which session decisions, dead-ends, and open questions deserve to live across sessions, classifies them into the user/feedback/project/reference types, and queues them as proposals for explicit confirmation. Auto-promotion is opt-in. Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",