@codyswann/lisa 4.13.1 → 4.13.2
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/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +11 -9
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-sonarcloud-access/SKILL.md +49 -7
- package/plugins/lisa/rules/reference/config-resolution.md +43 -6
- package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/lisa/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/lisa/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/lisa/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/lisa/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/lisa/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/lisa/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/lisa/skills/lisa-sonarcloud-access/SKILL.md +49 -7
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/lisa-agy/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/lisa-agy/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/lisa-agy/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/lisa-agy/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/lisa-agy/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/lisa-agy/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/lisa-agy/skills/lisa-sonarcloud-access/SKILL.md +49 -7
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +43 -6
- package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/lisa-copilot/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/lisa-copilot/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/lisa-copilot/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/lisa-copilot/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/lisa-copilot/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/lisa-copilot/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/lisa-copilot/skills/lisa-sonarcloud-access/SKILL.md +49 -7
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +43 -6
- package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/lisa-cursor/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/lisa-cursor/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/lisa-cursor/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/lisa-cursor/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/lisa-cursor/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/lisa-cursor/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/lisa-cursor/skills/lisa-sonarcloud-access/SKILL.md +49 -7
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +43 -6
- package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +48 -6
- package/plugins/src/base/skills/lisa-jam-access/SKILL.md +38 -2
- package/plugins/src/base/skills/lisa-notion-access/SKILL.md +47 -6
- package/plugins/src/base/skills/lisa-posthog-access/SKILL.md +38 -2
- package/plugins/src/base/skills/lisa-sentry-access/SKILL.md +38 -2
- package/plugins/src/base/skills/lisa-setup-atlassian/SKILL.md +53 -7
- package/plugins/src/base/skills/lisa-setup-notion/SKILL.md +53 -7
- package/plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md +49 -7
|
@@ -167,10 +167,43 @@ read_notion_token() {
|
|
|
167
167
|
# Preferred path: the single secrets chokepoint. It owns the one-store rule
|
|
168
168
|
# and the surface ladder, so anything it can answer must not be read out of an
|
|
169
169
|
# OS keychain here — a second reader is how the same credential ends up living
|
|
170
|
-
# in two places and drifting. Keep
|
|
170
|
+
# in two places and drifting. Keep the LADDER below identical to
|
|
171
|
+
# `notion-access`; the tail may differ, because this skill falls through to a
|
|
172
|
+
# legacy keychain rung and that one does not. Saying "the ladder" rather
|
|
173
|
+
# than "this function" is deliberate — the old wording asked for something
|
|
174
|
+
# unachievable, and an unachievable rule is one that gets quietly dropped.
|
|
175
|
+
#
|
|
176
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
177
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
178
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
179
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
180
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
181
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
182
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
183
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
184
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
185
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
186
|
+
# happens AFTER the ladder may differ between them.
|
|
187
|
+
local candidates=(
|
|
188
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
189
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
190
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
191
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
192
|
+
)
|
|
193
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
194
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
195
|
+
fi
|
|
196
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
197
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
198
|
+
fi
|
|
199
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
200
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
201
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
202
|
+
|
|
171
203
|
local resolver
|
|
172
|
-
|
|
173
|
-
|
|
204
|
+
local tried=()
|
|
205
|
+
for resolver in "${candidates[@]}"; do
|
|
206
|
+
tried+=("$resolver")
|
|
174
207
|
if [ -f "$resolver" ]; then
|
|
175
208
|
local via_lisa
|
|
176
209
|
via_lisa=$(node "$resolver" get NOTION_API_TOKEN 2>/dev/null) \
|
|
@@ -181,15 +214,17 @@ read_notion_token() {
|
|
|
181
214
|
# Legacy fallback: the OS keychain written by the guided flow below, for
|
|
182
215
|
# projects that have not adopted a credentials provider. Reached only when the
|
|
183
216
|
# chokepoint is absent or has no entry.
|
|
217
|
+
local from_keychain=""
|
|
184
218
|
case "$(uname -s)" in
|
|
185
|
-
Darwin) security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null ;;
|
|
186
|
-
Linux) command -v secret-tool >/dev/null &&
|
|
219
|
+
Darwin) from_keychain=$(security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null) ;;
|
|
220
|
+
Linux) command -v secret-tool >/dev/null && \
|
|
221
|
+
from_keychain=$(secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null) ;;
|
|
187
222
|
MINGW*|MSYS*|CYGWIN*)
|
|
188
223
|
# `cmdkey /generic ... /pass:` stores the secret in Windows Credential Manager, but
|
|
189
224
|
# `cmdkey /list` never prints stored passwords (by design). Read the CredentialBlob
|
|
190
225
|
# back via the Win32 CredRead API through PowerShell; pass the target name via an env
|
|
191
226
|
# var to dodge nested quoting, and strip the CRLF powershell.exe appends.
|
|
192
|
-
LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
227
|
+
from_keychain=$(LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
193
228
|
Add-Type -TypeDefinition @"
|
|
194
229
|
using System;
|
|
195
230
|
using System.Runtime.InteropServices;
|
|
@@ -215,8 +250,19 @@ public static class LisaCred {
|
|
|
215
250
|
}
|
|
216
251
|
}
|
|
217
252
|
"@
|
|
218
|
-
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r' ;;
|
|
253
|
+
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r') ;;
|
|
219
254
|
esac
|
|
255
|
+
[ -n "$from_keychain" ] && { echo "$from_keychain"; return; }
|
|
256
|
+
|
|
257
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
258
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
259
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
260
|
+
# resolved value, on any path.
|
|
261
|
+
echo "Error: could not resolve NOTION_API_TOKEN through lisa-secrets-access or the legacy keychain." >&2
|
|
262
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
263
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
264
|
+
echo " <OS keychain> service=lisa-notion account=$workspace" >&2
|
|
265
|
+
return 1
|
|
220
266
|
}
|
|
221
267
|
|
|
222
268
|
TOKEN=$(read_notion_token "$WORKSPACE")
|
|
@@ -62,9 +62,38 @@ not the only one:
|
|
|
62
62
|
read_sonar_secret() {
|
|
63
63
|
local name="$1"
|
|
64
64
|
[ -n "${!name:-}" ] && { echo "${!name}"; return; }
|
|
65
|
+
#
|
|
66
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
67
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
68
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
69
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
70
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
71
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
72
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
73
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
74
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
75
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
76
|
+
# happens AFTER the ladder may differ between them.
|
|
77
|
+
local candidates=(
|
|
78
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
79
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
80
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
81
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
82
|
+
)
|
|
83
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
84
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
85
|
+
fi
|
|
86
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
87
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
88
|
+
fi
|
|
89
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
90
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
91
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
92
|
+
|
|
65
93
|
local resolver
|
|
66
|
-
|
|
67
|
-
|
|
94
|
+
local tried=()
|
|
95
|
+
for resolver in "${candidates[@]}"; do
|
|
96
|
+
tried+=("$resolver")
|
|
68
97
|
if [ -f "$resolver" ]; then
|
|
69
98
|
local via_lisa
|
|
70
99
|
via_lisa=$(node "$resolver" get "$name" 2>/dev/null) \
|
|
@@ -72,6 +101,13 @@ read_sonar_secret() {
|
|
|
72
101
|
break
|
|
73
102
|
fi
|
|
74
103
|
done
|
|
104
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
105
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
106
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
107
|
+
# resolved value, on any path.
|
|
108
|
+
echo "Error: could not resolve $name through lisa-secrets-access." >&2
|
|
109
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
110
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
75
111
|
return 1
|
|
76
112
|
}
|
|
77
113
|
|
|
@@ -81,11 +117,17 @@ SONARQUBE_CLI_TOKEN=$(read_sonar_secret SONARQUBE_CLI_TOKEN) && export SONARQUBE
|
|
|
81
117
|
SONARQUBE_CLI_ORG=$(read_sonar_secret SONARQUBE_CLI_ORG) && export SONARQUBE_CLI_ORG
|
|
82
118
|
```
|
|
83
119
|
|
|
84
|
-
`sonar-secrets.sh` runs the same resolution with
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
a timeout, because it sits in front of every
|
|
88
|
-
verbatim when this skill runs inside a hook.
|
|
120
|
+
`sonar-secrets.sh` runs the same resolution with two differences that belong to
|
|
121
|
+
a hook rather than to a skill: it anchors every candidate at `$repo_root` (a
|
|
122
|
+
hook fires from whatever directory the agent happens to be in) and it wraps the
|
|
123
|
+
`resolve-secret.mjs` call in a timeout, because it sits in front of every
|
|
124
|
+
prompt. Use its search order verbatim when this skill runs inside a hook.
|
|
125
|
+
|
|
126
|
+
This paragraph used to claim the hook searched a *longer* path than the ladder
|
|
127
|
+
above. It did — the ladder above stopped after `.agents/`, so in a checkout
|
|
128
|
+
that vendored neither leading path it reached no resolver at all and returned
|
|
129
|
+
without a word. The two now cover the same layouts, and the fix that closed
|
|
130
|
+
that gap is guarded by `credential-resolver-ladder`.
|
|
89
131
|
|
|
90
132
|
Wiring is performed once by `/lisa:setup:sonar` (which drives `sonar integrate
|
|
91
133
|
<agent>`); this access layer assumes the MCP is already wired. This is distinct
|
|
@@ -876,9 +876,34 @@ read_notion_token() {
|
|
|
876
876
|
# Preferred path: the single secrets chokepoint, which owns the one-store rule
|
|
877
877
|
# and the surface ladder. An agent following this reference must try it before
|
|
878
878
|
# any keychain — a second reader is how one credential ends up in two places.
|
|
879
|
+
#
|
|
880
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
881
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
882
|
+
# wants used. The plugin rungs are the floor: `resolve-secret.mjs` ships
|
|
883
|
+
# beside the skill, so a rung pointing at it is reachable from anywhere the
|
|
884
|
+
# plugin itself is installed. Without one, a consumer repository that vendors
|
|
885
|
+
# none of the leading paths never reaches a resolver at all — and an agent
|
|
886
|
+
# copying a two-rung ladder out of THIS reference reproduces that.
|
|
887
|
+
local candidates=(
|
|
888
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
889
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
890
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
891
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
892
|
+
)
|
|
893
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
894
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
895
|
+
fi
|
|
896
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
897
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
898
|
+
fi
|
|
899
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
900
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
901
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
902
|
+
|
|
879
903
|
local resolver
|
|
880
|
-
|
|
881
|
-
|
|
904
|
+
local tried=()
|
|
905
|
+
for resolver in "${candidates[@]}"; do
|
|
906
|
+
tried+=("$resolver")
|
|
882
907
|
if [ -f "$resolver" ]; then
|
|
883
908
|
local via_lisa
|
|
884
909
|
via_lisa=$(node "$resolver" get NOTION_API_TOKEN 2>/dev/null) \
|
|
@@ -889,16 +914,17 @@ read_notion_token() {
|
|
|
889
914
|
# Legacy fallback: the OS keychain written by the guided setup flow, for
|
|
890
915
|
# projects with no credentials provider. Reached only when the chokepoint is
|
|
891
916
|
# absent or has no entry.
|
|
917
|
+
local from_keychain=""
|
|
892
918
|
case "$(uname -s)" in
|
|
893
|
-
Darwin) security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null ;;
|
|
919
|
+
Darwin) from_keychain=$(security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null) ;;
|
|
894
920
|
Linux) command -v secret-tool >/dev/null && \
|
|
895
|
-
secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null ;;
|
|
921
|
+
from_keychain=$(secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null) ;;
|
|
896
922
|
MINGW*|MSYS*|CYGWIN*)
|
|
897
923
|
# `cmdkey /generic ... /pass:` stores the secret in Windows Credential Manager, but
|
|
898
924
|
# `cmdkey /list` never prints stored passwords (by design). Read the CredentialBlob
|
|
899
925
|
# back via the Win32 CredRead API through PowerShell; pass the target name via an env
|
|
900
926
|
# var to dodge nested quoting, and strip the CRLF powershell.exe appends.
|
|
901
|
-
LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
927
|
+
from_keychain=$(LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
902
928
|
Add-Type -TypeDefinition @"
|
|
903
929
|
using System;
|
|
904
930
|
using System.Runtime.InteropServices;
|
|
@@ -924,8 +950,19 @@ public static class LisaCred {
|
|
|
924
950
|
}
|
|
925
951
|
}
|
|
926
952
|
"@
|
|
927
|
-
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r' ;;
|
|
953
|
+
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r') ;;
|
|
928
954
|
esac
|
|
955
|
+
[ -n "$from_keychain" ] && { echo "$from_keychain"; return; }
|
|
956
|
+
|
|
957
|
+
# Name every path. A bare empty return sends the next reader hunting for a
|
|
958
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
959
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
960
|
+
# resolved value, on any path.
|
|
961
|
+
echo "Error: could not resolve NOTION_API_TOKEN through lisa-secrets-access or the legacy keychain." >&2
|
|
962
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
963
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
964
|
+
echo " <OS keychain> service=lisa-notion account=$workspace" >&2
|
|
965
|
+
return 1
|
|
929
966
|
}
|
|
930
967
|
```
|
|
931
968
|
|
|
@@ -56,9 +56,38 @@ read_atlassian_token() {
|
|
|
56
56
|
# and the surface ladder, so anything it can answer must not be read out of an
|
|
57
57
|
# OS keychain here — a second reader is how the same credential ends up living
|
|
58
58
|
# in two places and drifting.
|
|
59
|
+
#
|
|
60
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
61
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
62
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
63
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
64
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
65
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
66
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
67
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
68
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
69
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
70
|
+
# happens AFTER the ladder may differ between them.
|
|
71
|
+
local candidates=(
|
|
72
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
73
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
74
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
75
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
76
|
+
)
|
|
77
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
78
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
79
|
+
fi
|
|
80
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
81
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
82
|
+
fi
|
|
83
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
84
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
85
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
86
|
+
|
|
59
87
|
local resolver
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
local tried=()
|
|
89
|
+
for resolver in "${candidates[@]}"; do
|
|
90
|
+
tried+=("$resolver")
|
|
62
91
|
if [ -f "$resolver" ]; then
|
|
63
92
|
local via_lisa
|
|
64
93
|
via_lisa=$(node "$resolver" get ATLASSIAN_API_TOKEN 2>/dev/null) \
|
|
@@ -76,15 +105,17 @@ read_atlassian_token() {
|
|
|
76
105
|
# surface can reach, so a project resting on it has no working tier 1 in cron,
|
|
77
106
|
# CI, or a cloud session. Re-run /lisa:setup:atlassian before that date to
|
|
78
107
|
# store ATLASSIAN_API_TOKEN through the chokepoint instead.
|
|
108
|
+
local from_keychain=""
|
|
79
109
|
case "$(uname -s)" in
|
|
80
|
-
Darwin) security find-generic-password -s lisa-atlassian -a "$email" -w 2>/dev/null ;;
|
|
81
|
-
Linux) command -v secret-tool >/dev/null &&
|
|
110
|
+
Darwin) from_keychain=$(security find-generic-password -s lisa-atlassian -a "$email" -w 2>/dev/null) ;;
|
|
111
|
+
Linux) command -v secret-tool >/dev/null && \
|
|
112
|
+
from_keychain=$(secret-tool lookup service lisa-atlassian account "$email" 2>/dev/null) ;;
|
|
82
113
|
MINGW*|MSYS*|CYGWIN*)
|
|
83
114
|
# `cmdkey /generic ... /pass:` stores the secret in Windows Credential Manager, but
|
|
84
115
|
# `cmdkey /list` never prints stored passwords (by design). Read the CredentialBlob
|
|
85
116
|
# back via the Win32 CredRead API through PowerShell; pass the target name via an env
|
|
86
117
|
# var to dodge nested quoting, and strip the CRLF powershell.exe appends.
|
|
87
|
-
LISA_CRED_TARGET="lisa-atlassian-${email}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
118
|
+
from_keychain=$(LISA_CRED_TARGET="lisa-atlassian-${email}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
88
119
|
Add-Type -TypeDefinition @"
|
|
89
120
|
using System;
|
|
90
121
|
using System.Runtime.InteropServices;
|
|
@@ -110,8 +141,19 @@ public static class LisaCred {
|
|
|
110
141
|
}
|
|
111
142
|
}
|
|
112
143
|
"@
|
|
113
|
-
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r' ;;
|
|
144
|
+
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r') ;;
|
|
114
145
|
esac
|
|
146
|
+
[ -n "$from_keychain" ] && { echo "$from_keychain"; return; }
|
|
147
|
+
|
|
148
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
149
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
150
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
151
|
+
# resolved value, on any path.
|
|
152
|
+
echo "Error: could not resolve ATLASSIAN_API_TOKEN through lisa-secrets-access or the legacy keychain." >&2
|
|
153
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
154
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
155
|
+
echo " <OS keychain> service=lisa-atlassian account=$email" >&2
|
|
156
|
+
return 1
|
|
115
157
|
}
|
|
116
158
|
TOKEN=$(read_atlassian_token "$EMAIL")
|
|
117
159
|
if [ -n "$TOKEN" ]; then
|
|
@@ -47,9 +47,38 @@ export PATH="$HOME/.local/bin:$PATH"
|
|
|
47
47
|
# divergence `credential-substrate-precedence` exists to remove.
|
|
48
48
|
read_jam_pat() {
|
|
49
49
|
[ -n "${JAM_PAT:-}" ] && { echo "$JAM_PAT"; return; }
|
|
50
|
+
#
|
|
51
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
52
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
53
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
54
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
55
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
56
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
57
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
58
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
59
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
60
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
61
|
+
# happens AFTER the ladder may differ between them.
|
|
62
|
+
local candidates=(
|
|
63
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
64
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
65
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
66
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
67
|
+
)
|
|
68
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
69
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
70
|
+
fi
|
|
71
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
72
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
73
|
+
fi
|
|
74
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
75
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
76
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
77
|
+
|
|
50
78
|
local resolver
|
|
51
|
-
|
|
52
|
-
|
|
79
|
+
local tried=()
|
|
80
|
+
for resolver in "${candidates[@]}"; do
|
|
81
|
+
tried+=("$resolver")
|
|
53
82
|
if [ -f "$resolver" ]; then
|
|
54
83
|
local via_lisa
|
|
55
84
|
via_lisa=$(node "$resolver" get JAM_PAT 2>/dev/null) \
|
|
@@ -57,6 +86,13 @@ read_jam_pat() {
|
|
|
57
86
|
break
|
|
58
87
|
fi
|
|
59
88
|
done
|
|
89
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
90
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
91
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
92
|
+
# resolved value, on any path.
|
|
93
|
+
echo "Error: could not resolve JAM_PAT through lisa-secrets-access." >&2
|
|
94
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
95
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
60
96
|
return 1
|
|
61
97
|
}
|
|
62
98
|
|
|
@@ -57,9 +57,38 @@ read_notion_token() {
|
|
|
57
57
|
# and the surface ladder, so anything it can answer must not be read out of an
|
|
58
58
|
# OS keychain here — a second reader is how the same credential ends up living
|
|
59
59
|
# in two places and drifting.
|
|
60
|
+
#
|
|
61
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
62
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
63
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
64
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
65
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
66
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
67
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
68
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
69
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
70
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
71
|
+
# happens AFTER the ladder may differ between them.
|
|
72
|
+
local candidates=(
|
|
73
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
74
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
75
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
76
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
77
|
+
)
|
|
78
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
79
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
80
|
+
fi
|
|
81
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
82
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
83
|
+
fi
|
|
84
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
85
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
86
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
87
|
+
|
|
60
88
|
local resolver
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
local tried=()
|
|
90
|
+
for resolver in "${candidates[@]}"; do
|
|
91
|
+
tried+=("$resolver")
|
|
63
92
|
if [ -f "$resolver" ]; then
|
|
64
93
|
local via_lisa
|
|
65
94
|
via_lisa=$(node "$resolver" get NOTION_API_TOKEN 2>/dev/null) \
|
|
@@ -77,16 +106,17 @@ read_notion_token() {
|
|
|
77
106
|
# surface can reach, so a project resting on it has no working tier 1 in cron,
|
|
78
107
|
# CI, or a cloud session. Re-run /lisa:setup:notion before that date to store
|
|
79
108
|
# NOTION_API_TOKEN through the chokepoint instead.
|
|
109
|
+
local from_keychain=""
|
|
80
110
|
case "$(uname -s)" in
|
|
81
|
-
Darwin) security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null ;;
|
|
111
|
+
Darwin) from_keychain=$(security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null) ;;
|
|
82
112
|
Linux) command -v secret-tool >/dev/null && \
|
|
83
|
-
secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null ;;
|
|
113
|
+
from_keychain=$(secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null) ;;
|
|
84
114
|
MINGW*|MSYS*|CYGWIN*)
|
|
85
115
|
# `cmdkey /generic ... /pass:` stores the secret in Windows Credential Manager, but
|
|
86
116
|
# `cmdkey /list` never prints stored passwords (by design). Read the CredentialBlob
|
|
87
117
|
# back via the Win32 CredRead API through PowerShell; pass the target name via an env
|
|
88
118
|
# var to dodge nested quoting, and strip the CRLF powershell.exe appends.
|
|
89
|
-
LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
119
|
+
from_keychain=$(LISA_CRED_TARGET="lisa-notion-${workspace}" powershell.exe -NoProfile -NonInteractive -Command '
|
|
90
120
|
Add-Type -TypeDefinition @"
|
|
91
121
|
using System;
|
|
92
122
|
using System.Runtime.InteropServices;
|
|
@@ -112,8 +142,19 @@ public static class LisaCred {
|
|
|
112
142
|
}
|
|
113
143
|
}
|
|
114
144
|
"@
|
|
115
|
-
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r' ;;
|
|
145
|
+
[LisaCred]::Read($env:LISA_CRED_TARGET)' 2>/dev/null | tr -d '\r') ;;
|
|
116
146
|
esac
|
|
147
|
+
[ -n "$from_keychain" ] && { echo "$from_keychain"; return; }
|
|
148
|
+
|
|
149
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
150
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
151
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
152
|
+
# resolved value, on any path.
|
|
153
|
+
echo "Error: could not resolve NOTION_API_TOKEN through lisa-secrets-access or the legacy keychain." >&2
|
|
154
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
155
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
156
|
+
echo " <OS keychain> service=lisa-notion account=$workspace" >&2
|
|
157
|
+
return 1
|
|
117
158
|
}
|
|
118
159
|
TOKEN=$(read_notion_token "$WORKSPACE")
|
|
119
160
|
if [ -n "$TOKEN" ]; then
|
|
@@ -48,9 +48,38 @@ POSTHOG_HOST=${POSTHOG_HOST:-https://app.posthog.com}
|
|
|
48
48
|
# MCP — the exact divergence `credential-substrate-precedence` exists to remove.
|
|
49
49
|
read_posthog_key() {
|
|
50
50
|
[ -n "${POSTHOG_PERSONAL_API_KEY:-}" ] && { echo "$POSTHOG_PERSONAL_API_KEY"; return; }
|
|
51
|
+
#
|
|
52
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
53
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
54
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
55
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
56
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
57
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
58
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
59
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
60
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
61
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
62
|
+
# happens AFTER the ladder may differ between them.
|
|
63
|
+
local candidates=(
|
|
64
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
65
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
66
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
67
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
68
|
+
)
|
|
69
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
70
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
71
|
+
fi
|
|
72
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
73
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
74
|
+
fi
|
|
75
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
76
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
77
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
78
|
+
|
|
51
79
|
local resolver
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
local tried=()
|
|
81
|
+
for resolver in "${candidates[@]}"; do
|
|
82
|
+
tried+=("$resolver")
|
|
54
83
|
if [ -f "$resolver" ]; then
|
|
55
84
|
local via_lisa
|
|
56
85
|
via_lisa=$(node "$resolver" get POSTHOG_PERSONAL_API_KEY 2>/dev/null) \
|
|
@@ -58,6 +87,13 @@ read_posthog_key() {
|
|
|
58
87
|
break
|
|
59
88
|
fi
|
|
60
89
|
done
|
|
90
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
91
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
92
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
93
|
+
# resolved value, on any path.
|
|
94
|
+
echo "Error: could not resolve POSTHOG_PERSONAL_API_KEY through lisa-secrets-access." >&2
|
|
95
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
96
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
61
97
|
return 1
|
|
62
98
|
}
|
|
63
99
|
|
|
@@ -47,9 +47,38 @@ interactively and headlessly — which is why it leads. The REST tier uses:
|
|
|
47
47
|
# Mirrors `linear-access`, `atlassian-access`, and `notion-access`.
|
|
48
48
|
read_sentry_token() {
|
|
49
49
|
[ -n "${SENTRY_AUTH_TOKEN:-}" ] && { echo "$SENTRY_AUTH_TOKEN"; return; }
|
|
50
|
+
#
|
|
51
|
+
# Ordered repo-first, ending at the plugin's own copy. Repo-relative rungs
|
|
52
|
+
# lead because a project that vendors the resolver has declared which copy it
|
|
53
|
+
# wants used, and that decision must survive this change untouched. The plugin
|
|
54
|
+
# rungs are the floor: `resolve-secret.mjs` ships beside this skill, so a rung
|
|
55
|
+
# pointing at it is reachable from anywhere the plugin itself is installed.
|
|
56
|
+
# Without one, a consumer repository that vendors none of the leading paths
|
|
57
|
+
# never reaches a resolver at all — the ladder exits without having asked
|
|
58
|
+
# anything, which is what pushed agents into improvising their own credential
|
|
59
|
+
# lookups. This LADDER is identical in every skill that resolves a credential
|
|
60
|
+
# and `credential-resolver-ladder` fails if any copy diverges. Only what
|
|
61
|
+
# happens AFTER the ladder may differ between them.
|
|
62
|
+
local candidates=(
|
|
63
|
+
.claude/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
64
|
+
.agents/skills/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
65
|
+
.opencode/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
66
|
+
.codex/skills/lisa/lisa-secrets-access/scripts/resolve-secret.mjs
|
|
67
|
+
)
|
|
68
|
+
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
|
69
|
+
candidates+=("$CLAUDE_PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
70
|
+
fi
|
|
71
|
+
if [ -n "${PLUGIN_ROOT:-}" ]; then
|
|
72
|
+
candidates+=("$PLUGIN_ROOT/skills/lisa-secrets-access/scripts/resolve-secret.mjs")
|
|
73
|
+
fi
|
|
74
|
+
# Last rung deliberately needs no environment variable: an agent that was
|
|
75
|
+
# never handed a plugin root still has the installed package to fall back on.
|
|
76
|
+
candidates+=(node_modules/@codyswann/lisa/plugins/lisa/skills/lisa-secrets-access/scripts/resolve-secret.mjs)
|
|
77
|
+
|
|
50
78
|
local resolver
|
|
51
|
-
|
|
52
|
-
|
|
79
|
+
local tried=()
|
|
80
|
+
for resolver in "${candidates[@]}"; do
|
|
81
|
+
tried+=("$resolver")
|
|
53
82
|
if [ -f "$resolver" ]; then
|
|
54
83
|
local via_lisa
|
|
55
84
|
via_lisa=$(node "$resolver" get SENTRY_AUTH_TOKEN 2>/dev/null) \
|
|
@@ -57,6 +86,13 @@ read_sentry_token() {
|
|
|
57
86
|
break
|
|
58
87
|
fi
|
|
59
88
|
done
|
|
89
|
+
# Name every path. A bare `return 1` sends the next reader hunting for a
|
|
90
|
+
# resolver they cannot see the absence of; the enumeration turns that into a
|
|
91
|
+
# seconds-long diagnosis. Paths and store coordinates only — never any
|
|
92
|
+
# resolved value, on any path.
|
|
93
|
+
echo "Error: could not resolve SENTRY_AUTH_TOKEN through lisa-secrets-access." >&2
|
|
94
|
+
echo "Tried, in order (relative paths are from $PWD):" >&2
|
|
95
|
+
printf ' %s\n' "${tried[@]}" >&2
|
|
60
96
|
return 1
|
|
61
97
|
}
|
|
62
98
|
|