@onlooker-community/ecosystem 0.15.2 → 0.17.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.
- package/.claude-plugin/marketplace.json +39 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.release-please-manifest.json +5 -2
- package/CHANGELOG.md +15 -0
- package/CLAUDE.md +88 -0
- package/package.json +3 -3
- package/plugins/compass/.claude-plugin/plugin.json +14 -0
- package/plugins/compass/CHANGELOG.md +8 -0
- package/plugins/compass/config.json +71 -0
- package/plugins/compass/docs/adr/001-evaluate-prompts-in-context.md +82 -0
- package/plugins/compass/docs/design.md +421 -0
- package/plugins/compass/hooks/hooks.json +82 -0
- package/plugins/compass/scripts/hooks/compass-bash-gate.sh +95 -0
- package/plugins/compass/scripts/hooks/compass-pre-tool-use.sh +86 -0
- package/plugins/compass/scripts/hooks/compass-record-write.sh +97 -0
- package/plugins/compass/scripts/hooks/compass-session-start.sh +77 -0
- package/plugins/compass/scripts/lib/compass-config.sh +72 -0
- package/plugins/compass/scripts/lib/compass-evaluator.sh +374 -0
- package/plugins/compass/scripts/lib/compass-events.sh +81 -0
- package/plugins/compass/scripts/lib/compass-gate.sh +465 -0
- package/plugins/compass/scripts/lib/compass-sanitizer.sh +82 -0
- package/plugins/compass/scripts/lib/compass-transcript.sh +135 -0
- package/plugins/governor/.claude-plugin/plugin.json +14 -0
- package/plugins/governor/CHANGELOG.md +22 -0
- package/plugins/governor/config.json +19 -0
- package/plugins/governor/hooks/hooks.json +48 -0
- package/plugins/governor/scripts/hooks/governor-post-tool-use.sh +147 -0
- package/plugins/governor/scripts/hooks/governor-pre-tool-use.sh +199 -0
- package/plugins/governor/scripts/hooks/governor-session-start.sh +109 -0
- package/plugins/governor/scripts/hooks/governor-stop.sh +108 -0
- package/plugins/governor/scripts/lib/governor-config.sh +79 -0
- package/plugins/governor/scripts/lib/governor-estimate.sh +116 -0
- package/plugins/governor/scripts/lib/governor-events.sh +81 -0
- package/plugins/governor/scripts/lib/governor-ledger.sh +172 -0
- package/plugins/scribe/.claude-plugin/plugin.json +12 -0
- package/plugins/scribe/CHANGELOG.md +8 -0
- package/plugins/scribe/config.json +20 -0
- package/plugins/scribe/hooks/hooks.json +37 -0
- package/plugins/scribe/scripts/hooks/scribe-capture.sh +76 -0
- package/plugins/scribe/scripts/hooks/scribe-session-start.sh +58 -0
- package/plugins/scribe/scripts/hooks/scribe-stop.sh +67 -0
- package/plugins/scribe/scripts/lib/scribe-config.sh +72 -0
- package/plugins/scribe/scripts/lib/scribe-distill.sh +239 -0
- package/plugins/scribe/scripts/lib/scribe-events.sh +80 -0
- package/plugins/scribe/scripts/lib/scribe-extract.sh +147 -0
- package/plugins/scribe/scripts/lib/scribe-project-key.sh +89 -0
- package/plugins/scribe/scripts/lib/scribe-ulid.sh +50 -0
- package/release-please-config.json +48 -0
- package/test/bats/governor-config.bats +106 -0
- package/test/bats/governor-estimate.bats +86 -0
- package/test/bats/governor-events.bats +238 -0
- package/test/bats/governor-ledger.bats +220 -0
- package/test/bats/scribe-extract.bats +102 -0
- package/test/bats/scribe-project-key.bats +75 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
setup() {
|
|
4
|
+
source "${BATS_TEST_DIRNAME}/../helpers/setup.bash"
|
|
5
|
+
setup_test_env
|
|
6
|
+
|
|
7
|
+
PLUGIN_ROOT="${REPO_ROOT}/plugins/governor"
|
|
8
|
+
export CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT"
|
|
9
|
+
export ONLOOKER_EVENTS_LOG="${ONLOOKER_DIR}/logs/onlooker-events.jsonl"
|
|
10
|
+
mkdir -p "$(dirname "$ONLOOKER_EVENTS_LOG")"
|
|
11
|
+
|
|
12
|
+
export _ONLOOKER_EVENT_JS="${REPO_ROOT}/scripts/lib/onlooker-event.mjs"
|
|
13
|
+
export CLAUDE_SESSION_ID="bats-ledger-$$"
|
|
14
|
+
|
|
15
|
+
# shellcheck disable=SC1091
|
|
16
|
+
source "${REPO_ROOT}/scripts/lib/portable-lock.sh"
|
|
17
|
+
# shellcheck disable=SC1091
|
|
18
|
+
source "${PLUGIN_ROOT}/scripts/lib/governor-config.sh"
|
|
19
|
+
# shellcheck disable=SC1091
|
|
20
|
+
source "${PLUGIN_ROOT}/scripts/lib/governor-events.sh"
|
|
21
|
+
# shellcheck disable=SC1091
|
|
22
|
+
source "${PLUGIN_ROOT}/scripts/lib/governor-ledger.sh"
|
|
23
|
+
|
|
24
|
+
export ONLOOKER_DIR="${TEST_HOME}/.onlooker"
|
|
25
|
+
SID="ledger-test-session-$$"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_make_record() {
|
|
29
|
+
local tokens="${1:-1000}"
|
|
30
|
+
local cost="${2:-0.009}"
|
|
31
|
+
jq -n \
|
|
32
|
+
--arg ts "2026-01-01T00:00:00Z" \
|
|
33
|
+
--arg sid "$SID" \
|
|
34
|
+
--arg aid "test-agent" \
|
|
35
|
+
--argjson est "$tokens" \
|
|
36
|
+
--argjson cost "$cost" \
|
|
37
|
+
'{
|
|
38
|
+
ts: $ts,
|
|
39
|
+
session_id: $sid,
|
|
40
|
+
agent_id: $aid,
|
|
41
|
+
agent_type: "Task",
|
|
42
|
+
estimated_tokens: $est,
|
|
43
|
+
cost_usd_estimated: $cost,
|
|
44
|
+
duration_ms: 1000
|
|
45
|
+
}'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_make_reservation() {
|
|
49
|
+
local tokens="${1:-1000}"
|
|
50
|
+
local cost="${2:-0.009}"
|
|
51
|
+
jq -n \
|
|
52
|
+
--arg ts "2026-01-01T00:00:00Z" \
|
|
53
|
+
--arg sid "$SID" \
|
|
54
|
+
--arg aid "test-agent" \
|
|
55
|
+
--argjson est "$tokens" \
|
|
56
|
+
--argjson cost "$cost" \
|
|
57
|
+
'{
|
|
58
|
+
ts: $ts,
|
|
59
|
+
session_id: $sid,
|
|
60
|
+
agent_id: $aid,
|
|
61
|
+
agent_type: "Task",
|
|
62
|
+
estimated_tokens: $est,
|
|
63
|
+
cost_usd_estimated: $cost,
|
|
64
|
+
record_type: "reservation"
|
|
65
|
+
}'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
_make_completion() {
|
|
69
|
+
local neg_tokens="${1:--1000}"
|
|
70
|
+
local actual_tokens="${2:-900}"
|
|
71
|
+
local cost="${3:-0.009}"
|
|
72
|
+
jq -n \
|
|
73
|
+
--arg ts "2026-01-01T00:00:00Z" \
|
|
74
|
+
--arg sid "$SID" \
|
|
75
|
+
--arg aid "test-agent" \
|
|
76
|
+
--argjson est "$neg_tokens" \
|
|
77
|
+
--argjson actual "$actual_tokens" \
|
|
78
|
+
--argjson cost "$cost" \
|
|
79
|
+
'{
|
|
80
|
+
ts: $ts,
|
|
81
|
+
session_id: $sid,
|
|
82
|
+
agent_id: $aid,
|
|
83
|
+
agent_type: "Task",
|
|
84
|
+
estimated_tokens: $est,
|
|
85
|
+
actual_tokens: $actual,
|
|
86
|
+
cost_usd_estimated: $cost,
|
|
87
|
+
duration_ms: 1500
|
|
88
|
+
}'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@test "governor_ledger_path returns a .jsonl path under ONLOOKER_DIR" {
|
|
92
|
+
local p
|
|
93
|
+
p=$(governor_ledger_path "test-session")
|
|
94
|
+
[[ "$p" == *".jsonl" ]]
|
|
95
|
+
[[ "$p" == *"test-session"* ]]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@test "governor_ledger_total_tokens returns 0 for missing ledger" {
|
|
99
|
+
local total
|
|
100
|
+
total=$(governor_ledger_total_tokens "no-such-session")
|
|
101
|
+
[ "$total" = "0" ]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@test "governor_ledger_total_cost returns 0 for missing ledger" {
|
|
105
|
+
local total
|
|
106
|
+
total=$(governor_ledger_total_cost "no-such-session")
|
|
107
|
+
[ "$total" = "0" ]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@test "governor_ledger_call_count returns 0 for missing ledger" {
|
|
111
|
+
local count
|
|
112
|
+
count=$(governor_ledger_call_count "no-such-session")
|
|
113
|
+
[ "$count" = "0" ]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@test "governor_ledger_append writes a record and it is readable" {
|
|
117
|
+
local record
|
|
118
|
+
record=$(_make_record 5000 0.045)
|
|
119
|
+
governor_ledger_append "$SID" "$record"
|
|
120
|
+
|
|
121
|
+
local ledger_path
|
|
122
|
+
ledger_path=$(governor_ledger_path "$SID")
|
|
123
|
+
[ -f "$ledger_path" ]
|
|
124
|
+
|
|
125
|
+
local lines
|
|
126
|
+
lines=$(awk 'END{print NR}' "$ledger_path")
|
|
127
|
+
[ "$lines" = "1" ]
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@test "governor_ledger_total_tokens sums across multiple records" {
|
|
131
|
+
governor_ledger_append "$SID" "$(_make_record 3000 0.027)"
|
|
132
|
+
governor_ledger_append "$SID" "$(_make_record 4000 0.036)"
|
|
133
|
+
governor_ledger_append "$SID" "$(_make_record 2500 0.023)"
|
|
134
|
+
|
|
135
|
+
local total
|
|
136
|
+
total=$(governor_ledger_total_tokens "$SID")
|
|
137
|
+
[ "$total" = "9500" ]
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@test "governor_ledger_total_cost sums across multiple records" {
|
|
141
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.01)"
|
|
142
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.02)"
|
|
143
|
+
|
|
144
|
+
local total
|
|
145
|
+
total=$(governor_ledger_total_cost "$SID")
|
|
146
|
+
# Allow slight floating-point representation variance
|
|
147
|
+
[[ "$total" =~ ^0\.03 ]]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@test "governor_ledger_call_count counts records" {
|
|
151
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.009)"
|
|
152
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.009)"
|
|
153
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.009)"
|
|
154
|
+
|
|
155
|
+
local count
|
|
156
|
+
count=$(governor_ledger_call_count "$SID")
|
|
157
|
+
[ "$count" = "3" ]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@test "governor_ledger_is_poisoned returns false for healthy ledger" {
|
|
161
|
+
governor_ledger_append "$SID" "$(_make_record 1000 0.009)"
|
|
162
|
+
run governor_ledger_is_poisoned "$SID"
|
|
163
|
+
[ "$status" -ne 0 ]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@test "governor_ledger_is_poisoned returns true after poison sentinel" {
|
|
167
|
+
local ledger_path
|
|
168
|
+
ledger_path=$(governor_ledger_path "$SID")
|
|
169
|
+
mkdir -p "$(dirname "$ledger_path")"
|
|
170
|
+
touch "$(governor_ledger_poison_path "$ledger_path")"
|
|
171
|
+
|
|
172
|
+
run governor_ledger_is_poisoned "$SID"
|
|
173
|
+
[ "$status" -eq 0 ]
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@test "governor_ledger_write_direct writes a record without acquiring the write lock" {
|
|
177
|
+
local ledger_path
|
|
178
|
+
ledger_path=$(governor_ledger_path "$SID")
|
|
179
|
+
mkdir -p "$(dirname "$ledger_path")"
|
|
180
|
+
|
|
181
|
+
local record
|
|
182
|
+
record=$(_make_reservation 2000 0.018)
|
|
183
|
+
governor_ledger_write_direct "$ledger_path" "$record"
|
|
184
|
+
|
|
185
|
+
local lines
|
|
186
|
+
lines=$(awk 'END{print NR}' "$ledger_path")
|
|
187
|
+
[ "$lines" = "1" ]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@test "two-phase: reservation plus completion converges to actual tokens" {
|
|
191
|
+
# Phase 1: PreToolUse writes reservation with N_est = 5000
|
|
192
|
+
local reservation
|
|
193
|
+
reservation=$(_make_reservation 5000 0.045)
|
|
194
|
+
governor_ledger_append "$SID" "$reservation"
|
|
195
|
+
|
|
196
|
+
local mid_total
|
|
197
|
+
mid_total=$(governor_ledger_total_tokens "$SID")
|
|
198
|
+
[ "$mid_total" = "5000" ]
|
|
199
|
+
|
|
200
|
+
# Phase 2: PostToolUse writes completion with estimated=-5000, actual=4200
|
|
201
|
+
local completion
|
|
202
|
+
completion=$(_make_completion -5000 4200 0.045)
|
|
203
|
+
governor_ledger_append "$SID" "$completion"
|
|
204
|
+
|
|
205
|
+
# Net: 5000 + (-5000) + 4200 = 4200
|
|
206
|
+
local final_total
|
|
207
|
+
final_total=$(governor_ledger_total_tokens "$SID")
|
|
208
|
+
[ "$final_total" = "4200" ]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@test "governor_ledger_call_count excludes reservation records" {
|
|
212
|
+
governor_ledger_append "$SID" "$(_make_reservation 1000 0.009)"
|
|
213
|
+
governor_ledger_append "$SID" "$(_make_completion -1000 900 0.009)"
|
|
214
|
+
governor_ledger_append "$SID" "$(_make_completion -1000 800 0.009)"
|
|
215
|
+
|
|
216
|
+
local count
|
|
217
|
+
count=$(governor_ledger_call_count "$SID")
|
|
218
|
+
# 2 completions, 1 reservation — only completions count
|
|
219
|
+
[ "$count" = "2" ]
|
|
220
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
setup() {
|
|
4
|
+
# shellcheck source=../helpers/setup.bash
|
|
5
|
+
source "${BATS_TEST_DIRNAME}/../helpers/setup.bash"
|
|
6
|
+
setup_test_env
|
|
7
|
+
|
|
8
|
+
PLUGIN_ROOT="${REPO_ROOT}/plugins/scribe"
|
|
9
|
+
export CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT"
|
|
10
|
+
# shellcheck disable=SC1091
|
|
11
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-config.sh"
|
|
12
|
+
# shellcheck disable=SC1091
|
|
13
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-extract.sh"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
# scribe_count_turns
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
@test "count_turns returns 0 for missing file" {
|
|
21
|
+
run scribe_count_turns "/nonexistent/path.jsonl"
|
|
22
|
+
[ "$status" -eq 0 ]
|
|
23
|
+
[ "$output" = "0" ]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@test "count_turns returns 0 for empty file" {
|
|
27
|
+
local f="${BATS_TEST_TMPDIR}/empty.jsonl"
|
|
28
|
+
touch "$f"
|
|
29
|
+
run scribe_count_turns "$f"
|
|
30
|
+
[ "$status" -eq 0 ]
|
|
31
|
+
[ "$output" = "0" ]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@test "count_turns counts only user-role entries" {
|
|
35
|
+
local f="${BATS_TEST_TMPDIR}/transcript.jsonl"
|
|
36
|
+
printf '%s\n' \
|
|
37
|
+
'{"role":"user","content":"hello"}' \
|
|
38
|
+
'{"role":"assistant","content":"hi"}' \
|
|
39
|
+
'{"role":"user","content":"thanks"}' \
|
|
40
|
+
'{"role":"assistant","content":"sure"}' \
|
|
41
|
+
> "$f"
|
|
42
|
+
run scribe_count_turns "$f"
|
|
43
|
+
[ "$status" -eq 0 ]
|
|
44
|
+
[ "$output" = "2" ]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@test "count_turns skips blank lines" {
|
|
48
|
+
local f="${BATS_TEST_TMPDIR}/sparse.jsonl"
|
|
49
|
+
printf '%s\n' \
|
|
50
|
+
'{"role":"user","content":"a"}' \
|
|
51
|
+
'' \
|
|
52
|
+
'{"role":"user","content":"b"}' \
|
|
53
|
+
> "$f"
|
|
54
|
+
run scribe_count_turns "$f"
|
|
55
|
+
[ "$status" -eq 0 ]
|
|
56
|
+
[ "$output" = "2" ]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# min_turns gate (via scribe_distill return code)
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
@test "scribe_distill exits 2 when transcript has fewer turns than min_turns" {
|
|
64
|
+
# shellcheck disable=SC1091
|
|
65
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-events.sh"
|
|
66
|
+
# shellcheck disable=SC1091
|
|
67
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-project-key.sh"
|
|
68
|
+
# shellcheck disable=SC1091
|
|
69
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-distill.sh"
|
|
70
|
+
|
|
71
|
+
# Load config so min_turns is available (default: 3).
|
|
72
|
+
scribe_config_load ""
|
|
73
|
+
|
|
74
|
+
# Transcript with only 1 user turn — below default min_turns of 3.
|
|
75
|
+
local f="${BATS_TEST_TMPDIR}/short.jsonl"
|
|
76
|
+
printf '%s\n' \
|
|
77
|
+
'{"role":"user","content":"hey"}' \
|
|
78
|
+
'{"role":"assistant","content":"yo"}' \
|
|
79
|
+
> "$f"
|
|
80
|
+
|
|
81
|
+
run scribe_distill "test-session-id" "${BATS_TEST_TMPDIR}" "$f"
|
|
82
|
+
[ "$status" -eq 2 ]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@test "scribe_distill min_turns skip produces no stderr output" {
|
|
86
|
+
# shellcheck disable=SC1091
|
|
87
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-events.sh"
|
|
88
|
+
# shellcheck disable=SC1091
|
|
89
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-project-key.sh"
|
|
90
|
+
# shellcheck disable=SC1091
|
|
91
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-distill.sh"
|
|
92
|
+
|
|
93
|
+
scribe_config_load ""
|
|
94
|
+
|
|
95
|
+
local f="${BATS_TEST_TMPDIR}/short2.jsonl"
|
|
96
|
+
printf '%s\n' '{"role":"user","content":"hi"}' > "$f"
|
|
97
|
+
|
|
98
|
+
# Run in a subshell capturing stderr separately.
|
|
99
|
+
local stderr_out
|
|
100
|
+
stderr_out=$(scribe_distill "test-sid" "${BATS_TEST_TMPDIR}" "$f" 2>&1 >/dev/null) || true
|
|
101
|
+
[ -z "$stderr_out" ]
|
|
102
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
setup() {
|
|
4
|
+
# shellcheck source=../helpers/setup.bash
|
|
5
|
+
source "${BATS_TEST_DIRNAME}/../helpers/setup.bash"
|
|
6
|
+
setup_test_env
|
|
7
|
+
|
|
8
|
+
PLUGIN_ROOT="${REPO_ROOT}/plugins/scribe"
|
|
9
|
+
# shellcheck disable=SC1091
|
|
10
|
+
source "${PLUGIN_ROOT}/scripts/lib/scribe-project-key.sh"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@test "non-git directory returns empty key" {
|
|
14
|
+
local d="${BATS_TEST_TMPDIR}/non-git"
|
|
15
|
+
mkdir -p "$d"
|
|
16
|
+
run scribe_project_key "$d"
|
|
17
|
+
[ "$status" -eq 0 ]
|
|
18
|
+
[ -z "$output" ]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@test "git repo without remote falls back to repo-root hash" {
|
|
22
|
+
local d="${BATS_TEST_TMPDIR}/local-only-repo"
|
|
23
|
+
mkdir -p "$d"
|
|
24
|
+
git -C "$d" init -q
|
|
25
|
+
git -C "$d" config user.email t@example.com
|
|
26
|
+
git -C "$d" config user.name "Test"
|
|
27
|
+
|
|
28
|
+
local k1
|
|
29
|
+
k1=$(scribe_project_key "$d")
|
|
30
|
+
[ -n "$k1" ]
|
|
31
|
+
[ "${#k1}" -eq 12 ]
|
|
32
|
+
|
|
33
|
+
# Stability: a second call returns the same key.
|
|
34
|
+
local k2
|
|
35
|
+
k2=$(scribe_project_key "$d")
|
|
36
|
+
[ "$k1" = "$k2" ]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@test "git repo with remote uses remote hash, ignores local path" {
|
|
40
|
+
local a="${BATS_TEST_TMPDIR}/clone-a"
|
|
41
|
+
local b="${BATS_TEST_TMPDIR}/clone-b"
|
|
42
|
+
mkdir -p "$a" "$b"
|
|
43
|
+
for d in "$a" "$b"; do
|
|
44
|
+
git -C "$d" init -q
|
|
45
|
+
git -C "$d" config user.email t@example.com
|
|
46
|
+
git -C "$d" config user.name "Test"
|
|
47
|
+
git -C "$d" remote add origin git@github.com:org/proj.git
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
local ka kb
|
|
51
|
+
ka=$(scribe_project_key "$a")
|
|
52
|
+
kb=$(scribe_project_key "$b")
|
|
53
|
+
[ -n "$ka" ]
|
|
54
|
+
[ "$ka" = "$kb" ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "different remotes yield different keys" {
|
|
58
|
+
local a="${BATS_TEST_TMPDIR}/proj-a"
|
|
59
|
+
local b="${BATS_TEST_TMPDIR}/proj-b"
|
|
60
|
+
mkdir -p "$a" "$b"
|
|
61
|
+
for d in "$a" "$b"; do
|
|
62
|
+
git -C "$d" init -q
|
|
63
|
+
git -C "$d" config user.email t@example.com
|
|
64
|
+
git -C "$d" config user.name "Test"
|
|
65
|
+
done
|
|
66
|
+
git -C "$a" remote add origin git@github.com:org/proj-a.git
|
|
67
|
+
git -C "$b" remote add origin git@github.com:org/proj-b.git
|
|
68
|
+
|
|
69
|
+
local ka kb
|
|
70
|
+
ka=$(scribe_project_key "$a")
|
|
71
|
+
kb=$(scribe_project_key "$b")
|
|
72
|
+
[ -n "$ka" ]
|
|
73
|
+
[ -n "$kb" ]
|
|
74
|
+
[ "$ka" != "$kb" ]
|
|
75
|
+
}
|