@onlooker-community/ecosystem 0.32.2 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/.release-please-manifest.json +9 -9
- package/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/plugins/archivist/scripts/lib/archivist-config.sh +10 -34
- package/plugins/assayer/.claude-plugin/plugin.json +1 -1
- package/plugins/assayer/CHANGELOG.md +7 -0
- package/plugins/assayer/scripts/lib/assayer-config.sh +39 -62
- package/plugins/bursar/.claude-plugin/plugin.json +1 -1
- package/plugins/bursar/CHANGELOG.md +12 -0
- package/plugins/bursar/scripts/hooks/bursar-session-end.sh +6 -5
- package/plugins/bursar/scripts/lib/bursar-config.sh +10 -43
- package/plugins/cartographer/scripts/lib/cartographer-config.sh +11 -29
- package/plugins/compass/scripts/lib/compass-config.sh +16 -46
- package/plugins/counsel/scripts/lib/counsel-config.sh +15 -46
- package/plugins/curator/.claude-plugin/plugin.json +1 -1
- package/plugins/curator/CHANGELOG.md +7 -0
- package/plugins/curator/scripts/lib/curator-config.sh +19 -44
- package/plugins/echo/scripts/lib/echo-config.sh +30 -59
- package/plugins/governor/scripts/lib/governor-config.sh +11 -41
- package/plugins/historian/scripts/lib/historian-config.sh +9 -33
- package/plugins/inspector/.claude-plugin/plugin.json +1 -1
- package/plugins/inspector/CHANGELOG.md +7 -0
- package/plugins/inspector/scripts/lib/inspector-config.sh +39 -63
- package/plugins/librarian/.claude-plugin/plugin.json +1 -1
- package/plugins/librarian/CHANGELOG.md +7 -0
- package/plugins/librarian/scripts/hooks/librarian-session-end.sh +38 -3
- package/plugins/librarian/scripts/lib/librarian-config.sh +10 -34
- package/plugins/lineage/.claude-plugin/plugin.json +1 -1
- package/plugins/lineage/CHANGELOG.md +7 -0
- package/plugins/lineage/scripts/lib/lineage-config.sh +17 -53
- package/plugins/scribe/.claude-plugin/plugin.json +1 -1
- package/plugins/scribe/CHANGELOG.md +7 -0
- package/plugins/scribe/scripts/lib/scribe-config.sh +17 -47
- package/plugins/tribunal/.claude-plugin/plugin.json +1 -1
- package/plugins/tribunal/CHANGELOG.md +7 -0
- package/plugins/tribunal/scripts/lib/tribunal-config.sh +25 -63
- package/plugins/warden/scripts/lib/warden-config.sh +17 -54
- package/scripts/lib/config-loader.sh +138 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Config resolution for Librarian.
|
|
3
3
|
#
|
|
4
|
-
# Reads
|
|
4
|
+
# Uses the shared config loader from ecosystem. Reads five layers, latest wins:
|
|
5
5
|
# 1. plugins/librarian/config.json (defaults shipped with the plugin)
|
|
6
6
|
# 2. ~/.claude/settings.json
|
|
7
|
-
# 3.
|
|
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
|
# librarian_config_load <repo_root> # populates _LIBRARIAN_CONFIG (JSON)
|
|
@@ -14,48 +16,22 @@
|
|
|
14
16
|
# Settings overlay only touches the `librarian.*` subtree of settings.json so
|
|
15
17
|
# it coexists with other plugins' configuration.
|
|
16
18
|
|
|
19
|
+
# shellcheck source=../../../scripts/lib/config-loader.sh
|
|
20
|
+
source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
|
|
21
|
+
|
|
17
22
|
_LIBRARIAN_CONFIG="{}"
|
|
18
23
|
|
|
19
24
|
librarian_config_load() {
|
|
20
25
|
local repo_root="${1:-}"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
local merged="{}"
|
|
25
|
-
local file
|
|
26
|
-
|
|
27
|
-
file="${plugin_root}/config.json"
|
|
28
|
-
if [[ -f "$file" ]]; then
|
|
29
|
-
local defaults
|
|
30
|
-
defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
|
|
31
|
-
merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
|
|
32
|
-
|| merged="$defaults"
|
|
33
|
-
fi
|
|
34
|
-
|
|
35
|
-
for file in "${home_dir}/.claude/settings.json" "${repo_root}/.claude/settings.json"; do
|
|
36
|
-
[[ -n "$file" && -f "$file" ]] || continue
|
|
37
|
-
local overlay
|
|
38
|
-
overlay=$(jq '{ librarian: (.librarian // {}) }' "$file" 2>/dev/null) || continue
|
|
39
|
-
[[ -z "$overlay" ]] && continue
|
|
40
|
-
merged=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
|
|
41
|
-
def deepmerge($a; $b):
|
|
42
|
-
if ($a|type) == "object" and ($b|type) == "object" then
|
|
43
|
-
reduce (($a|keys) + ($b|keys) | unique)[] as $k
|
|
44
|
-
({}; .[$k] = deepmerge($a[$k]; $b[$k]))
|
|
45
|
-
elif $b == null then $a
|
|
46
|
-
else $b end;
|
|
47
|
-
deepmerge($a; $b)
|
|
48
|
-
' 2>/dev/null) || true
|
|
49
|
-
done
|
|
50
|
-
|
|
51
|
-
_LIBRARIAN_CONFIG="$merged"
|
|
26
|
+
config_load_plugin "librarian" "$repo_root" "_LIBRARIAN_CONFIG"
|
|
27
|
+
return 0
|
|
52
28
|
}
|
|
53
29
|
|
|
54
30
|
# Read a value from the loaded config. Usage:
|
|
55
31
|
# librarian_config_get '.librarian.surfacer.max_pending_for_inject'
|
|
56
32
|
librarian_config_get() {
|
|
57
33
|
local path="$1"
|
|
58
|
-
|
|
34
|
+
config_get "_LIBRARIAN_CONFIG" "${path}"
|
|
59
35
|
}
|
|
60
36
|
|
|
61
37
|
# Returns 0 if librarian.auto_promote is true, 1 otherwise.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lineage",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Per-change provenance for the Onlooker ecosystem. Records session/turn metadata plus a secret-redacted, size-capped snippet for every Edit/Write/MultiEdit at PostToolUse, then answers \"why does this line exist?\" via /lineage by joining change records to historian-preserved transcripts. Emits lineage.* events for audit. Builds on the Onlooker ecosystem plugin.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Onlooker Community",
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.2](https://github.com/onlooker-community/ecosystem/compare/lineage-v0.2.1...lineage-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/lineage-v0.2.0...lineage-v0.2.1) (2026-08-01)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,71 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Config resolution for lineage.
|
|
3
3
|
#
|
|
4
|
-
# Reads
|
|
4
|
+
# Uses the shared config loader from ecosystem. Reads five layers, latest wins:
|
|
5
5
|
# 1. plugins/lineage/config.json (defaults shipped with the plugin)
|
|
6
6
|
# 2. ~/.claude/settings.json
|
|
7
|
-
# 3.
|
|
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
|
-
# lineage_config_load <repo_root>
|
|
11
|
-
# lineage_config_get <jq-path>
|
|
12
|
-
# lineage_config_get_json <jq-path>
|
|
13
|
-
# lineage_config_max_snippet_chars # echoes the snippet cap (default 4000)
|
|
14
|
-
# lineage_config_redact_enabled # 0 unless redact_secrets is false
|
|
15
|
-
# lineage_config_prompt_source # echoes the prompt-source strategy
|
|
16
|
-
# lineage_config_ignore_globs # echoes ignore globs, one per line
|
|
12
|
+
# lineage_config_load <repo_root> # populates _lineage_CONFIG (JSON)
|
|
13
|
+
# lineage_config_get <jq-path> # echoes string value (empty if unset)
|
|
14
|
+
# lineage_config_get_json <jq-path> # echoes JSON value (null if unset)
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
# shellcheck source=../../../scripts/lib/config-loader.sh
|
|
17
|
+
source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
|
|
18
|
+
|
|
19
|
+
_lineage_CONFIG="{}"
|
|
19
20
|
|
|
20
21
|
lineage_config_load() {
|
|
21
22
|
local repo_root="${1:-}"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
local merged="{}"
|
|
26
|
-
local file
|
|
27
|
-
|
|
28
|
-
file="${plugin_root}/config.json"
|
|
29
|
-
if [[ -f "$file" ]]; then
|
|
30
|
-
local defaults
|
|
31
|
-
defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
|
|
32
|
-
merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
|
|
33
|
-
|| merged="$defaults"
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
local repo_settings=""
|
|
37
|
-
[[ -n "$repo_root" ]] && repo_settings="${repo_root}/.claude/settings.json"
|
|
38
|
-
|
|
39
|
-
for file in "${home_dir}/.claude/settings.json" "$repo_settings"; do
|
|
40
|
-
[[ -n "$file" && -f "$file" ]] || continue
|
|
41
|
-
local overlay
|
|
42
|
-
overlay=$(jq '{ lineage: (.lineage // {}) }' "$file" 2>/dev/null) || continue
|
|
43
|
-
[[ -z "$overlay" ]] && continue
|
|
44
|
-
local attempt
|
|
45
|
-
if attempt=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
|
|
46
|
-
def deepmerge($a; $b):
|
|
47
|
-
if ($a|type) == "object" and ($b|type) == "object" then
|
|
48
|
-
reduce (($a|keys) + ($b|keys) | unique)[] as $k
|
|
49
|
-
({}; .[$k] = deepmerge($a[$k]; $b[$k]))
|
|
50
|
-
elif $b == null then $a
|
|
51
|
-
else $b end;
|
|
52
|
-
deepmerge($a; $b)
|
|
53
|
-
' 2>/dev/null) && [[ -n "$attempt" ]]; then
|
|
54
|
-
merged="$attempt"
|
|
55
|
-
fi
|
|
56
|
-
done
|
|
57
|
-
|
|
58
|
-
_LINEAGE_CONFIG="$merged"
|
|
23
|
+
config_load_plugin "lineage" "$repo_root" "_lineage_CONFIG"
|
|
24
|
+
return 0
|
|
59
25
|
}
|
|
60
26
|
|
|
61
27
|
lineage_config_get() {
|
|
62
28
|
local path="$1"
|
|
63
|
-
|
|
29
|
+
config_get "_lineage_CONFIG" "${path}"
|
|
64
30
|
}
|
|
65
31
|
|
|
66
32
|
lineage_config_get_json() {
|
|
67
33
|
local path="$1"
|
|
68
|
-
|
|
34
|
+
config_get_json "_lineage_CONFIG" "${path}"
|
|
69
35
|
}
|
|
70
36
|
|
|
71
37
|
lineage_config_max_snippet_chars() {
|
|
@@ -75,10 +41,8 @@ lineage_config_max_snippet_chars() {
|
|
|
75
41
|
}
|
|
76
42
|
|
|
77
43
|
lineage_config_redact_enabled() {
|
|
78
|
-
# Default on. jq's `//` treats a literal `false` as empty, so read the raw
|
|
79
|
-
# JSON value and only disable on an explicit false.
|
|
80
44
|
local v
|
|
81
|
-
v=$(
|
|
45
|
+
v=$(lineage_config_get '.lineage.redact_secrets')
|
|
82
46
|
[[ "$v" != "false" ]]
|
|
83
47
|
}
|
|
84
48
|
|
|
@@ -89,5 +53,5 @@ lineage_config_prompt_source() {
|
|
|
89
53
|
}
|
|
90
54
|
|
|
91
55
|
lineage_config_ignore_globs() {
|
|
92
|
-
|
|
56
|
+
lineage_config_get_json '.lineage.ignore_globs // ["**/.git/**","**/node_modules/**","**/dist/**","**/*.lock"]' | jq -r '.[]'
|
|
93
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scribe",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Intent documentation from agent activity. Captures why changes were made — problem context, decisions, tradeoffs — and distills them into readable artifacts at session end.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Onlooker Community",
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.2](https://github.com/onlooker-community/ecosystem/compare/scribe-v0.4.1...scribe-v0.4.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.4.1](https://github.com/onlooker-community/ecosystem/compare/scribe-v0.4.0...scribe-v0.4.1) (2026-08-01)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,65 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Config resolution for
|
|
2
|
+
# Config resolution for scribe.
|
|
3
3
|
#
|
|
4
|
-
# Reads
|
|
4
|
+
# Uses the shared config loader from ecosystem. Reads five layers, latest wins:
|
|
5
5
|
# 1. plugins/scribe/config.json (defaults shipped with the plugin)
|
|
6
6
|
# 2. ~/.claude/settings.json
|
|
7
|
-
# 3.
|
|
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
|
-
# scribe_config_load <repo_root>
|
|
11
|
-
# scribe_config_get <jq-path>
|
|
12
|
-
# scribe_config_get_json <jq-path>
|
|
12
|
+
# scribe_config_load <repo_root> # populates _scribe_CONFIG (JSON)
|
|
13
|
+
# scribe_config_get <jq-path> # echoes string value (empty if unset)
|
|
14
|
+
# scribe_config_get_json <jq-path> # echoes JSON value (null if unset)
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
# shellcheck source=../../../scripts/lib/config-loader.sh
|
|
17
|
+
source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
|
|
18
|
+
|
|
19
|
+
_scribe_CONFIG="{}"
|
|
15
20
|
|
|
16
21
|
scribe_config_load() {
|
|
17
22
|
local repo_root="${1:-}"
|
|
18
|
-
|
|
19
|
-
|
|
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 '{ scribe: (.scribe // {}) }' "$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
|
-
_SCRIBE_CONFIG="$merged"
|
|
23
|
+
config_load_plugin "scribe" "$repo_root" "_scribe_CONFIG"
|
|
24
|
+
return 0
|
|
55
25
|
}
|
|
56
26
|
|
|
57
27
|
scribe_config_get() {
|
|
58
28
|
local path="$1"
|
|
59
|
-
|
|
29
|
+
config_get "_scribe_CONFIG" "${path}"
|
|
60
30
|
}
|
|
61
31
|
|
|
62
32
|
scribe_config_get_json() {
|
|
63
33
|
local path="$1"
|
|
64
|
-
|
|
65
|
-
}
|
|
34
|
+
config_get_json "_scribe_CONFIG" "${path}"
|
|
35
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tribunal",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
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.2](https://github.com/onlooker-community/ecosystem/compare/tribunal-v1.1.1...tribunal-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/tribunal-v1.1.0...tribunal-v1.1.1) (2026-08-01)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,93 +1,55 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Config resolution for
|
|
2
|
+
# Config resolution for tribunal.
|
|
3
3
|
#
|
|
4
|
-
# Reads
|
|
4
|
+
# Uses the shared config loader from ecosystem. Reads five layers, latest wins:
|
|
5
5
|
# 1. plugins/tribunal/config.json (defaults shipped with the plugin)
|
|
6
6
|
# 2. ~/.claude/settings.json
|
|
7
|
-
# 3.
|
|
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
|
-
# tribunal_config_load <repo_root>
|
|
11
|
-
# tribunal_config_get <jq-path>
|
|
12
|
-
# tribunal_config_get_json <jq-path>
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
# # falling back to tribunal.judges.model
|
|
17
|
-
#
|
|
18
|
-
# Settings overlay only touches the `tribunal.*` subtree so this plugin coexists
|
|
19
|
-
# with other plugins' configuration.
|
|
12
|
+
# tribunal_config_load <repo_root> # populates _tribunal_CONFIG (JSON)
|
|
13
|
+
# tribunal_config_get <jq-path> # echoes string value (empty if unset)
|
|
14
|
+
# tribunal_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"
|
|
20
18
|
|
|
21
19
|
_TRIBUNAL_CONFIG="{}"
|
|
22
20
|
|
|
23
21
|
tribunal_config_load() {
|
|
24
22
|
local repo_root="${1:-}"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
local merged="{}"
|
|
29
|
-
local file
|
|
30
|
-
|
|
31
|
-
file="${plugin_root}/config.json"
|
|
32
|
-
if [[ -f "$file" ]]; then
|
|
33
|
-
local defaults
|
|
34
|
-
defaults=$(jq '.' "$file" 2>/dev/null) || defaults="{}"
|
|
35
|
-
merged=$(jq -n --argjson a "$merged" --argjson b "$defaults" '$a * $b' 2>/dev/null) \
|
|
36
|
-
|| merged="$defaults"
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
for file in "${home_dir}/.claude/settings.json" "${repo_root}/.claude/settings.json"; do
|
|
40
|
-
[[ -n "$file" && -f "$file" ]] || continue
|
|
41
|
-
local overlay
|
|
42
|
-
overlay=$(jq '{ tribunal: (.tribunal // {}) }' "$file" 2>/dev/null) || continue
|
|
43
|
-
[[ -z "$overlay" ]] && continue
|
|
44
|
-
local attempt
|
|
45
|
-
if attempt=$(jq -n --argjson a "$merged" --argjson b "$overlay" '
|
|
46
|
-
def deepmerge($a; $b):
|
|
47
|
-
if ($a|type) == "object" and ($b|type) == "object" then
|
|
48
|
-
reduce (($a|keys) + ($b|keys) | unique)[] as $k
|
|
49
|
-
({}; .[$k] = deepmerge($a[$k]; $b[$k]))
|
|
50
|
-
elif $b == null then $a
|
|
51
|
-
else $b end;
|
|
52
|
-
deepmerge($a; $b)
|
|
53
|
-
' 2>/dev/null) && [[ -n "$attempt" ]]; then
|
|
54
|
-
merged="$attempt"
|
|
55
|
-
fi
|
|
56
|
-
done
|
|
57
|
-
|
|
58
|
-
_TRIBUNAL_CONFIG="$merged"
|
|
23
|
+
config_load_plugin "tribunal" "$repo_root" "_TRIBUNAL_CONFIG"
|
|
24
|
+
return 0
|
|
59
25
|
}
|
|
60
26
|
|
|
61
|
-
# Read a string value from the loaded config.
|
|
62
|
-
# Usage: tribunal_config_get '.tribunal.session.gate_policy'
|
|
63
27
|
tribunal_config_get() {
|
|
64
28
|
local path="$1"
|
|
65
|
-
|
|
29
|
+
config_get "_TRIBUNAL_CONFIG" "${path}"
|
|
66
30
|
}
|
|
67
31
|
|
|
68
|
-
# Read a JSON value (arrays, objects, numbers) from the loaded config.
|
|
69
|
-
# Usage: tribunal_config_get_json '.tribunal.session.judge_types'
|
|
70
32
|
tribunal_config_get_json() {
|
|
71
33
|
local path="$1"
|
|
72
|
-
|
|
34
|
+
config_get_json "_TRIBUNAL_CONFIG" "${path}"
|
|
73
35
|
}
|
|
74
36
|
|
|
75
|
-
# Returns 0 if tribunal.stop_hook.enabled is true. Default is false.
|
|
76
37
|
tribunal_config_stop_hook_enabled() {
|
|
77
38
|
local v
|
|
78
39
|
v=$(tribunal_config_get '.tribunal.stop_hook.enabled')
|
|
79
40
|
[[ "$v" == "true" ]]
|
|
80
41
|
}
|
|
81
42
|
|
|
82
|
-
# Resolve the model id for a given judge_type.
|
|
83
|
-
# Precedence: tribunal.judges.<type>.model > tribunal.judges.model
|
|
84
43
|
tribunal_config_judge_model() {
|
|
85
|
-
local judge_type="$1"
|
|
86
|
-
local
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
44
|
+
local judge_type="${1:-}"
|
|
45
|
+
local v
|
|
46
|
+
if [[ -n "$judge_type" ]]; then
|
|
47
|
+
v=$(tribunal_config_get ".tribunal.judges.\"$judge_type\".model")
|
|
48
|
+
if [[ -n "$v" ]]; then
|
|
49
|
+
printf '%s' "$v"
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
91
52
|
fi
|
|
92
|
-
tribunal_config_get '.tribunal.judges.model'
|
|
53
|
+
v=$(tribunal_config_get '.tribunal.judges.model')
|
|
54
|
+
printf '%s' "${v:-claude-opus-4-7}"
|
|
93
55
|
}
|
|
@@ -1,72 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Config resolution for
|
|
2
|
+
# Config resolution for warden.
|
|
3
3
|
#
|
|
4
|
-
# Reads
|
|
4
|
+
# Uses the shared config loader from ecosystem. Reads five layers, latest wins:
|
|
5
5
|
# 1. plugins/warden/config.json (defaults shipped with the plugin)
|
|
6
6
|
# 2. ~/.claude/settings.json
|
|
7
|
-
# 3.
|
|
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
|
-
# warden_config_load <repo_root>
|
|
11
|
-
# warden_config_get <jq-path>
|
|
12
|
-
# warden_config_get_json <jq-path>
|
|
12
|
+
# warden_config_load <repo_root> # populates _warden_CONFIG (JSON)
|
|
13
|
+
# warden_config_get <jq-path> # echoes string value (empty if unset)
|
|
14
|
+
# warden_config_get_json <jq-path> # echoes JSON value (null if unset)
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
# shellcheck source=../../../scripts/lib/config-loader.sh
|
|
17
|
+
source "${PLUGIN_ROOT}/../../scripts/lib/config-loader.sh"
|
|
18
|
+
|
|
19
|
+
_warden_CONFIG="{}"
|
|
15
20
|
|
|
16
21
|
warden_config_load() {
|
|
17
22
|
local repo_root="${1:-}"
|
|
18
|
-
|
|
19
|
-
|
|
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 '{ warden: (.warden // {}) }' "$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
|
-
_WARDEN_CONFIG="$merged"
|
|
23
|
+
config_load_plugin "warden" "$repo_root" "_warden_CONFIG"
|
|
24
|
+
return 0
|
|
55
25
|
}
|
|
56
26
|
|
|
57
27
|
warden_config_get() {
|
|
58
28
|
local path="$1"
|
|
59
|
-
|
|
60
|
-
# empty, so a `false` boolean would read back as "" and a `${v:-true}`
|
|
61
|
-
# default would silently flip it to true. Emit the raw value and map only a
|
|
62
|
-
# literal JSON null to the empty string.
|
|
63
|
-
local v
|
|
64
|
-
v=$(printf '%s' "$_WARDEN_CONFIG" | jq -r "${path}" 2>/dev/null) || return 1
|
|
65
|
-
[[ "$v" == "null" ]] && v=""
|
|
66
|
-
printf '%s' "$v"
|
|
29
|
+
config_get "_warden_CONFIG" "${path}"
|
|
67
30
|
}
|
|
68
31
|
|
|
69
32
|
warden_config_get_json() {
|
|
70
33
|
local path="$1"
|
|
71
|
-
|
|
72
|
-
}
|
|
34
|
+
config_get_json "_warden_CONFIG" "${path}"
|
|
35
|
+
}
|