@onlooker-community/ecosystem 0.33.0 → 0.33.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 (32) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.release-please-manifest.json +7 -7
  3. package/CHANGELOG.md +7 -0
  4. package/package.json +1 -1
  5. package/plugins/archivist/scripts/lib/archivist-config.sh +10 -34
  6. package/plugins/assayer/.claude-plugin/plugin.json +1 -1
  7. package/plugins/assayer/CHANGELOG.md +7 -0
  8. package/plugins/assayer/scripts/lib/assayer-config.sh +39 -62
  9. package/plugins/cartographer/scripts/lib/cartographer-config.sh +11 -29
  10. package/plugins/compass/scripts/lib/compass-config.sh +16 -46
  11. package/plugins/counsel/scripts/lib/counsel-config.sh +15 -46
  12. package/plugins/curator/.claude-plugin/plugin.json +1 -1
  13. package/plugins/curator/CHANGELOG.md +7 -0
  14. package/plugins/curator/scripts/lib/curator-config.sh +19 -44
  15. package/plugins/echo/scripts/lib/echo-config.sh +30 -59
  16. package/plugins/governor/scripts/lib/governor-config.sh +11 -41
  17. package/plugins/historian/scripts/lib/historian-config.sh +9 -33
  18. package/plugins/inspector/.claude-plugin/plugin.json +1 -1
  19. package/plugins/inspector/CHANGELOG.md +7 -0
  20. package/plugins/inspector/scripts/lib/inspector-config.sh +39 -63
  21. package/plugins/librarian/scripts/lib/librarian-config.sh +10 -34
  22. package/plugins/lineage/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lineage/CHANGELOG.md +7 -0
  24. package/plugins/lineage/scripts/lib/lineage-config.sh +17 -53
  25. package/plugins/scribe/.claude-plugin/plugin.json +1 -1
  26. package/plugins/scribe/CHANGELOG.md +7 -0
  27. package/plugins/scribe/scripts/lib/scribe-config.sh +17 -47
  28. package/plugins/tribunal/.claude-plugin/plugin.json +1 -1
  29. package/plugins/tribunal/CHANGELOG.md +7 -0
  30. package/plugins/tribunal/scripts/lib/tribunal-config.sh +25 -63
  31. package/plugins/warden/scripts/lib/warden-config.sh +17 -54
  32. package/scripts/lib/config-loader.sh +8 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecosystem",
3
- "version": "0.33.0",
3
+ "version": "0.33.1",
4
4
  "description": "Observability substrate for Claude Code. Provides the shared $ONLOOKER_DIR storage root (default $HOME/.onlooker), canonical schema-validated event emission, session and tool tracking hooks, and prompt rules. Required by all other Onlooker plugins.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,19 +1,19 @@
1
1
  {
2
- ".": "0.33.0",
2
+ ".": "0.33.1",
3
3
  "plugins/archivist": "0.3.1",
4
- "plugins/tribunal": "1.1.1",
4
+ "plugins/tribunal": "1.1.2",
5
5
  "plugins/echo": "0.3.1",
6
6
  "plugins/cartographer": "0.3.1",
7
7
  "plugins/governor": "0.3.2",
8
8
  "plugins/compass": "0.4.1",
9
- "plugins/scribe": "0.4.1",
9
+ "plugins/scribe": "0.4.2",
10
10
  "plugins/counsel": "0.5.1",
11
11
  "plugins/warden": "0.3.1",
12
12
  "plugins/librarian": "0.6.1",
13
- "plugins/curator": "0.2.1",
13
+ "plugins/curator": "0.2.2",
14
14
  "plugins/historian": "0.3.2",
15
- "plugins/assayer": "1.1.1",
15
+ "plugins/assayer": "1.1.2",
16
16
  "plugins/bursar": "0.3.0",
17
- "plugins/lineage": "0.2.1",
18
- "plugins/inspector": "0.3.1"
17
+ "plugins/lineage": "0.2.2",
18
+ "plugins/inspector": "0.3.2"
19
19
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.33.1](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.33.0...ecosystem-v0.33.1) (2026-08-02)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * restore config convenience functions & refactor execution plugins to shared loader ([#128](https://github.com/onlooker-community/ecosystem/issues/128)) ([4b3660c](https://github.com/onlooker-community/ecosystem/commit/4b3660c5a8b234187ec1e71c37b63e6a3d305c98))
9
+
3
10
  ## [0.33.0](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.32.2...ecosystem-v0.33.0) (2026-08-02)
4
11
 
5
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlooker-community/ecosystem",
3
- "version": "0.33.0",
3
+ "version": "0.33.1",
4
4
  "description": "Agents, skills, hooks, commands, rules, and MCP configurations that power [Onlooker](https://onlooker.dev)",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env bash
2
2
  # Config resolution for Archivist.
3
3
  #
4
- # Reads three layers, latest wins:
4
+ # Uses the shared config loader from ecosystem. Reads five layers, latest wins:
5
5
  # 1. plugins/archivist/config.json (defaults shipped with the plugin)
6
6
  # 2. ~/.claude/settings.json
7
- # 3. <repo>/.claude/settings.json
7
+ # 3. ~/.claude/settings.local.json (local overrides user)
8
+ # 4. <repo>/.claude/settings.json
9
+ # 5. <repo>/.claude/settings.local.json (local overrides project)
8
10
  #
9
11
  # Exposes:
10
12
  # archivist_config_load <repo_root> # populates _ARCHIVIST_CONFIG (JSON)
@@ -13,46 +15,20 @@
13
15
  # Settings overlay only touches the `archivist.*` subtree of settings.json so it
14
16
  # coexists with other plugins' configuration.
15
17
 
18
+ # shellcheck source=../../../scripts/lib/config-loader.sh
19
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
20
+
16
21
  _ARCHIVIST_CONFIG="{}"
17
22
 
18
23
  archivist_config_load() {
19
24
  local repo_root="${1:-}"
20
- local plugin_root="${CLAUDE_PLUGIN_ROOT:-}"
21
- local home_dir="${HOME:-}"
22
-
23
- local merged="{}"
24
- local file
25
-
26
- file="${plugin_root}/config.json"
27
- if [[ -f "$file" ]]; then
28
- local defaults
29
- defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
30
- merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
31
- || merged="$defaults"
32
- fi
33
-
34
- for file in "${home_dir}/.claude/settings.json" "${repo_root}/.claude/settings.json"; do
35
- [[ -n "$file" && -f "$file" ]] || continue
36
- local overlay
37
- overlay=$(jq '{ archivist: (.archivist // {}) }' "$file" 2>/dev/null) || continue
38
- [[ -z "$overlay" ]] && continue
39
- merged=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
40
- def deepmerge($a; $b):
41
- if ($a|type) == "object" and ($b|type) == "object" then
42
- reduce (($a|keys) + ($b|keys) | unique)[] as $k
43
- ({}; .[$k] = deepmerge($a[$k]; $b[$k]))
44
- elif $b == null then $a
45
- else $b end;
46
- deepmerge($a; $b)
47
- ' 2>/dev/null) || true
48
- done
49
-
50
- _ARCHIVIST_CONFIG="$merged"
25
+ config_load_plugin "archivist" "$repo_root" "_ARCHIVIST_CONFIG"
26
+ return 0
51
27
  }
52
28
 
53
29
  # Read a value from the loaded config. Usage:
54
30
  # archivist_config_get '.archivist.injection.max_items'
55
31
  archivist_config_get() {
56
32
  local path="$1"
57
- printf '%s' "$_ARCHIVIST_CONFIG" | jq -r "${path} // empty" 2>/dev/null
33
+ config_get "_ARCHIVIST_CONFIG" "${path}"
58
34
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assayer",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Claim verification. At session end, parses the agent's final message for testable claims (\"I ran the tests, they pass\", \"the build is green\") and checks each against the actual command results in the session transcript, classifying it corroborated, contradicted, or unverifiable. Catches lying-without-malice. Advisory by default. 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.2](https://github.com/onlooker-community/ecosystem/compare/assayer-v1.1.1...assayer-v1.1.2) (2026-08-02)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * restore config convenience functions & refactor execution plugins to shared loader ([#128](https://github.com/onlooker-community/ecosystem/issues/128)) ([4b3660c](https://github.com/onlooker-community/ecosystem/commit/4b3660c5a8b234187ec1e71c37b63e6a3d305c98))
9
+
3
10
  ## [1.1.1](https://github.com/onlooker-community/ecosystem/compare/assayer-v1.1.0...assayer-v1.1.1) (2026-08-01)
4
11
 
5
12
 
@@ -1,82 +1,59 @@
1
1
  #!/usr/bin/env bash
2
- # Config loading for Assayer.
3
- # Reads the repo's .claude/settings.json assayer.* keys, falling back to the
4
- # plugin's own config.json defaults.
5
-
6
- _ASSAYER_CONFIG_JSON=""
7
- _ASSAYER_PLUGIN_CONFIG_JSON=""
2
+ # Config resolution for assayer.
3
+ #
4
+ # Uses the shared config loader from ecosystem. Reads five layers, latest wins:
5
+ # 1. plugins/assayer/config.json (defaults shipped with the plugin)
6
+ # 2. ~/.claude/settings.json
7
+ # 3. ~/.claude/settings.local.json (local overrides user)
8
+ # 4. <repo>/.claude/settings.json
9
+ # 5. <repo>/.claude/settings.local.json (local overrides project)
10
+ #
11
+ # Exposes:
12
+ # assayer_config_load <repo_root> # populates _assayer_CONFIG (JSON)
13
+ # assayer_config_get <jq-path> # echoes string value (empty if unset)
14
+ # assayer_config_get_json <jq-path> # echoes JSON value (null if unset)
15
+
16
+ # shellcheck source=../../../scripts/lib/config-loader.sh
17
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
18
+
19
+ _assayer_CONFIG="{}"
8
20
 
9
21
  assayer_config_load() {
10
22
  local repo_root="${1:-}"
11
-
12
- _ASSAYER_PLUGIN_CONFIG_JSON=""
13
- local plugin_config="${CLAUDE_PLUGIN_ROOT:-}/config.json"
14
- if [[ -f "$plugin_config" ]]; then
15
- _ASSAYER_PLUGIN_CONFIG_JSON=$(cat "$plugin_config" 2>/dev/null) || _ASSAYER_PLUGIN_CONFIG_JSON=""
16
- fi
17
-
18
- _ASSAYER_CONFIG_JSON=""
19
- if [[ -n "$repo_root" ]]; then
20
- local settings_file="${repo_root}/.claude/settings.json"
21
- if [[ -f "$settings_file" ]]; then
22
- local settings
23
- settings=$(cat "$settings_file" 2>/dev/null) || settings=""
24
- local block
25
- block=$(printf '%s' "$settings" | jq -c '.assayer // empty' 2>/dev/null) || block=""
26
- [[ -n "$block" ]] && _ASSAYER_CONFIG_JSON="$block"
27
- fi
28
- fi
23
+ config_load_plugin "assayer" "$repo_root" "_assayer_CONFIG"
24
+ return 0
29
25
  }
30
26
 
31
- # Get a single scalar value. Checks settings.json first, then plugin config.json.
32
27
  assayer_config_get() {
33
- local key="$1"
34
-
35
- if [[ -n "$_ASSAYER_CONFIG_JSON" ]]; then
36
- local val
37
- val=$(printf '%s' "$_ASSAYER_CONFIG_JSON" | jq -r "${key} // empty" 2>/dev/null) || val=""
38
- [[ -n "$val" && "$val" != "null" ]] && {
39
- printf '%s' "$val"
40
- return 0
41
- }
42
- fi
43
-
44
- if [[ -n "$_ASSAYER_PLUGIN_CONFIG_JSON" ]]; then
45
- local val
46
- val=$(printf '%s' "$_ASSAYER_PLUGIN_CONFIG_JSON" | jq -r ".assayer${key} // empty" 2>/dev/null) || val=""
47
- [[ -n "$val" && "$val" != "null" ]] && {
48
- printf '%s' "$val"
49
- return 0
50
- }
51
- fi
28
+ local path="$1"
29
+ config_get "_assayer_CONFIG" "${path}"
52
30
  }
53
31
 
54
- assayer_config_model() {
55
- local val
56
- val=$(assayer_config_get '.evaluation.model')
57
- printf '%s' "${val:-claude-haiku-4-5-20251001}"
32
+ assayer_config_get_json() {
33
+ local path="$1"
34
+ config_get_json "_assayer_CONFIG" "${path}"
58
35
  }
59
36
 
60
- assayer_config_timeout() {
61
- local val
62
- val=$(assayer_config_get '.evaluation.timeout_seconds')
63
- printf '%s' "${val:-60}"
37
+ assayer_config_model() {
38
+ local v
39
+ v=$(assayer_config_get '.assayer.evaluation.model')
40
+ printf '%s' "${v:-claude-haiku-4-5-20251001}"
64
41
  }
65
42
 
66
43
  assayer_config_max_claims() {
67
- local val
68
- val=$(assayer_config_get '.max_claims')
69
- printf '%s' "${val:-12}"
44
+ local v
45
+ v=$(assayer_config_get '.assayer.max_claims')
46
+ printf '%s' "${v:-12}"
70
47
  }
71
48
 
72
49
  assayer_config_min_confidence() {
73
- local val
74
- val=$(assayer_config_get '.min_confidence')
75
- printf '%s' "${val:-0.5}"
50
+ local v
51
+ v=$(assayer_config_get '.assayer.min_confidence')
52
+ printf '%s' "${v:-0.5}"
76
53
  }
77
54
 
78
- assayer_config_final_message_chars() {
79
- local val
80
- val=$(assayer_config_get '.final_message_chars')
81
- printf '%s' "${val:-6000}"
55
+ assayer_config_timeout() {
56
+ local v
57
+ v=$(assayer_config_get '.assayer.evaluation.timeout_seconds')
58
+ printf '%s' "${v:-60}"
82
59
  }
@@ -1,54 +1,36 @@
1
1
  #!/usr/bin/env bash
2
2
  # cartographer-config.sh — load and query Cartographer configuration.
3
3
  #
4
- # Merges three layers in precedence order (later wins):
4
+ # Uses the shared config loader from ecosystem. Merges five layers in precedence order:
5
5
  # 1. plugins/cartographer/config.json (plugin defaults)
6
6
  # 2. ~/.claude/settings.json (.cartographer subtree)
7
- # 3. <repo>/.claude/settings.json (.cartographer subtree)
7
+ # 3. ~/.claude/settings.local.json (.cartographer subtree, local overrides user)
8
+ # 4. <repo>/.claude/settings.json (.cartographer subtree)
9
+ # 5. <repo>/.claude/settings.local.json (.cartographer subtree, local overrides project)
8
10
  #
9
11
  # Usage:
10
12
  # cartographer_config_load <repo_root>
11
13
  # cartographer_config_get_json ".cartographer.exclude_paths"
12
14
 
15
+ # shellcheck source=../../../scripts/lib/config-loader.sh
16
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
17
+
13
18
  _CARTOGRAPHER_CONFIG=""
14
- _CARTOGRAPHER_PLUGIN_CONFIG=""
15
19
 
16
20
  cartographer_config_load() {
17
21
  local repo_root="${1:-}"
18
- local plugin_dir
19
- plugin_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
20
- local plugin_config="$plugin_dir/config.json"
21
-
22
- _CARTOGRAPHER_PLUGIN_CONFIG="{}"
23
- if [[ -f "$plugin_config" ]]; then
24
- _CARTOGRAPHER_PLUGIN_CONFIG=$(cat "$plugin_config")
25
- fi
26
-
27
- local home_settings="{}"
28
- if [[ -f "$HOME/.claude/settings.json" ]]; then
29
- home_settings=$(cat "$HOME/.claude/settings.json")
30
- fi
31
-
32
- local repo_settings="{}"
33
- if [[ -n "$repo_root" && -f "$repo_root/.claude/settings.json" ]]; then
34
- repo_settings=$(cat "$repo_root/.claude/settings.json")
35
- fi
36
-
37
- _CARTOGRAPHER_CONFIG=$(jq -n \
38
- --argjson plugin "$_CARTOGRAPHER_PLUGIN_CONFIG" \
39
- --argjson home "$home_settings" \
40
- --argjson repo "$repo_settings" \
41
- '$plugin * {"cartographer": (($plugin.cartographer // {}) * ($home.cartographer // {}) * ($repo.cartographer // {}))}')
22
+ config_load_plugin "cartographer" "$repo_root" "_CARTOGRAPHER_CONFIG"
23
+ return 0
42
24
  }
43
25
 
44
26
  cartographer_config_get() {
45
27
  local path="${1:-}"
46
- printf '%s' "$_CARTOGRAPHER_CONFIG" | jq -r "$path // empty" 2>/dev/null
28
+ config_get "_CARTOGRAPHER_CONFIG" "${path}"
47
29
  }
48
30
 
49
31
  cartographer_config_get_json() {
50
32
  local path="${1:-}"
51
- printf '%s' "$_CARTOGRAPHER_CONFIG" | jq -c "$path // empty" 2>/dev/null
33
+ config_get_json "_CARTOGRAPHER_CONFIG" "${path}"
52
34
  }
53
35
 
54
36
  cartographer_config_model_extraction() {
@@ -1,65 +1,35 @@
1
1
  #!/usr/bin/env bash
2
- # Config resolution for Compass.
2
+ # Config resolution for compass.
3
3
  #
4
- # Reads three layers, latest wins:
4
+ # Uses the shared config loader from ecosystem. Reads five layers, latest wins:
5
5
  # 1. plugins/compass/config.json (defaults shipped with the plugin)
6
6
  # 2. ~/.claude/settings.json
7
- # 3. <repo>/.claude/settings.json
7
+ # 3. ~/.claude/settings.local.json (local overrides user)
8
+ # 4. <repo>/.claude/settings.json
9
+ # 5. <repo>/.claude/settings.local.json (local overrides project)
8
10
  #
9
11
  # Exposes:
10
- # compass_config_load <repo_root> # populates _COMPASS_CONFIG (JSON)
11
- # compass_config_get <jq-path> # echoes string value (empty if unset)
12
- # compass_config_get_json <jq-path> # echoes JSON value (null if unset)
12
+ # compass_config_load <repo_root> # populates _compass_CONFIG (JSON)
13
+ # compass_config_get <jq-path> # echoes string value (empty if unset)
14
+ # compass_config_get_json <jq-path> # echoes JSON value (null if unset)
13
15
 
14
- _COMPASS_CONFIG="{}"
16
+ # shellcheck source=../../../scripts/lib/config-loader.sh
17
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
18
+
19
+ _compass_CONFIG="{}"
15
20
 
16
21
  compass_config_load() {
17
22
  local repo_root="${1:-}"
18
- local plugin_root="${CLAUDE_PLUGIN_ROOT:-}"
19
- local home_dir="${HOME:-}"
20
-
21
- local merged="{}"
22
- local file
23
-
24
- file="${plugin_root}/config.json"
25
- if [[ -f "$file" ]]; then
26
- local defaults
27
- defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
28
- merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
29
- || merged="$defaults"
30
- fi
31
-
32
- local repo_settings=""
33
- [[ -n "$repo_root" ]] && repo_settings="${repo_root}/.claude/settings.json"
34
-
35
- for file in "${home_dir}/.claude/settings.json" "$repo_settings"; do
36
- [[ -n "$file" && -f "$file" ]] || continue
37
- local overlay
38
- overlay=$(jq '{ compass: (.compass // {}) }' "$file" 2>/dev/null) || continue
39
- [[ -z "$overlay" ]] && continue
40
- local attempt
41
- if attempt=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
42
- def deepmerge($a; $b):
43
- if ($a|type) == "object" and ($b|type) == "object" then
44
- reduce (($a|keys) + ($b|keys) | unique)[] as $k
45
- ({}; .[$k] = deepmerge($a[$k]; $b[$k]))
46
- elif $b == null then $a
47
- else $b end;
48
- deepmerge($a; $b)
49
- ' 2>/dev/null) && [[ -n "$attempt" ]]; then
50
- merged="$attempt"
51
- fi
52
- done
53
-
54
- _COMPASS_CONFIG="$merged"
23
+ config_load_plugin "compass" "$repo_root" "_compass_CONFIG"
24
+ return 0
55
25
  }
56
26
 
57
27
  compass_config_get() {
58
28
  local path="$1"
59
- printf '%s' "$_COMPASS_CONFIG" | jq -r "${path} // empty" 2>/dev/null
29
+ config_get "_compass_CONFIG" "${path}"
60
30
  }
61
31
 
62
32
  compass_config_get_json() {
63
33
  local path="$1"
64
- printf '%s' "$_COMPASS_CONFIG" | jq -c "${path}" 2>/dev/null
34
+ config_get_json "_compass_CONFIG" "${path}"
65
35
  }
@@ -1,66 +1,35 @@
1
1
  #!/usr/bin/env bash
2
- # Config resolution for Counsel.
2
+ # Config resolution for counsel.
3
3
  #
4
- # Three-layer merge, latest wins:
5
- # 1. plugins/counsel/config.json (plugin defaults)
4
+ # Uses the shared config loader from ecosystem. Reads five layers, latest wins:
5
+ # 1. plugins/counsel/config.json (defaults shipped with the plugin)
6
6
  # 2. ~/.claude/settings.json
7
- # 3. <repo>/.claude/settings.json
7
+ # 3. ~/.claude/settings.local.json (local overrides user)
8
+ # 4. <repo>/.claude/settings.json
9
+ # 5. <repo>/.claude/settings.local.json (local overrides project)
8
10
  #
9
11
  # Exposes:
10
- # counsel_config_load <repo_root> # populates _COUNSEL_CONFIG (JSON)
12
+ # counsel_config_load <repo_root> # populates _counsel_CONFIG (JSON)
11
13
  # counsel_config_get <jq-path> # echoes string value (empty if unset)
12
14
  # counsel_config_get_json <jq-path> # echoes JSON value (null if unset)
13
15
 
14
- _COUNSEL_CONFIG="{}"
16
+ # shellcheck source=../../../scripts/lib/config-loader.sh
17
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
18
+
19
+ _counsel_CONFIG="{}"
15
20
 
16
21
  counsel_config_load() {
17
22
  local repo_root="${1:-}"
18
- local plugin_root="${CLAUDE_PLUGIN_ROOT:-}"
19
- local home_dir="${HOME:-}"
20
-
21
- local merged="{}"
22
- local file
23
-
24
- file="${plugin_root}/config.json"
25
- if [[ -f "$file" ]]; then
26
- local defaults
27
- defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
28
- merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
29
- || merged="$defaults"
30
- fi
31
-
32
- local repo_settings=""
33
- [[ -n "$repo_root" ]] && repo_settings="${repo_root}/.claude/settings.json"
34
-
35
- for file in "${home_dir}/.claude/settings.json" "$repo_settings"; do
36
- [[ -n "$file" && -f "$file" ]] || continue
37
- local overlay
38
- overlay=$(jq '{ counsel: (.counsel // {}) }' "$file" 2>/dev/null) || continue
39
- [[ -z "$overlay" ]] && continue
40
- local attempt
41
- if attempt=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
42
- def deepmerge($a; $b):
43
- if ($a|type) == "object" and ($b|type) == "object" then
44
- reduce (($a|keys) + ($b|keys) | unique)[] as $k
45
- ({}; .[$k] = deepmerge($a[$k]; $b[$k]))
46
- elif $b == null then $a
47
- else $b end;
48
- deepmerge($a; $b)
49
- ' 2>/dev/null) && [[ -n "$attempt" ]]; then
50
- merged="$attempt"
51
- fi
52
- done
53
-
54
- _COUNSEL_CONFIG="$merged"
23
+ config_load_plugin "counsel" "$repo_root" "_counsel_CONFIG"
24
+ return 0
55
25
  }
56
26
 
57
27
  counsel_config_get() {
58
28
  local path="$1"
59
- printf '%s' "$_COUNSEL_CONFIG" | jq -r "${path} // empty" 2>/dev/null
29
+ config_get "_counsel_CONFIG" "${path}"
60
30
  }
61
31
 
62
32
  counsel_config_get_json() {
63
33
  local path="$1"
64
- printf '%s' "$_COUNSEL_CONFIG" | jq -c "${path}" 2>/dev/null
34
+ config_get_json "_counsel_CONFIG" "${path}"
65
35
  }
66
-
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "curator",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Maintenance layer for the user's typed auto-memory store. At every SessionStart, runs four cheap heuristic checks (date_decayed, path_broken, broken_index, orphaned_memory) against the memories at ~/.claude/projects/<encoded>/memory/ inside a wall-clock budget. Surfaces findings as a one-line pointer to /curator review; never edits the memory store directly. 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.2.2](https://github.com/onlooker-community/ecosystem/compare/curator-v0.2.1...curator-v0.2.2) (2026-08-02)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * restore config convenience functions & refactor execution plugins to shared loader ([#128](https://github.com/onlooker-community/ecosystem/issues/128)) ([4b3660c](https://github.com/onlooker-community/ecosystem/commit/4b3660c5a8b234187ec1e71c37b63e6a3d305c98))
9
+
3
10
  ## [0.2.1](https://github.com/onlooker-community/ecosystem/compare/curator-v0.2.0...curator-v0.2.1) (2026-08-01)
4
11
 
5
12
 
@@ -1,60 +1,35 @@
1
1
  #!/usr/bin/env bash
2
- # Config resolution for Curator.
2
+ # Config resolution for curator.
3
3
  #
4
- # Reads three layers, latest wins:
4
+ # Uses the shared config loader from ecosystem. Reads five layers, latest wins:
5
5
  # 1. plugins/curator/config.json (defaults shipped with the plugin)
6
6
  # 2. ~/.claude/settings.json
7
- # 3. <repo>/.claude/settings.json
7
+ # 3. ~/.claude/settings.local.json (local overrides user)
8
+ # 4. <repo>/.claude/settings.json
9
+ # 5. <repo>/.claude/settings.local.json (local overrides project)
8
10
  #
9
11
  # Exposes:
10
- # curator_config_load <repo_root> # populates _CURATOR_CONFIG (JSON)
12
+ # curator_config_load <repo_root> # populates _curator_CONFIG (JSON)
11
13
  # curator_config_get <jq-path> # echoes string value (empty if unset)
12
- #
13
- # Settings overlay only touches the `curator.*` subtree of settings.json.
14
+ # curator_config_get_json <jq-path> # echoes JSON value (null if unset)
15
+
16
+ # shellcheck source=../../../scripts/lib/config-loader.sh
17
+ source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
14
18
 
15
- _CURATOR_CONFIG="{}"
19
+ _curator_CONFIG="{}"
16
20
 
17
21
  curator_config_load() {
18
22
  local repo_root="${1:-}"
19
- local plugin_root="${CLAUDE_PLUGIN_ROOT:-}"
20
- local home_dir="${HOME:-}"
21
-
22
- local merged="{}"
23
- local file
24
-
25
- file="${plugin_root}/config.json"
26
- if [[ -f "$file" ]]; then
27
- local defaults
28
- defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
29
- merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
30
- || merged="$defaults"
31
- fi
32
-
33
- for file in "${home_dir}/.claude/settings.json" "${repo_root}/.claude/settings.json"; do
34
- [[ -n "$file" && -f "$file" ]] || continue
35
- local overlay
36
- overlay=$(jq '{ curator: (.curator // {}) }' "$file" 2>/dev/null) || continue
37
- [[ -z "$overlay" ]] && continue
38
- merged=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
39
- def deepmerge($a; $b):
40
- if ($a|type) == "object" and ($b|type) == "object" then
41
- reduce (($a|keys) + ($b|keys) | unique)[] as $k
42
- ({}; .[$k] = deepmerge($a[$k]; $b[$k]))
43
- elif $b == null then $a
44
- else $b end;
45
- deepmerge($a; $b)
46
- ' 2>/dev/null) || true
47
- done
48
-
49
- _CURATOR_CONFIG="$merged"
23
+ config_load_plugin "curator" "$repo_root" "_curator_CONFIG"
24
+ return 0
50
25
  }
51
26
 
52
27
  curator_config_get() {
53
28
  local path="$1"
54
- # The `// empty` operator treats `false` the same as null, so a
55
- # value of `false` would silently disappear and the caller would
56
- # misread "explicitly disabled" as "default to enabled". Use an
57
- # explicit null check so booleans round-trip correctly.
58
- printf '%s' "$_CURATOR_CONFIG" \
59
- | jq -r "${path} | if . == null then empty else . end" 2>/dev/null
29
+ config_get "_curator_CONFIG" "${path}"
30
+ }
31
+
32
+ curator_config_get_json() {
33
+ local path="$1"
34
+ config_get_json "_curator_CONFIG" "${path}"
60
35
  }