@codyswann/lisa 4.10.5 → 4.10.6

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 (142) hide show
  1. package/dist/codex/scripts/setup-jira-cli.sh +50 -0
  2. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  3. package/dist/core/upstream-evidence-manifest.js +16 -15
  4. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  5. package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +13 -0
  6. package/package.json +1 -1
  7. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  8. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  9. package/plugins/lisa/.codex-plugin/skills/lisa-jira-add-journey/SKILL.md +16 -2
  10. package/plugins/lisa/.codex-plugin/skills/lisa-jira-evidence/SKILL.md +6 -3
  11. package/plugins/lisa/.codex-plugin/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  12. package/plugins/lisa/.codex-plugin/skills/lisa-jira-journey/SKILL.md +2 -1
  13. package/plugins/lisa/.codex-plugin/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  14. package/plugins/lisa/hooks/setup-jira-cli.sh +50 -0
  15. package/plugins/lisa/rules/reference/base-rules.md +1 -1
  16. package/plugins/lisa/skills/lisa-jira-add-journey/SKILL.md +16 -2
  17. package/plugins/lisa/skills/lisa-jira-evidence/SKILL.md +6 -3
  18. package/plugins/lisa/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  19. package/plugins/lisa/skills/lisa-jira-journey/SKILL.md +2 -1
  20. package/plugins/lisa/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  21. package/plugins/lisa-agy/plugin.json +1 -1
  22. package/plugins/lisa-agy/skills/lisa-jira-add-journey/SKILL.md +16 -2
  23. package/plugins/lisa-agy/skills/lisa-jira-evidence/SKILL.md +6 -3
  24. package/plugins/lisa-agy/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  25. package/plugins/lisa-agy/skills/lisa-jira-journey/SKILL.md +2 -1
  26. package/plugins/lisa-agy/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  27. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  29. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  30. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-copilot/hooks/setup-jira-cli.sh +50 -0
  34. package/plugins/lisa-copilot/rules/reference/base-rules.md +1 -1
  35. package/plugins/lisa-copilot/skills/lisa-jira-add-journey/SKILL.md +16 -2
  36. package/plugins/lisa-copilot/skills/lisa-jira-evidence/SKILL.md +6 -3
  37. package/plugins/lisa-copilot/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  38. package/plugins/lisa-copilot/skills/lisa-jira-journey/SKILL.md +2 -1
  39. package/plugins/lisa-copilot/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  40. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-cursor/hooks/setup-jira-cli.sh +50 -0
  42. package/plugins/lisa-cursor/rules/base-rules-reference.mdc +1 -1
  43. package/plugins/lisa-cursor/skills/lisa-jira-add-journey/SKILL.md +16 -2
  44. package/plugins/lisa-cursor/skills/lisa-jira-evidence/SKILL.md +6 -3
  45. package/plugins/lisa-cursor/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  46. package/plugins/lisa-cursor/skills/lisa-jira-journey/SKILL.md +2 -1
  47. package/plugins/lisa-cursor/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  48. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  50. package/plugins/lisa-expo/.codex-plugin/skills/jira-add-journey/SKILL.md +16 -2
  51. package/plugins/lisa-expo/.codex-plugin/skills/jira-evidence/SKILL.md +6 -3
  52. package/plugins/lisa-expo/.codex-plugin/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  53. package/plugins/lisa-expo/.codex-plugin/skills/jira-journey/SKILL.md +2 -1
  54. package/plugins/lisa-expo/skills/jira-add-journey/SKILL.md +16 -2
  55. package/plugins/lisa-expo/skills/jira-evidence/SKILL.md +6 -3
  56. package/plugins/lisa-expo/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  57. package/plugins/lisa-expo/skills/jira-journey/SKILL.md +2 -1
  58. package/plugins/lisa-expo-agy/plugin.json +1 -1
  59. package/plugins/lisa-expo-agy/skills/jira-add-journey/SKILL.md +16 -2
  60. package/plugins/lisa-expo-agy/skills/jira-evidence/SKILL.md +6 -3
  61. package/plugins/lisa-expo-agy/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  62. package/plugins/lisa-expo-agy/skills/jira-journey/SKILL.md +2 -1
  63. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-expo-copilot/skills/jira-add-journey/SKILL.md +16 -2
  65. package/plugins/lisa-expo-copilot/skills/jira-evidence/SKILL.md +6 -3
  66. package/plugins/lisa-expo-copilot/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  67. package/plugins/lisa-expo-copilot/skills/jira-journey/SKILL.md +2 -1
  68. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-expo-cursor/skills/jira-add-journey/SKILL.md +16 -2
  70. package/plugins/lisa-expo-cursor/skills/jira-evidence/SKILL.md +6 -3
  71. package/plugins/lisa-expo-cursor/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  72. package/plugins/lisa-expo-cursor/skills/jira-journey/SKILL.md +2 -1
  73. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  75. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  76. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  81. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  86. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  91. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-rails/.codex-plugin/skills/jira-add-journey/SKILL.md +16 -2
  96. package/plugins/lisa-rails/.codex-plugin/skills/jira-evidence/SKILL.md +6 -3
  97. package/plugins/lisa-rails/.codex-plugin/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  98. package/plugins/lisa-rails/.codex-plugin/skills/jira-journey/SKILL.md +2 -1
  99. package/plugins/lisa-rails/skills/jira-add-journey/SKILL.md +16 -2
  100. package/plugins/lisa-rails/skills/jira-evidence/SKILL.md +6 -3
  101. package/plugins/lisa-rails/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  102. package/plugins/lisa-rails/skills/jira-journey/SKILL.md +2 -1
  103. package/plugins/lisa-rails-agy/plugin.json +1 -1
  104. package/plugins/lisa-rails-agy/skills/jira-add-journey/SKILL.md +16 -2
  105. package/plugins/lisa-rails-agy/skills/jira-evidence/SKILL.md +6 -3
  106. package/plugins/lisa-rails-agy/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  107. package/plugins/lisa-rails-agy/skills/jira-journey/SKILL.md +2 -1
  108. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-rails-copilot/skills/jira-add-journey/SKILL.md +16 -2
  110. package/plugins/lisa-rails-copilot/skills/jira-evidence/SKILL.md +6 -3
  111. package/plugins/lisa-rails-copilot/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  112. package/plugins/lisa-rails-copilot/skills/jira-journey/SKILL.md +2 -1
  113. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-rails-cursor/skills/jira-add-journey/SKILL.md +16 -2
  115. package/plugins/lisa-rails-cursor/skills/jira-evidence/SKILL.md +6 -3
  116. package/plugins/lisa-rails-cursor/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  117. package/plugins/lisa-rails-cursor/skills/jira-journey/SKILL.md +2 -1
  118. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  120. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  121. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  125. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  126. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  128. package/plugins/src/base/hooks/setup-jira-cli.sh +50 -0
  129. package/plugins/src/base/rules/reference/base-rules.md +1 -1
  130. package/plugins/src/base/skills/lisa-jira-add-journey/SKILL.md +16 -2
  131. package/plugins/src/base/skills/lisa-jira-evidence/SKILL.md +6 -3
  132. package/plugins/src/base/skills/lisa-jira-evidence/scripts/post-evidence.sh +56 -5
  133. package/plugins/src/base/skills/lisa-jira-journey/SKILL.md +2 -1
  134. package/plugins/src/base/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +53 -4
  135. package/plugins/src/expo/skills/jira-add-journey/SKILL.md +16 -2
  136. package/plugins/src/expo/skills/jira-evidence/SKILL.md +6 -3
  137. package/plugins/src/expo/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  138. package/plugins/src/expo/skills/jira-journey/SKILL.md +2 -1
  139. package/plugins/src/rails/skills/jira-add-journey/SKILL.md +16 -2
  140. package/plugins/src/rails/skills/jira-evidence/SKILL.md +6 -3
  141. package/plugins/src/rails/skills/jira-evidence/scripts/post-evidence.sh +56 -5
  142. package/plugins/src/rails/skills/jira-journey/SKILL.md +2 -1
@@ -109,6 +109,19 @@ export const LisaSessionBootstrap = async ({
109
109
  process.env.JIRA_PROJECT ?? readLisaConfig(["jira", "project"]) ?? "";
110
110
  const login = process.env.JIRA_LOGIN;
111
111
  if (server && login) {
112
+ // Consumers of this file (CodySwannGT/lisa#2767 — until then it had
113
+ // none, making this hook an inert control):
114
+ // * lisa-jira-evidence/scripts/post-evidence.sh — greps server/login,
115
+ // then passes `--config <path>` to `jira issue move`.
116
+ // * lisa-jira-read-ticket/scripts/download-attachment.sh — greps the
117
+ // same keys, but only when JIRA_SERVER/JIRA_LOGIN are unset.
118
+ // * SKILL prose — types `jira --config .lisa/jira-cli/.config.yml`.
119
+ //
120
+ // No per-harness environment export is involved anywhere: two consumers
121
+ // parse this YAML in Lisa-owned code, and the one real jira-cli call
122
+ // passes an argument. jira-cli resolves --config > JIRA_CONFIG_FILE >
123
+ // ~/.config/.jira/.config.yml, and a --config path that does not exist
124
+ // fails closed rather than falling back (measured, jira-cli v1.7.0).
112
125
  const dir = `${root}/.lisa/jira-cli`;
113
126
  mkdirSync(dir, { recursive: true });
114
127
  const config = [
package/package.json CHANGED
@@ -149,7 +149,7 @@
149
149
  "zod-validation-error": "^4.0.0"
150
150
  },
151
151
  "name": "@codyswann/lisa",
152
- "version": "4.10.5",
152
+ "version": "4.10.6",
153
153
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
154
154
  "main": "dist/index.js",
155
155
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.5",
3
+ "version": "4.10.6",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.5",
3
+ "version": "4.10.6",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -16,7 +16,12 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
16
16
  ## Prerequisites
17
17
 
18
18
  - `JIRA_API_TOKEN` environment variable set
19
- - `jira-cli` configured (`~/.config/.jira/.config.yml`)
19
+ - `jira-cli` configured. Prefer the config Lisa writes at
20
+ `.lisa/jira-cli/.config.yml` (the `setup-jira-cli` SessionStart hook writes it
21
+ from `JIRA_SERVER` / `JIRA_LOGIN` / `JIRA_PROJECT` on a project whose
22
+ `tracker` is `jira`), and pass it explicitly with `--config`. A developer's
23
+ own `~/.config/.jira/.config.yml` still works as jira-cli's default when no
24
+ `--config` is given.
20
25
 
21
26
  ## Workflow
22
27
 
@@ -25,9 +30,18 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
25
30
  Use the Atlassian MCP or jira-cli to read the full ticket details:
26
31
 
27
32
  ```bash
28
- jira issue view <TICKET_ID>
33
+ # Run from the project root. --config pins jira-cli to the file Lisa's
34
+ # setup-jira-cli hook wrote, instead of the machine's own ~/.config/.jira.
35
+ # jira-cli resolves --config > JIRA_CONFIG_FILE > ~/.config/.jira/.config.yml,
36
+ # and a --config path that does not exist fails closed with "Missing
37
+ # configuration file." rather than silently using the default.
38
+ jira --config .lisa/jira-cli/.config.yml issue view <TICKET_ID>
29
39
  ```
30
40
 
41
+ If `.lisa/jira-cli/.config.yml` does not exist, drop `--config` to fall back to
42
+ the machine's own jira-cli config — but say so in your report rather than
43
+ letting the Lisa-written config go quietly unused.
44
+
31
45
  Extract: title, description, acceptance criteria, components, labels, linked tickets.
32
46
 
33
47
  ### Step 2: Check for Existing Journey
@@ -35,7 +35,10 @@ Upload captured evidence and generated templates to GitHub PR description and JI
35
35
  ## Prerequisites
36
36
 
37
37
  - `JIRA_API_TOKEN` environment variable set
38
- - `jira-cli` configured (`~/.config/.jira/.config.yml`) — server and login are read from there
38
+ - a jira-cli config — `.lisa/jira-cli/.config.yml` if the `setup-jira-cli`
39
+ SessionStart hook wrote one, otherwise `~/.config/.jira/.config.yml`. `server`
40
+ and `login` are read from whichever is used, and the fallback is announced on
41
+ stderr rather than taken silently.
39
42
  - `gh` CLI authenticated
40
43
  - Evidence directory containing:
41
44
  - `NN-name.txt` or `NN-name.json` text evidence files (e.g., `01-health-check.json`)
@@ -66,7 +69,7 @@ bash .claude/skills/jira-evidence/scripts/post-evidence.sh PROJ-123 ./evidence 4
66
69
 
67
70
  ## What It Does
68
71
 
69
- 1. **Read JIRA config** — Reads `~/.config/.jira/.config.yml` to obtain `server` and `login` dynamically
72
+ 1. **Read JIRA config** — Resolves the jira-cli config (`$PROJECT_DIR/.lisa/jira-cli/.config.yml` first, then `~/.config/.jira/.config.yml`, announcing the fallback) and reads `server` and `login` from it dynamically — no hardcoded values. Exits 1 naming both paths when neither exists. The same resolved path is then passed to `jira issue move` as `--config`, so the CLI cannot end up on a different config than the one this script parsed.
70
73
  2. **Upload to GitHub `pr-assets` release** — Uploads evidence files via `gh release upload --clobber`
71
74
  3. **Update PR description** — Replaces or appends the `## Evidence` section in the PR body
72
75
  4. **Post JIRA comment** — Posts `comment.txt` as a new comment (wiki markup with code blocks)
@@ -97,4 +100,4 @@ gh release create pr-assets --title "PR Assets" --notes "CDN for PR evidence"
97
100
 
98
101
  ### JIRA API returns 403
99
102
 
100
- Ensure `JIRA_API_TOKEN` is set and `login` in `~/.config/.jira/.config.yml` matches your Atlassian account email.
103
+ Ensure `JIRA_API_TOKEN` is set and `login` in the resolved jira-cli config (`.lisa/jira-cli/.config.yml`, else `~/.config/.jira/.config.yml`) matches your Atlassian account email.
@@ -6,7 +6,11 @@
6
6
  #
7
7
  # Prerequisites:
8
8
  # - JIRA_API_TOKEN env var set
9
- # - jira-cli configured (~/.config/.jira/.config.yml)
9
+ # - a jira-cli config, resolved in this order (see "CONFIG RESOLUTION" below):
10
+ # 1. ${PROJECT_DIR}/.lisa/jira-cli/.config.yml (written by the
11
+ # setup-jira-cli SessionStart hook from the JIRA_* environment)
12
+ # 2. ~/.config/.jira/.config.yml (a developer's own
13
+ # `jira init` config; announced on stderr when it is used)
10
14
  # - gh CLI authenticated
11
15
  #
12
16
  # What it does:
@@ -23,9 +27,50 @@ TICKET_ID="${1:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
23
27
  EVIDENCE_DIR="${2:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
24
28
  PR_NUMBER="${3:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
25
29
 
26
- JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
27
- if [[ ! -f "$JIRA_CONFIG" ]]; then
28
- echo "ERROR: jira-cli config not found at $JIRA_CONFIG — run 'jira init' first" >&2
30
+ # ─────────────────────────────────────────────────────────────────────────────
31
+ # CONFIG RESOLUTION
32
+ #
33
+ # The setup-jira-cli SessionStart hook writes ${PROJECT_DIR}/.lisa/jira-cli/
34
+ # .config.yml. Nothing read it — this script looked only at the developer's own
35
+ # ~/.config/.jira/.config.yml and exited 1 telling the operator to run
36
+ # `jira init`, so on a headless JIRA project the hook was an inert control.
37
+ # See CodySwannGT/lisa#2767.
38
+ #
39
+ # PROJECT_DIR is resolved with the same rule as the hook that writes the file,
40
+ # deliberately character-for-character: CLAUDE_PROJECT_DIR (the harness's own
41
+ # declaration of the root, inert on harnesses that never set it), then the git
42
+ # toplevel, then pwd. A session launched from a subdirectory otherwise reads a
43
+ # directory it never wrote — the #2768 defect, on the read side.
44
+ #
45
+ # Nothing here writes to ~/.config/.jira. That file is a developer's personal
46
+ # jira-cli state; it is read as a fallback and never created or modified.
47
+ #
48
+ # NOTE: the `.lisa.config.json` reads in Step 5 below are still resolved from
49
+ # the process working directory. That is pre-existing and out of scope here.
50
+ # ─────────────────────────────────────────────────────────────────────────────
51
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
52
+ if [[ -z "${PROJECT_DIR}" || ! -d "${PROJECT_DIR}" ]]; then
53
+ PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
54
+ fi
55
+ PROJECT_JIRA_CONFIG="${PROJECT_DIR}/.lisa/jira-cli/.config.yml"
56
+ HOME_JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
57
+
58
+ if [[ -f "$PROJECT_JIRA_CONFIG" ]]; then
59
+ JIRA_CONFIG="$PROJECT_JIRA_CONFIG"
60
+ elif [[ -f "$HOME_JIRA_CONFIG" ]]; then
61
+ # Announced, never silent. A silent fall-through to the developer's own file
62
+ # is precisely how the Lisa-written config stayed unconsumed without anyone
63
+ # noticing, and on a headless runner there is no such file to fall back to.
64
+ echo "NOTE: no Lisa-written jira-cli config at $PROJECT_JIRA_CONFIG" >&2
65
+ echo " falling back to the developer config at $HOME_JIRA_CONFIG" >&2
66
+ JIRA_CONFIG="$HOME_JIRA_CONFIG"
67
+ else
68
+ echo "ERROR: jira-cli config not found." >&2
69
+ echo " Lisa-written config (expected): $PROJECT_JIRA_CONFIG" >&2
70
+ echo " developer config (fallback): $HOME_JIRA_CONFIG" >&2
71
+ echo " Fix: export JIRA_SERVER, JIRA_LOGIN (and JIRA_INSTALLATION," >&2
72
+ echo " JIRA_PROJECT) and start a new session so the setup-jira-cli hook" >&2
73
+ echo " writes the project config — or run 'jira init' locally." >&2
29
74
  exit 1
30
75
  fi
31
76
  JIRA_SERVER=$(grep '^server:' "$JIRA_CONFIG" | awk '{print $2}')
@@ -169,7 +214,13 @@ fi
169
214
  echo ""
170
215
  if [ -n "$REVIEW" ]; then
171
216
  echo "==> Moving $TICKET_ID to $REVIEW..."
172
- jira issue move "$TICKET_ID" "$REVIEW" 2>&1 && echo " ✓ Ticket moved to $REVIEW" || echo " WARNING: Could not move ticket to $REVIEW (not a valid transition?); leaving in current status" >&2
217
+ # --config pins jira-cli to the same file this script parsed above.
218
+ # jira-cli resolves --config > JIRA_CONFIG_FILE > ~/.config/.jira/
219
+ # .config.yml, and a --config path that does not exist fails closed
220
+ # rather than falling back (measured against jira-cli v1.7.0). The flag
221
+ # needs no environment export, so this works identically on every
222
+ # harness — see the harness note in the setup-jira-cli hook.
223
+ jira --config "$JIRA_CONFIG" issue move "$TICKET_ID" "$REVIEW" 2>&1 && echo " ✓ Ticket moved to $REVIEW" || echo " WARNING: Could not move ticket to $REVIEW (not a valid transition?); leaving in current status" >&2
173
224
  else
174
225
  echo "==> No jira.workflow.review configured; leaving $TICKET_ID in its current (claimed) status per config-resolution."
175
226
  fi
@@ -20,7 +20,8 @@ Parse a JIRA ticket's Validation Journey, execute the verification steps using t
20
20
  ## Prerequisites
21
21
 
22
22
  - `JIRA_API_TOKEN` environment variable set
23
- - `jira-cli` configured (`~/.config/.jira/.config.yml`)
23
+ - `jira-cli` configured — `.lisa/jira-cli/.config.yml` (written by the
24
+ `setup-jira-cli` SessionStart hook) or `~/.config/.jira/.config.yml`
24
25
  - `gh` CLI authenticated
25
26
  - Appropriate services running for the verification type (dev server, database, etc.)
26
27
 
@@ -19,6 +19,13 @@
19
19
  # JIRA_LOGIN - login email
20
20
  # JIRA_API_TOKEN - API token (https://id.atlassian.com/manage-profile/security/api-tokens)
21
21
  #
22
+ # JIRA_SERVER and JIRA_LOGIN each fall back to a jira-cli config when unset:
23
+ # ${PROJECT_DIR}/.lisa/jira-cli/.config.yml (written by the setup-jira-cli
24
+ # SessionStart hook) first, then ${HOME}/.config/.jira/.config.yml, with the
25
+ # fallback announced on stderr. When BOTH env vars are set, no config file is
26
+ # opened at all. JIRA_API_TOKEN has no config fallback — it is a secret and
27
+ # is never written to the jira-cli config.
28
+ #
22
29
  # Exit codes:
23
30
  # 0 success
24
31
  # 1 download failed (HTTP error)
@@ -34,12 +41,54 @@ fi
34
41
  ID_OR_URL="$1"
35
42
  OUTPUT_PATH="$2"
36
43
 
37
- # Resolve credentials: prefer env, fall back to jira-cli config for server/login.
38
- JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
39
- if [[ -z "${JIRA_SERVER:-}" && -f "$JIRA_CONFIG" ]]; then
44
+ # ─────────────────────────────────────────────────────────────────────────────
45
+ # Resolve credentials: prefer env, fall back to a jira-cli config for
46
+ # server/login.
47
+ #
48
+ # The env-first arm is load-bearing and unchanged: a headless environment that
49
+ # exports JIRA_SERVER and JIRA_LOGIN never opens a config file at all. The
50
+ # resolution below is therefore gated on actually needing it.
51
+ #
52
+ # What changed (CodySwannGT/lisa#2767): the fallback looked only at the
53
+ # developer's own ~/.config/.jira/.config.yml. The setup-jira-cli SessionStart
54
+ # hook writes ${PROJECT_DIR}/.lisa/jira-cli/.config.yml, which nothing read —
55
+ # so on a headless JIRA project with the JIRA_* vars absent, the file Lisa had
56
+ # just written was ignored and this script exited 2. The Lisa-written config is
57
+ # now preferred, with the developer config kept as an announced fallback.
58
+ #
59
+ # PROJECT_DIR uses the same rule as the hook that writes the file:
60
+ # CLAUDE_PROJECT_DIR, then the git toplevel, then pwd. Resolving from the
61
+ # process working directory instead would reintroduce #2768 on the read side.
62
+ #
63
+ # Nothing here writes to ~/.config/.jira — it is read, never created.
64
+ # ─────────────────────────────────────────────────────────────────────────────
65
+ JIRA_CONFIG=""
66
+ if [[ -z "${JIRA_SERVER:-}" || -z "${JIRA_LOGIN:-}" ]]; then
67
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
68
+ if [[ -z "${PROJECT_DIR}" || ! -d "${PROJECT_DIR}" ]]; then
69
+ PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
70
+ fi
71
+ PROJECT_JIRA_CONFIG="${PROJECT_DIR}/.lisa/jira-cli/.config.yml"
72
+ HOME_JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
73
+
74
+ if [[ -f "$PROJECT_JIRA_CONFIG" ]]; then
75
+ JIRA_CONFIG="$PROJECT_JIRA_CONFIG"
76
+ elif [[ -f "$HOME_JIRA_CONFIG" ]]; then
77
+ # Announced, never silent — a quiet fall-through to the developer's own
78
+ # file is how the Lisa-written config stayed unconsumed unnoticed.
79
+ echo "NOTE: no Lisa-written jira-cli config at $PROJECT_JIRA_CONFIG" >&2
80
+ echo " falling back to the developer config at $HOME_JIRA_CONFIG" >&2
81
+ JIRA_CONFIG="$HOME_JIRA_CONFIG"
82
+ else
83
+ echo "NOTE: no jira-cli config at $PROJECT_JIRA_CONFIG" >&2
84
+ echo " or $HOME_JIRA_CONFIG; relying on the environment alone." >&2
85
+ fi
86
+ fi
87
+
88
+ if [[ -z "${JIRA_SERVER:-}" && -n "$JIRA_CONFIG" ]]; then
40
89
  JIRA_SERVER=$(grep '^server:' "$JIRA_CONFIG" | awk '{print $2}')
41
90
  fi
42
- if [[ -z "${JIRA_LOGIN:-}" && -f "$JIRA_CONFIG" ]]; then
91
+ if [[ -z "${JIRA_LOGIN:-}" && -n "$JIRA_CONFIG" ]]; then
43
92
  JIRA_LOGIN=$(grep '^login:' "$JIRA_CONFIG" | awk '{print $2}')
44
93
  fi
45
94
 
@@ -44,6 +44,56 @@ cat >/dev/null 2>&1 || true
44
44
  # one resolution rule, allowed to drift, is what produced the Codex half of
45
45
  # this defect in the first place.
46
46
  # ---------------------------------------------------------------------------
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # WHO READS WHAT THIS WRITES — and why no per-harness env export is needed.
50
+ #
51
+ # `${PROJECT_DIR}/.lisa/jira-cli/.config.yml` had NO reader at all until
52
+ # CodySwannGT/lisa#2767: the hook wrote a file, every consumer looked at
53
+ # `${HOME}/.config/.jira/.config.yml` instead, and the hook was therefore an
54
+ # inert control that reported success while feeding nothing. It now has three
55
+ # consumers, all Lisa-owned:
56
+ #
57
+ # * lisa-jira-evidence/scripts/post-evidence.sh — greps `server:`/`login:`
58
+ # out of this YAML, then passes `--config <path>` to `jira issue move`.
59
+ # * lisa-jira-read-ticket/scripts/download-attachment.sh — greps the same two
60
+ # keys, but ONLY when JIRA_SERVER/JIRA_LOGIN are unset. Env still wins; a
61
+ # headless runner with those exported never opens this file.
62
+ # * SKILL prose (lisa-jira-add-journey, base-rules) — types
63
+ # `jira --config .lisa/jira-cli/.config.yml issue view <KEY>`.
64
+ #
65
+ # #2767 framed the blocking question as "can a SessionStart hook export an
66
+ # environment variable into the agent's later tool invocations, and does that
67
+ # differ per harness?" That question is MOOT for every consumer above, because
68
+ # none of them needs an export:
69
+ #
70
+ # - Two of the three parse this YAML themselves, in Lisa-owned shell.
71
+ # - The one real jira-cli invocation passes `--config`, an ARGUMENT. It
72
+ # crosses no process boundary, so it behaves identically on Claude Code,
73
+ # Codex, Cursor, Copilot, OpenCode and Antigravity. There is no per-harness
74
+ # capability to record because no harness capability is used.
75
+ #
76
+ # The only surface where an export could still have mattered is a freehand
77
+ # `jira ...` an agent types from SKILL prose. That is compensated at the same
78
+ # rung rather than dropped: the prose types `--config` too. `JIRA_CONFIG_FILE`
79
+ # is deliberately exported NOWHERE in Lisa — an unexported variable is another
80
+ # inert control, and the flag makes the export unnecessary.
81
+ #
82
+ # jira-cli's own resolution order, MEASURED against v1.7.0 (darwin/arm64)
83
+ # rather than taken from its README:
84
+ #
85
+ # 1. `--config`/`-c <path>` (highest; accepted either before or
86
+ # after the subcommand)
87
+ # 2. `JIRA_CONFIG_FILE=<path>`
88
+ # 3. `${HOME}/.config/.jira/.config.yml` (default)
89
+ #
90
+ # A path named by (1) or (2) that does not exist FAILS CLOSED: jira-cli prints
91
+ # "Missing configuration file." and exits 1 — it does NOT fall back to (3).
92
+ # That is what makes passing `--config` safe rather than a silent no-op.
93
+ #
94
+ # This hook never writes to `${HOME}/.config/.jira`. That is a developer's
95
+ # personal jira-cli state; consumers read it as an ANNOUNCED fallback only.
96
+ # ---------------------------------------------------------------------------
47
97
  PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
48
98
  if [[ -z "${PROJECT_DIR}" || ! -d "${PROJECT_DIR}" ]]; then
49
99
  PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
@@ -70,7 +70,7 @@ Testing Discipline:
70
70
  JIRA Discipline:
71
71
  - If working on a JIRA issue, make sure the branch you're working on references and is added to the JIRA issue.
72
72
  - If working on a JIRA issue, update the issue as you work through it. For example, if working on a Bug Triage, update the issue with your questions/feedback/suggestions.
73
- - When reading a JIRA issue, always read ALL comments on the ticket — not just the description. Comments contain critical context: stakeholder decisions, scope changes, blockers, triage findings from other repos, and implementation notes. Use the Atlassian MCP or `jira issue view <TICKET_ID> --comments 100` to fetch them.
73
+ - When reading a JIRA issue, always read ALL comments on the ticket — not just the description. Comments contain critical context: stakeholder decisions, scope changes, blockers, triage findings from other repos, and implementation notes. Use the Atlassian MCP or `jira --config .lisa/jira-cli/.config.yml issue view <TICKET_ID> --comments 100` to fetch them (the `--config` pins jira-cli to the config the `setup-jira-cli` hook wrote; drop it to use the machine's own `~/.config/.jira/.config.yml`).
74
74
  - When requesting clarification on a JIRA issue, post the question as a comment using ADF (Atlassian Document Format) and @mention the Reporter so they receive a notification.
75
75
  - When creating JIRA tickets, establish issue link relationships (e.g. "is blocked by", "blocks", "relates to", "is duplicated by") between tickets that have dependencies or logical connections. Do not leave related tickets unlinked. Relationship discovery is mandatory on every create and update — search BOTH the local git history (`git log --all --grep=<keyword>`, `git log -- <path>`) AND Jira (JQL by component, keyword, label, epic siblings) before declaring "no related work." Record the searches you ran and their outcomes in the description (or a comment) so a reviewer can see the search was real.
76
76
  - Ticket scope by type: Bug, Task, and Sub-task tickets MUST be single-repo (one work unit, one repo). Epic, Spike, and Story tickets MAY span multiple repos. If a Bug/Task/Sub-task crosses repos, split it per the `repo-scope-split` rule — at PRD-decomposition time via `task-decomposition` step 1.5 (parent Story + per-repo children); at work-time (an existing ticket an agent is about to implement) via the work-time split procedure (narrow the original to one repo, spin off a sibling per additional repo cloning its metadata, link the producer→consumer dependency, then proceed). A cross-repo work unit is a decomposition error the agent fixes by splitting, not a reason to bounce the ticket to the reporter.
@@ -16,7 +16,12 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
16
16
  ## Prerequisites
17
17
 
18
18
  - `JIRA_API_TOKEN` environment variable set
19
- - `jira-cli` configured (`~/.config/.jira/.config.yml`)
19
+ - `jira-cli` configured. Prefer the config Lisa writes at
20
+ `.lisa/jira-cli/.config.yml` (the `setup-jira-cli` SessionStart hook writes it
21
+ from `JIRA_SERVER` / `JIRA_LOGIN` / `JIRA_PROJECT` on a project whose
22
+ `tracker` is `jira`), and pass it explicitly with `--config`. A developer's
23
+ own `~/.config/.jira/.config.yml` still works as jira-cli's default when no
24
+ `--config` is given.
20
25
 
21
26
  ## Workflow
22
27
 
@@ -25,9 +30,18 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
25
30
  Use the Atlassian MCP or jira-cli to read the full ticket details:
26
31
 
27
32
  ```bash
28
- jira issue view <TICKET_ID>
33
+ # Run from the project root. --config pins jira-cli to the file Lisa's
34
+ # setup-jira-cli hook wrote, instead of the machine's own ~/.config/.jira.
35
+ # jira-cli resolves --config > JIRA_CONFIG_FILE > ~/.config/.jira/.config.yml,
36
+ # and a --config path that does not exist fails closed with "Missing
37
+ # configuration file." rather than silently using the default.
38
+ jira --config .lisa/jira-cli/.config.yml issue view <TICKET_ID>
29
39
  ```
30
40
 
41
+ If `.lisa/jira-cli/.config.yml` does not exist, drop `--config` to fall back to
42
+ the machine's own jira-cli config — but say so in your report rather than
43
+ letting the Lisa-written config go quietly unused.
44
+
31
45
  Extract: title, description, acceptance criteria, components, labels, linked tickets.
32
46
 
33
47
  ### Step 2: Check for Existing Journey
@@ -35,7 +35,10 @@ Upload captured evidence and generated templates to GitHub PR description and JI
35
35
  ## Prerequisites
36
36
 
37
37
  - `JIRA_API_TOKEN` environment variable set
38
- - `jira-cli` configured (`~/.config/.jira/.config.yml`) — server and login are read from there
38
+ - a jira-cli config — `.lisa/jira-cli/.config.yml` if the `setup-jira-cli`
39
+ SessionStart hook wrote one, otherwise `~/.config/.jira/.config.yml`. `server`
40
+ and `login` are read from whichever is used, and the fallback is announced on
41
+ stderr rather than taken silently.
39
42
  - `gh` CLI authenticated
40
43
  - Evidence directory containing:
41
44
  - `NN-name.txt` or `NN-name.json` text evidence files (e.g., `01-health-check.json`)
@@ -66,7 +69,7 @@ bash .claude/skills/jira-evidence/scripts/post-evidence.sh PROJ-123 ./evidence 4
66
69
 
67
70
  ## What It Does
68
71
 
69
- 1. **Read JIRA config** — Reads `~/.config/.jira/.config.yml` to obtain `server` and `login` dynamically
72
+ 1. **Read JIRA config** — Resolves the jira-cli config (`$PROJECT_DIR/.lisa/jira-cli/.config.yml` first, then `~/.config/.jira/.config.yml`, announcing the fallback) and reads `server` and `login` from it dynamically — no hardcoded values. Exits 1 naming both paths when neither exists. The same resolved path is then passed to `jira issue move` as `--config`, so the CLI cannot end up on a different config than the one this script parsed.
70
73
  2. **Upload to GitHub `pr-assets` release** — Uploads evidence files via `gh release upload --clobber`
71
74
  3. **Update PR description** — Replaces or appends the `## Evidence` section in the PR body
72
75
  4. **Post JIRA comment** — Posts `comment.txt` as a new comment (wiki markup with code blocks)
@@ -97,4 +100,4 @@ gh release create pr-assets --title "PR Assets" --notes "CDN for PR evidence"
97
100
 
98
101
  ### JIRA API returns 403
99
102
 
100
- Ensure `JIRA_API_TOKEN` is set and `login` in `~/.config/.jira/.config.yml` matches your Atlassian account email.
103
+ Ensure `JIRA_API_TOKEN` is set and `login` in the resolved jira-cli config (`.lisa/jira-cli/.config.yml`, else `~/.config/.jira/.config.yml`) matches your Atlassian account email.
@@ -6,7 +6,11 @@
6
6
  #
7
7
  # Prerequisites:
8
8
  # - JIRA_API_TOKEN env var set
9
- # - jira-cli configured (~/.config/.jira/.config.yml)
9
+ # - a jira-cli config, resolved in this order (see "CONFIG RESOLUTION" below):
10
+ # 1. ${PROJECT_DIR}/.lisa/jira-cli/.config.yml (written by the
11
+ # setup-jira-cli SessionStart hook from the JIRA_* environment)
12
+ # 2. ~/.config/.jira/.config.yml (a developer's own
13
+ # `jira init` config; announced on stderr when it is used)
10
14
  # - gh CLI authenticated
11
15
  #
12
16
  # What it does:
@@ -23,9 +27,50 @@ TICKET_ID="${1:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
23
27
  EVIDENCE_DIR="${2:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
24
28
  PR_NUMBER="${3:?Usage: post-evidence.sh <TICKET_ID> <EVIDENCE_DIR> <PR_NUMBER>}"
25
29
 
26
- JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
27
- if [[ ! -f "$JIRA_CONFIG" ]]; then
28
- echo "ERROR: jira-cli config not found at $JIRA_CONFIG — run 'jira init' first" >&2
30
+ # ─────────────────────────────────────────────────────────────────────────────
31
+ # CONFIG RESOLUTION
32
+ #
33
+ # The setup-jira-cli SessionStart hook writes ${PROJECT_DIR}/.lisa/jira-cli/
34
+ # .config.yml. Nothing read it — this script looked only at the developer's own
35
+ # ~/.config/.jira/.config.yml and exited 1 telling the operator to run
36
+ # `jira init`, so on a headless JIRA project the hook was an inert control.
37
+ # See CodySwannGT/lisa#2767.
38
+ #
39
+ # PROJECT_DIR is resolved with the same rule as the hook that writes the file,
40
+ # deliberately character-for-character: CLAUDE_PROJECT_DIR (the harness's own
41
+ # declaration of the root, inert on harnesses that never set it), then the git
42
+ # toplevel, then pwd. A session launched from a subdirectory otherwise reads a
43
+ # directory it never wrote — the #2768 defect, on the read side.
44
+ #
45
+ # Nothing here writes to ~/.config/.jira. That file is a developer's personal
46
+ # jira-cli state; it is read as a fallback and never created or modified.
47
+ #
48
+ # NOTE: the `.lisa.config.json` reads in Step 5 below are still resolved from
49
+ # the process working directory. That is pre-existing and out of scope here.
50
+ # ─────────────────────────────────────────────────────────────────────────────
51
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
52
+ if [[ -z "${PROJECT_DIR}" || ! -d "${PROJECT_DIR}" ]]; then
53
+ PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
54
+ fi
55
+ PROJECT_JIRA_CONFIG="${PROJECT_DIR}/.lisa/jira-cli/.config.yml"
56
+ HOME_JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
57
+
58
+ if [[ -f "$PROJECT_JIRA_CONFIG" ]]; then
59
+ JIRA_CONFIG="$PROJECT_JIRA_CONFIG"
60
+ elif [[ -f "$HOME_JIRA_CONFIG" ]]; then
61
+ # Announced, never silent. A silent fall-through to the developer's own file
62
+ # is precisely how the Lisa-written config stayed unconsumed without anyone
63
+ # noticing, and on a headless runner there is no such file to fall back to.
64
+ echo "NOTE: no Lisa-written jira-cli config at $PROJECT_JIRA_CONFIG" >&2
65
+ echo " falling back to the developer config at $HOME_JIRA_CONFIG" >&2
66
+ JIRA_CONFIG="$HOME_JIRA_CONFIG"
67
+ else
68
+ echo "ERROR: jira-cli config not found." >&2
69
+ echo " Lisa-written config (expected): $PROJECT_JIRA_CONFIG" >&2
70
+ echo " developer config (fallback): $HOME_JIRA_CONFIG" >&2
71
+ echo " Fix: export JIRA_SERVER, JIRA_LOGIN (and JIRA_INSTALLATION," >&2
72
+ echo " JIRA_PROJECT) and start a new session so the setup-jira-cli hook" >&2
73
+ echo " writes the project config — or run 'jira init' locally." >&2
29
74
  exit 1
30
75
  fi
31
76
  JIRA_SERVER=$(grep '^server:' "$JIRA_CONFIG" | awk '{print $2}')
@@ -169,7 +214,13 @@ fi
169
214
  echo ""
170
215
  if [ -n "$REVIEW" ]; then
171
216
  echo "==> Moving $TICKET_ID to $REVIEW..."
172
- jira issue move "$TICKET_ID" "$REVIEW" 2>&1 && echo " ✓ Ticket moved to $REVIEW" || echo " WARNING: Could not move ticket to $REVIEW (not a valid transition?); leaving in current status" >&2
217
+ # --config pins jira-cli to the same file this script parsed above.
218
+ # jira-cli resolves --config > JIRA_CONFIG_FILE > ~/.config/.jira/
219
+ # .config.yml, and a --config path that does not exist fails closed
220
+ # rather than falling back (measured against jira-cli v1.7.0). The flag
221
+ # needs no environment export, so this works identically on every
222
+ # harness — see the harness note in the setup-jira-cli hook.
223
+ jira --config "$JIRA_CONFIG" issue move "$TICKET_ID" "$REVIEW" 2>&1 && echo " ✓ Ticket moved to $REVIEW" || echo " WARNING: Could not move ticket to $REVIEW (not a valid transition?); leaving in current status" >&2
173
224
  else
174
225
  echo "==> No jira.workflow.review configured; leaving $TICKET_ID in its current (claimed) status per config-resolution."
175
226
  fi
@@ -20,7 +20,8 @@ Parse a JIRA ticket's Validation Journey, execute the verification steps using t
20
20
  ## Prerequisites
21
21
 
22
22
  - `JIRA_API_TOKEN` environment variable set
23
- - `jira-cli` configured (`~/.config/.jira/.config.yml`)
23
+ - `jira-cli` configured — `.lisa/jira-cli/.config.yml` (written by the
24
+ `setup-jira-cli` SessionStart hook) or `~/.config/.jira/.config.yml`
24
25
  - `gh` CLI authenticated
25
26
  - Appropriate services running for the verification type (dev server, database, etc.)
26
27
 
@@ -19,6 +19,13 @@
19
19
  # JIRA_LOGIN - login email
20
20
  # JIRA_API_TOKEN - API token (https://id.atlassian.com/manage-profile/security/api-tokens)
21
21
  #
22
+ # JIRA_SERVER and JIRA_LOGIN each fall back to a jira-cli config when unset:
23
+ # ${PROJECT_DIR}/.lisa/jira-cli/.config.yml (written by the setup-jira-cli
24
+ # SessionStart hook) first, then ${HOME}/.config/.jira/.config.yml, with the
25
+ # fallback announced on stderr. When BOTH env vars are set, no config file is
26
+ # opened at all. JIRA_API_TOKEN has no config fallback — it is a secret and
27
+ # is never written to the jira-cli config.
28
+ #
22
29
  # Exit codes:
23
30
  # 0 success
24
31
  # 1 download failed (HTTP error)
@@ -34,12 +41,54 @@ fi
34
41
  ID_OR_URL="$1"
35
42
  OUTPUT_PATH="$2"
36
43
 
37
- # Resolve credentials: prefer env, fall back to jira-cli config for server/login.
38
- JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
39
- if [[ -z "${JIRA_SERVER:-}" && -f "$JIRA_CONFIG" ]]; then
44
+ # ─────────────────────────────────────────────────────────────────────────────
45
+ # Resolve credentials: prefer env, fall back to a jira-cli config for
46
+ # server/login.
47
+ #
48
+ # The env-first arm is load-bearing and unchanged: a headless environment that
49
+ # exports JIRA_SERVER and JIRA_LOGIN never opens a config file at all. The
50
+ # resolution below is therefore gated on actually needing it.
51
+ #
52
+ # What changed (CodySwannGT/lisa#2767): the fallback looked only at the
53
+ # developer's own ~/.config/.jira/.config.yml. The setup-jira-cli SessionStart
54
+ # hook writes ${PROJECT_DIR}/.lisa/jira-cli/.config.yml, which nothing read —
55
+ # so on a headless JIRA project with the JIRA_* vars absent, the file Lisa had
56
+ # just written was ignored and this script exited 2. The Lisa-written config is
57
+ # now preferred, with the developer config kept as an announced fallback.
58
+ #
59
+ # PROJECT_DIR uses the same rule as the hook that writes the file:
60
+ # CLAUDE_PROJECT_DIR, then the git toplevel, then pwd. Resolving from the
61
+ # process working directory instead would reintroduce #2768 on the read side.
62
+ #
63
+ # Nothing here writes to ~/.config/.jira — it is read, never created.
64
+ # ─────────────────────────────────────────────────────────────────────────────
65
+ JIRA_CONFIG=""
66
+ if [[ -z "${JIRA_SERVER:-}" || -z "${JIRA_LOGIN:-}" ]]; then
67
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
68
+ if [[ -z "${PROJECT_DIR}" || ! -d "${PROJECT_DIR}" ]]; then
69
+ PROJECT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
70
+ fi
71
+ PROJECT_JIRA_CONFIG="${PROJECT_DIR}/.lisa/jira-cli/.config.yml"
72
+ HOME_JIRA_CONFIG="${HOME}/.config/.jira/.config.yml"
73
+
74
+ if [[ -f "$PROJECT_JIRA_CONFIG" ]]; then
75
+ JIRA_CONFIG="$PROJECT_JIRA_CONFIG"
76
+ elif [[ -f "$HOME_JIRA_CONFIG" ]]; then
77
+ # Announced, never silent — a quiet fall-through to the developer's own
78
+ # file is how the Lisa-written config stayed unconsumed unnoticed.
79
+ echo "NOTE: no Lisa-written jira-cli config at $PROJECT_JIRA_CONFIG" >&2
80
+ echo " falling back to the developer config at $HOME_JIRA_CONFIG" >&2
81
+ JIRA_CONFIG="$HOME_JIRA_CONFIG"
82
+ else
83
+ echo "NOTE: no jira-cli config at $PROJECT_JIRA_CONFIG" >&2
84
+ echo " or $HOME_JIRA_CONFIG; relying on the environment alone." >&2
85
+ fi
86
+ fi
87
+
88
+ if [[ -z "${JIRA_SERVER:-}" && -n "$JIRA_CONFIG" ]]; then
40
89
  JIRA_SERVER=$(grep '^server:' "$JIRA_CONFIG" | awk '{print $2}')
41
90
  fi
42
- if [[ -z "${JIRA_LOGIN:-}" && -f "$JIRA_CONFIG" ]]; then
91
+ if [[ -z "${JIRA_LOGIN:-}" && -n "$JIRA_CONFIG" ]]; then
43
92
  JIRA_LOGIN=$(grep '^login:' "$JIRA_CONFIG" | awk '{print $2}')
44
93
  fi
45
94
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.10.5",
3
+ "version": "4.10.6",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -16,7 +16,12 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
16
16
  ## Prerequisites
17
17
 
18
18
  - `JIRA_API_TOKEN` environment variable set
19
- - `jira-cli` configured (`~/.config/.jira/.config.yml`)
19
+ - `jira-cli` configured. Prefer the config Lisa writes at
20
+ `.lisa/jira-cli/.config.yml` (the `setup-jira-cli` SessionStart hook writes it
21
+ from `JIRA_SERVER` / `JIRA_LOGIN` / `JIRA_PROJECT` on a project whose
22
+ `tracker` is `jira`), and pass it explicitly with `--config`. A developer's
23
+ own `~/.config/.jira/.config.yml` still works as jira-cli's default when no
24
+ `--config` is given.
20
25
 
21
26
  ## Workflow
22
27
 
@@ -25,9 +30,18 @@ Read an existing JIRA ticket, analyze the change type, and generate a Validation
25
30
  Use the Atlassian MCP or jira-cli to read the full ticket details:
26
31
 
27
32
  ```bash
28
- jira issue view <TICKET_ID>
33
+ # Run from the project root. --config pins jira-cli to the file Lisa's
34
+ # setup-jira-cli hook wrote, instead of the machine's own ~/.config/.jira.
35
+ # jira-cli resolves --config > JIRA_CONFIG_FILE > ~/.config/.jira/.config.yml,
36
+ # and a --config path that does not exist fails closed with "Missing
37
+ # configuration file." rather than silently using the default.
38
+ jira --config .lisa/jira-cli/.config.yml issue view <TICKET_ID>
29
39
  ```
30
40
 
41
+ If `.lisa/jira-cli/.config.yml` does not exist, drop `--config` to fall back to
42
+ the machine's own jira-cli config — but say so in your report rather than
43
+ letting the Lisa-written config go quietly unused.
44
+
31
45
  Extract: title, description, acceptance criteria, components, labels, linked tickets.
32
46
 
33
47
  ### Step 2: Check for Existing Journey