@onlooker-community/ecosystem 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) 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 +19 -0
  5. package/CLAUDE.md +10 -0
  6. package/package.json +2 -3
  7. package/plugins/archivist/.claude-plugin/plugin.json +1 -1
  8. package/plugins/archivist/CHANGELOG.md +7 -0
  9. package/plugins/archivist/README.md +4 -10
  10. package/plugins/archivist/config.json +0 -1
  11. package/plugins/archivist/scripts/hooks/archivist-extract.sh +0 -6
  12. package/plugins/archivist/scripts/hooks/archivist-inject.sh +2 -7
  13. package/plugins/archivist/scripts/lib/archivist-config.sh +0 -8
  14. package/plugins/assayer/.claude-plugin/plugin.json +1 -1
  15. package/plugins/assayer/CHANGELOG.md +7 -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 +1 -3
  19. package/plugins/assayer/scripts/lib/assayer-config.sh +0 -6
  20. package/plugins/bursar/.claude-plugin/plugin.json +1 -1
  21. package/plugins/bursar/CHANGELOG.md +7 -0
  22. package/plugins/bursar/README.md +3 -11
  23. package/plugins/bursar/config.json +0 -1
  24. package/plugins/bursar/scripts/hooks/bursar-session-end.sh +4 -6
  25. package/plugins/bursar/scripts/hooks/bursar-session-start.sh +3 -5
  26. package/plugins/bursar/scripts/lib/bursar-config.sh +1 -7
  27. package/plugins/cartographer/.claude-plugin/plugin.json +1 -1
  28. package/plugins/cartographer/CHANGELOG.md +7 -0
  29. package/plugins/cartographer/README.md +3 -10
  30. package/plugins/cartographer/config.json +0 -1
  31. package/plugins/cartographer/scripts/hooks/cartographer-post-write.sh +0 -2
  32. package/plugins/cartographer/scripts/hooks/cartographer-session-start.sh +0 -2
  33. package/plugins/cartographer/scripts/lib/cartographer-config.sh +0 -7
  34. package/plugins/cartographer/skills/cartographer/SKILL.md +0 -5
  35. package/plugins/compass/.claude-plugin/plugin.json +1 -1
  36. package/plugins/compass/CHANGELOG.md +7 -0
  37. package/plugins/compass/README.md +4 -10
  38. package/plugins/compass/config.json +0 -1
  39. package/plugins/compass/scripts/hooks/compass-bash-gate.sh +0 -4
  40. package/plugins/compass/scripts/hooks/compass-pre-tool-use.sh +0 -4
  41. package/plugins/compass/scripts/hooks/compass-record-write.sh +0 -4
  42. package/plugins/compass/scripts/hooks/compass-session-start.sh +1 -6
  43. package/plugins/compass/scripts/lib/compass-config.sh +0 -7
  44. package/plugins/counsel/.claude-plugin/plugin.json +1 -1
  45. package/plugins/counsel/CHANGELOG.md +7 -0
  46. package/plugins/counsel/README.md +6 -10
  47. package/plugins/counsel/config.json +0 -1
  48. package/plugins/counsel/scripts/hooks/counsel-session-start.sh +1 -7
  49. package/plugins/counsel/scripts/lib/counsel-config.sh +0 -6
  50. package/plugins/counsel/skills/counsel/SKILL.md +0 -5
  51. package/plugins/curator/.claude-plugin/plugin.json +1 -1
  52. package/plugins/curator/CHANGELOG.md +7 -0
  53. package/plugins/curator/README.md +1 -11
  54. package/plugins/curator/config.json +0 -1
  55. package/plugins/curator/scripts/hooks/curator-session-start.sh +0 -6
  56. package/plugins/curator/scripts/lib/curator-config.sh +0 -7
  57. package/plugins/echo/.claude-plugin/plugin.json +1 -1
  58. package/plugins/echo/CHANGELOG.md +7 -0
  59. package/plugins/echo/README.md +3 -9
  60. package/plugins/echo/config.json +0 -1
  61. package/plugins/echo/scripts/hooks/echo-stop-gate.sh +1 -3
  62. package/plugins/echo/scripts/lib/echo-config.sh +0 -6
  63. package/plugins/governor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/governor/CHANGELOG.md +7 -0
  65. package/plugins/governor/README.md +4 -10
  66. package/plugins/governor/config.json +0 -1
  67. package/plugins/governor/scripts/hooks/governor-post-tool-use.sh +0 -5
  68. package/plugins/governor/scripts/hooks/governor-pre-tool-use.sh +0 -5
  69. package/plugins/governor/scripts/hooks/governor-session-start.sh +4 -9
  70. package/plugins/governor/scripts/hooks/governor-stop.sh +0 -5
  71. package/plugins/governor/scripts/lib/governor-config.sh +0 -7
  72. package/plugins/historian/.claude-plugin/plugin.json +1 -1
  73. package/plugins/historian/CHANGELOG.md +14 -0
  74. package/plugins/historian/README.md +3 -7
  75. package/plugins/historian/config.json +0 -1
  76. package/plugins/historian/scripts/hooks/historian-prompt-submit.sh +1 -6
  77. package/plugins/historian/scripts/hooks/historian-session-end.sh +2 -6
  78. package/plugins/historian/scripts/lib/historian-config.sh +0 -6
  79. package/plugins/historian/scripts/lib/historian-embedder.sh +10 -6
  80. package/plugins/inspector/.claude-plugin/plugin.json +1 -1
  81. package/plugins/inspector/CHANGELOG.md +7 -0
  82. package/plugins/inspector/README.md +9 -5
  83. package/plugins/inspector/config.json +0 -1
  84. package/plugins/inspector/scripts/hooks/inspector-post-write.sh +0 -7
  85. package/plugins/inspector/scripts/lib/inspector-config.sh +0 -7
  86. package/plugins/librarian/.claude-plugin/plugin.json +1 -1
  87. package/plugins/librarian/CHANGELOG.md +7 -0
  88. package/plugins/librarian/README.md +5 -9
  89. package/plugins/librarian/config.json +0 -1
  90. package/plugins/librarian/scripts/hooks/librarian-session-end.sh +0 -2
  91. package/plugins/librarian/scripts/hooks/librarian-session-start.sh +0 -6
  92. package/plugins/librarian/scripts/lib/librarian-config.sh +0 -8
  93. package/plugins/lineage/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lineage/CHANGELOG.md +7 -1
  95. package/plugins/lineage/README.md +3 -12
  96. package/plugins/lineage/config.json +0 -1
  97. package/plugins/lineage/scripts/hooks/lineage-post-tool-use.sh +0 -1
  98. package/plugins/lineage/scripts/lib/lineage-config.sh +0 -7
  99. package/plugins/lineage/skills/lineage/SKILL.md +1 -4
  100. package/plugins/scribe/.claude-plugin/plugin.json +1 -1
  101. package/plugins/scribe/CHANGELOG.md +7 -0
  102. package/plugins/scribe/README.md +4 -12
  103. package/plugins/scribe/config.json +0 -1
  104. package/plugins/scribe/scripts/hooks/scribe-capture.sh +0 -4
  105. package/plugins/scribe/scripts/hooks/scribe-session-start.sh +2 -7
  106. package/plugins/scribe/scripts/hooks/scribe-stop.sh +0 -5
  107. package/plugins/scribe/scripts/lib/scribe-config.sh +1 -8
  108. package/plugins/scribe/scripts/lib/scribe-extract.sh +16 -12
  109. package/plugins/tribunal/.claude-plugin/plugin.json +1 -1
  110. package/plugins/tribunal/CHANGELOG.md +7 -0
  111. package/plugins/tribunal/README.md +7 -1
  112. package/plugins/tribunal/config.json +0 -1
  113. package/plugins/tribunal/scripts/hooks/tribunal-stop-gate.sh +3 -14
  114. package/plugins/tribunal/scripts/lib/tribunal-config.sh +0 -8
  115. package/plugins/warden/.claude-plugin/plugin.json +1 -1
  116. package/plugins/warden/CHANGELOG.md +7 -0
  117. package/plugins/warden/README.md +3 -12
  118. package/plugins/warden/config.json +0 -1
  119. package/plugins/warden/scripts/hooks/warden-post-tool-use.sh +0 -4
  120. package/plugins/warden/scripts/hooks/warden-pre-tool-use.sh +0 -4
  121. package/plugins/warden/scripts/hooks/warden-session-start.sh +1 -6
  122. package/plugins/warden/scripts/lib/warden-config.sh +1 -8
  123. package/renovate.json +34 -0
  124. package/test/bats/archivist-config-files.bats +2 -2
  125. package/test/bats/archivist-config.bats +0 -25
  126. package/test/bats/archivist-inject.bats +1 -13
  127. package/test/bats/assayer-config.bats +0 -13
  128. package/test/bats/assayer-stop-hook.bats +3 -17
  129. package/test/bats/bursar-config.bats +0 -25
  130. package/test/bats/bursar-session-end.bats +0 -20
  131. package/test/bats/bursar-session-start.bats +1 -18
  132. package/test/bats/cartographer-config.bats +0 -25
  133. package/test/bats/compass-config.bats +1 -26
  134. package/test/bats/compass-gate.bats +1 -3
  135. package/test/bats/curator-session-start.bats +2 -12
  136. package/test/bats/echo-config.bats +0 -24
  137. package/test/bats/echo-stop-hook.bats +3 -15
  138. package/test/bats/governor-config.bats +0 -36
  139. package/test/bats/historian-prompt-submit.bats +2 -8
  140. package/test/bats/historian-session-end.bats +4 -14
  141. package/test/bats/inspector-config.bats +0 -13
  142. package/test/bats/inspector-post-write-hook.bats +10 -17
  143. package/test/bats/librarian-session-end.bats +0 -11
  144. package/test/bats/librarian-session-start.bats +1 -11
  145. package/test/bats/lineage-config.bats +0 -25
  146. package/test/bats/lineage-post-tool-use.bats +1 -7
  147. package/test/bats/scribe-extract.bats +6 -6
  148. package/test/bats/tribunal-config.bats +0 -25
  149. package/test/bats/warden-config.bats +0 -25
  150. package/test/bats/warden-scanner.bats +1 -1
@@ -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
+ }
@@ -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.0",
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,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.0](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.0.1...tribunal-v1.1.0) (2026-07-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * **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))
9
+
3
10
  ## [1.0.1](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.0.0...tribunal-v1.0.1) (2026-05-25)
4
11
 
5
12
 
@@ -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.
@@ -64,10 +58,6 @@ _done() {
64
58
  REPO_ROOT=$(tribunal_project_repo_root "$CWD")
65
59
  tribunal_config_load "$REPO_ROOT"
66
60
 
67
- if ! tribunal_config_stop_hook_enabled; then
68
- _done
69
- fi
70
-
71
61
  PROJECT_KEY=$(tribunal_project_key "$CWD")
72
62
  if [[ -z "$PROJECT_KEY" || -z "$REPO_ROOT" ]]; then
73
63
  _done
@@ -77,8 +67,7 @@ if [[ -z "$TRANSCRIPT_PATH" || ! -f "$TRANSCRIPT_PATH" ]]; then
77
67
  _done
78
68
  fi
79
69
 
80
- # Skip if no files were modified since the last commit AND the user enabled
81
- # skip_if_no_file_changes (default true).
70
+ # Skip if no files were modified since the last commit AND skip_if_no_file_changes is true.
82
71
  SKIP_IF_CLEAN=$(tribunal_config_get '.tribunal.stop_hook.skip_if_no_file_changes')
83
72
  if [[ "$SKIP_IF_CLEAN" == "true" ]]; then
84
73
  if git -C "$REPO_ROOT" diff --quiet 2>/dev/null && git -C "$REPO_ROOT" diff --cached --quiet 2>/dev/null; then
@@ -10,7 +10,6 @@
10
10
  # tribunal_config_load <repo_root> # populates _TRIBUNAL_CONFIG (JSON)
11
11
  # tribunal_config_get <jq-path> # echoes string value (empty if unset)
12
12
  # tribunal_config_get_json <jq-path> # echoes JSON value (null if unset)
13
- # tribunal_config_enabled # 0 if tribunal.enabled is true
14
13
  # tribunal_config_stop_hook_enabled # 0 if tribunal.stop_hook.enabled is true
15
14
  # tribunal_config_judge_model <judge_type>
16
15
  # # echoes per-judge-type model override,
@@ -73,13 +72,6 @@ tribunal_config_get_json() {
73
72
  printf '%s' "$_TRIBUNAL_CONFIG" | jq -c "${path}" 2>/dev/null
74
73
  }
75
74
 
76
- # Returns 0 if tribunal.enabled is true.
77
- tribunal_config_enabled() {
78
- local v
79
- v=$(tribunal_config_get '.tribunal.enabled')
80
- [[ "$v" == "true" ]]
81
- }
82
-
83
75
  # Returns 0 if tribunal.stop_hook.enabled is true. Default is false.
84
76
  tribunal_config_stop_hook_enabled() {
85
77
  local v
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "warden",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Untrusted-content gate. Scans content flowing in through WebFetch and Read for prompt-injection patterns, and when a threat is detected closes a session-scoped gate that blocks Write, Edit, and Bash until the user explicitly clears it. Grounded in Meta's Agents Rule of Two: an agent should hold no more than two of {private data, external actions, untrusted content} at once — warden removes the external-actions property while untrusted content is in play. Builds on the Onlooker ecosystem plugin.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.0](https://github.com/onlooker-community/ecosystem/compare/warden-v0.2.0...warden-v0.3.0) (2026-07-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * **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))
9
+
3
10
  ## [0.2.0](https://github.com/onlooker-community/ecosystem/compare/warden-v0.1.0...warden-v0.2.0) (2026-06-02)
4
11
 
5
12
 
@@ -36,18 +36,11 @@ Clean content (no signature) never reaches the model. Set `escalation.enabled: f
36
36
 
37
37
  ## Activation
38
38
 
39
- Warden is **off by default**. Enable per-project in `.claude/settings.json`:
39
+ Install the plugin in Claude from the marketplace with:
40
40
 
41
- ```json
42
- {
43
- "warden": {
44
- "enabled": true
45
- }
46
- }
47
41
  ```
48
-
49
- Or globally in `~/.claude/settings.json`.
50
-
42
+ /plugin install warden@onlooker-community
43
+ ```
51
44
  ## Configuration
52
45
 
53
46
  All keys are optional. Unset keys fall back to the plugin's `config.json` defaults.
@@ -55,7 +48,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
55
48
  ```json
56
49
  {
57
50
  "warden": {
58
- "enabled": false,
59
51
  "scan": {
60
52
  "sources": ["web_fetch", "file_read"],
61
53
  "max_content_chars": 20000,
@@ -88,7 +80,6 @@ All keys are optional. Unset keys fall back to the plugin's `config.json` defaul
88
80
 
89
81
  | Key | Default | Description |
90
82
  |-----|---------|-------------|
91
- | `enabled` | `false` | Must be `true` for any scanning or gating to run. |
92
83
  | `scan.sources` | `["web_fetch", "file_read"]` | Which ingestion sources to scan. Matches the schema's `source_type` enum. |
93
84
  | `scan.max_content_chars` | `20000` | Length cap on the content fed into detection. |
94
85
  | `scan.skip_globs` | lockfiles, `node_modules`, `.git`, `dist`, `build`, … | Globs whose reads are not scanned. |
@@ -2,7 +2,6 @@
2
2
  "plugin_name": "warden",
3
3
  "storage_path": "~/.onlooker",
4
4
  "warden": {
5
- "enabled": false,
6
5
  "scan": {
7
6
  "sources": ["web_fetch", "file_read"],
8
7
  "max_content_chars": 20000,
@@ -50,10 +50,6 @@ _done() { exit 0; }
50
50
 
51
51
  warden_config_load "$CWD"
52
52
 
53
- if ! warden_config_enabled; then
54
- _done
55
- fi
56
-
57
53
  [[ -z "$SESSION_ID" ]] && _done
58
54
 
59
55
  # If the gate is already closed, there is nothing more to do — it stays closed
@@ -35,10 +35,6 @@ export _HOOK_SESSION_ID="$SESSION_ID"
35
35
 
36
36
  warden_config_load "$CWD"
37
37
 
38
- if ! warden_config_enabled; then
39
- exit 0
40
- fi
41
-
42
38
  [[ -z "$SESSION_ID" ]] && exit 0
43
39
 
44
40
  # Gate open → allow silently.
@@ -2,8 +2,7 @@
2
2
  # Warden SessionStart hook.
3
3
  #
4
4
  # Fires at every session start. Responsibilities:
5
- # 1. Skip silently when warden.enabled is false.
6
- # 2. Ensure the session gate directory exists.
5
+ # 1. Ensure the session gate directory exists.
7
6
  #
8
7
  # A new session starts with the gate OPEN — the gate is session-scoped because
9
8
  # the threat model is untrusted content ingested into THIS session's context.
@@ -34,10 +33,6 @@ _done() { exit 0; }
34
33
 
35
34
  warden_config_load "$CWD"
36
35
 
37
- if ! warden_config_enabled; then
38
- _done
39
- fi
40
-
41
36
  [[ -z "$SESSION_ID" ]] && {
42
37
  printf 'warden-session-start: no session_id in hook input\n' >&2
43
38
  _done
@@ -10,7 +10,6 @@
10
10
  # warden_config_load <repo_root> # populates _WARDEN_CONFIG (JSON)
11
11
  # warden_config_get <jq-path> # echoes string value (empty if unset)
12
12
  # warden_config_get_json <jq-path> # echoes JSON value (null if unset)
13
- # warden_config_enabled # 0 if warden.enabled is true
14
13
 
15
14
  _WARDEN_CONFIG="{}"
16
15
 
@@ -70,10 +69,4 @@ warden_config_get() {
70
69
  warden_config_get_json() {
71
70
  local path="$1"
72
71
  printf '%s' "$_WARDEN_CONFIG" | jq -c "${path}" 2>/dev/null
73
- }
74
-
75
- warden_config_enabled() {
76
- local v
77
- v=$(warden_config_get '.warden.enabled')
78
- [[ "$v" == "true" ]]
79
- }
72
+ }
package/renovate.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": ["config:recommended", ":dependencyDashboard"],
4
+ "labels": ["dependencies"],
5
+ "schedule": ["before 5am on monday"],
6
+ "timezone": "UTC",
7
+ "lockFileMaintenance": {
8
+ "enabled": true,
9
+ "schedule": ["before 5am on the first day of the month"]
10
+ },
11
+ "packageRules": [
12
+ {
13
+ "description": "Group GitHub Actions updates",
14
+ "matchManagers": ["github-actions"],
15
+ "groupName": "GitHub Actions"
16
+ },
17
+ {
18
+ "description": "Group mise tool version updates",
19
+ "matchManagers": ["mise"],
20
+ "groupName": "mise tools"
21
+ },
22
+ {
23
+ "description": "Group npm devDependency updates",
24
+ "matchDepTypes": ["devDependencies"],
25
+ "groupName": "npm devDependencies"
26
+ },
27
+ {
28
+ "description": "Require dashboard approval for major devDependency bumps",
29
+ "matchDepTypes": ["devDependencies"],
30
+ "matchUpdateTypes": ["major"],
31
+ "dependencyDashboardApproval": true
32
+ }
33
+ ]
34
+ }
@@ -11,8 +11,8 @@ setup_file() {
11
11
  [ "$status" -eq 0 ]
12
12
  }
13
13
 
14
- @test "archivist config.json has plugin_name and archivist.enabled defaulting to false" {
15
- run jq -e '.plugin_name == "archivist" and .archivist.enabled == false' \
14
+ @test "archivist config.json has plugin_name field" {
15
+ run jq -e '.plugin_name == "archivist"' \
16
16
  "${REPO_ROOT}/plugins/archivist/config.json"
17
17
  [ "$status" -eq 0 ]
18
18
  }
@@ -10,31 +10,6 @@ setup() {
10
10
  source "${PLUGIN_ROOT}/scripts/lib/archivist-config.sh"
11
11
  }
12
12
 
13
- @test "config defaults from plugin config.json: disabled" {
14
- archivist_config_load ""
15
- run archivist_config_enabled
16
- [ "$status" -ne 0 ]
17
- }
18
-
19
- @test "user-level settings.json overlay can enable archivist" {
20
- mkdir -p "${HOME}/.claude"
21
- printf '%s\n' '{"archivist":{"enabled":true}}' > "${HOME}/.claude/settings.json"
22
- archivist_config_load ""
23
- run archivist_config_enabled
24
- [ "$status" -eq 0 ]
25
- }
26
-
27
- @test "repo-level settings.json overrides user-level" {
28
- mkdir -p "${HOME}/.claude"
29
- printf '%s\n' '{"archivist":{"enabled":true}}' > "${HOME}/.claude/settings.json"
30
- local repo="${BATS_TEST_TMPDIR}/repo"
31
- mkdir -p "${repo}/.claude"
32
- printf '%s\n' '{"archivist":{"enabled":false}}' > "${repo}/.claude/settings.json"
33
- archivist_config_load "$repo"
34
- run archivist_config_enabled
35
- [ "$status" -ne 0 ]
36
- }
37
-
38
13
  @test "injection.max_items defaults from config.json" {
39
14
  archivist_config_load ""
40
15
  local v
@@ -35,21 +35,9 @@ setup() {
35
35
  "updated_at": "2026-05-22T10:00:00Z"
36
36
  }' > "${kind_dir}/01TESTTESTTESTTESTTESTTEST.json"
37
37
 
38
- # Project-scoped settings.json that enables archivist.
39
- mkdir -p "${PROJECT_REPO}/.claude"
40
- printf '%s\n' '{"archivist":{"enabled":true}}' > "${PROJECT_REPO}/.claude/settings.json"
41
38
  }
42
39
 
43
- @test "inject hook is a no-op when archivist is disabled" {
44
- rm -f "${PROJECT_REPO}/.claude/settings.json"
45
- local input
46
- input=$(jq -n --arg cwd "$PROJECT_REPO" '{cwd: $cwd, source: "startup", session_id: "s"}')
47
- run bash -c "printf '%s' '$input' | '${PLUGIN_ROOT}/scripts/hooks/archivist-inject.sh'"
48
- [ "$status" -eq 0 ]
49
- echo "$output" | jq -e '.hookSpecificOutput.additionalContext == ""' >/dev/null
50
- }
51
-
52
- @test "inject hook emits seeded artifact when enabled" {
40
+ @test "inject hook emits seeded artifact" {
53
41
  local input
54
42
  input=$(jq -n --arg cwd "$PROJECT_REPO" '{cwd: $cwd, source: "startup", session_id: "s"}')
55
43
  run bash -c "printf '%s' '$input' | '${PLUGIN_ROOT}/scripts/hooks/archivist-inject.sh'"
@@ -14,19 +14,6 @@ setup() {
14
14
  mkdir -p "${REPO}/.claude"
15
15
  }
16
16
 
17
- @test "disabled by default (no settings)" {
18
- assayer_config_load "$REPO"
19
- run assayer_config_enabled
20
- [ "$status" -ne 0 ]
21
- }
22
-
23
- @test "enabled when settings opt in" {
24
- printf '%s\n' '{"assayer":{"enabled":true}}' >"${REPO}/.claude/settings.json"
25
- assayer_config_load "$REPO"
26
- run assayer_config_enabled
27
- [ "$status" -eq 0 ]
28
- }
29
-
30
17
  @test "default model is haiku" {
31
18
  assayer_config_load "$REPO"
32
19
  [ "$(assayer_config_model)" = "claude-haiku-4-5-20251001" ]
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Exercises the Assayer Stop hook's gating behavior. Does not invoke claude -p
4
4
  # (the hook bails before the extraction step when preconditions fail).
5
- # Verifies: disabled-by-default, no-git, recursion guard, no-transcript, and
5
+ # Verifies: no-git, recursion guard, no-transcript, and
6
6
  # stdout silence (advisory hook must never block Stop).
7
7
 
8
8
  setup() {
@@ -30,14 +30,6 @@ _make_input() {
30
30
  '{cwd: $cwd, session_id: $sid, transcript_path: $tp}'
31
31
  }
32
32
 
33
- @test "exits 0 silently when assayer.enabled is false (default)" {
34
- local input
35
- input=$(_make_input)
36
- run bash -c "printf '%s' '$input' | ONLOOKER_DIR='$ONLOOKER_DIR' '$HOOK'"
37
- [ "$status" -eq 0 ]
38
- [ -z "$output" ]
39
- }
40
-
41
33
  @test "exits 0 when cwd is not a git repo" {
42
34
  local non_repo="${BATS_TEST_TMPDIR}/not-a-repo"
43
35
  mkdir -p "$non_repo"
@@ -48,8 +40,6 @@ _make_input() {
48
40
  }
49
41
 
50
42
  @test "recursion guard: ASSAYER_NESTED=1 causes immediate exit 0" {
51
- mkdir -p "${REPO}/.claude"
52
- printf '%s\n' '{"assayer":{"enabled":true}}' >"${REPO}/.claude/settings.json"
53
43
  local input
54
44
  input=$(_make_input)
55
45
  run bash -c "printf '%s' '$input' | ASSAYER_NESTED=1 ONLOOKER_DIR='$ONLOOKER_DIR' '$HOOK'"
@@ -57,9 +47,7 @@ _make_input() {
57
47
  [ -z "$output" ]
58
48
  }
59
49
 
60
- @test "exits 0 when enabled but transcript is missing" {
61
- mkdir -p "${REPO}/.claude"
62
- printf '%s\n' '{"assayer":{"enabled":true}}' >"${REPO}/.claude/settings.json"
50
+ @test "exits 0 when transcript is missing" {
63
51
  local input
64
52
  input=$(_make_input "$REPO" "test-session" "${BATS_TEST_TMPDIR}/nope.jsonl")
65
53
  run bash -c "printf '%s' '$input' | ONLOOKER_DIR='$ONLOOKER_DIR' '$HOOK'"
@@ -67,9 +55,7 @@ _make_input() {
67
55
  [ -z "$output" ]
68
56
  }
69
57
 
70
- @test "exits 0 when enabled but final message is empty" {
71
- mkdir -p "${REPO}/.claude"
72
- printf '%s\n' '{"assayer":{"enabled":true}}' >"${REPO}/.claude/settings.json"
58
+ @test "exits 0 when final message is empty" {
73
59
  # Transcript with no assistant text turn.
74
60
  local empty_transcript="${BATS_TEST_TMPDIR}/empty.jsonl"
75
61
  printf '%s\n' '{"type":"user","message":{"content":[{"type":"text","text":"hi"}]}}' >"$empty_transcript"
@@ -10,31 +10,6 @@ setup() {
10
10
  source "${PLUGIN_ROOT}/scripts/lib/bursar-config.sh"
11
11
  }
12
12
 
13
- @test "bursar is disabled by default" {
14
- bursar_config_load ""
15
- run bursar_config_enabled
16
- [ "$status" -ne 0 ]
17
- }
18
-
19
- @test "user-level settings.json can enable bursar" {
20
- mkdir -p "${HOME}/.claude"
21
- printf '%s\n' '{"bursar":{"enabled":true}}' > "${HOME}/.claude/settings.json"
22
- bursar_config_load ""
23
- run bursar_config_enabled
24
- [ "$status" -eq 0 ]
25
- }
26
-
27
- @test "repo-level settings.json overrides user-level" {
28
- mkdir -p "${HOME}/.claude"
29
- printf '%s\n' '{"bursar":{"enabled":true}}' > "${HOME}/.claude/settings.json"
30
- local repo="${BATS_TEST_TMPDIR}/repo"
31
- mkdir -p "${repo}/.claude"
32
- printf '%s\n' '{"bursar":{"enabled":false}}' > "${repo}/.claude/settings.json"
33
- bursar_config_load "$repo"
34
- run bursar_config_enabled
35
- [ "$status" -ne 0 ]
36
- }
37
-
38
13
  @test "default window is rolling_7d" {
39
14
  bursar_config_load ""
40
15
  [ "$(bursar_config_window)" = "rolling_7d" ]
@@ -16,11 +16,6 @@ setup() {
16
16
  PK="projendabcd12"
17
17
  }
18
18
 
19
- _enable() {
20
- mkdir -p "${HOME}/.claude"
21
- printf '%s\n' '{"bursar":{"enabled":true}}' > "${HOME}/.claude/settings.json"
22
- }
23
-
24
19
  _breadcrumb() {
25
20
  local dir="${ONLOOKER_DIR}/bursar/sessions"
26
21
  mkdir -p "$dir"
@@ -44,7 +39,6 @@ _run_hook() {
44
39
  }
45
40
 
46
41
  @test "records a session's spend from governor.session.complete" {
47
- _enable
48
42
  _breadcrumb
49
43
  _seed_governor_event
50
44
  _run_hook
@@ -62,7 +56,6 @@ _run_hook() {
62
56
  }
63
57
 
64
58
  @test "removes the breadcrumb after recording" {
65
- _enable
66
59
  _breadcrumb
67
60
  _seed_governor_event
68
61
  _run_hook
@@ -70,7 +63,6 @@ _run_hook() {
70
63
  }
71
64
 
72
65
  @test "degrades to governor_present:false when no governor event exists" {
73
- _enable
74
66
  _breadcrumb
75
67
  # no governor.session.complete seeded
76
68
  _run_hook
@@ -84,7 +76,6 @@ _run_hook() {
84
76
  }
85
77
 
86
78
  @test "is idempotent across a repeated SessionEnd" {
87
- _enable
88
79
  _breadcrumb
89
80
  _seed_governor_event
90
81
  _run_hook
@@ -94,17 +85,7 @@ _run_hook() {
94
85
  [ "$(wc -l < "$(_ledger_path)")" -eq 1 ]
95
86
  }
96
87
 
97
- @test "writes nothing when bursar is disabled" {
98
- # bursar disabled (no settings written)
99
- _breadcrumb
100
- _seed_governor_event
101
- _run_hook
102
- [ "$status" -eq 0 ]
103
- [ ! -d "${ONLOOKER_DIR}/bursar/projects" ]
104
- }
105
-
106
88
  @test "keeps the breadcrumb and emits nothing when the ledger write fails" {
107
- _enable
108
89
  _breadcrumb
109
90
  _seed_governor_event
110
91
  # Force bursar_ledger_record to fail: a file where the projects dir must go,
@@ -121,7 +102,6 @@ _run_hook() {
121
102
  }
122
103
 
123
104
  @test "emits bursar.session.recorded" {
124
- _enable
125
105
  _breadcrumb
126
106
  _seed_governor_event
127
107
  _run_hook