@howlil/ez-agents 2.0.0 → 3.0.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.
Files changed (145) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +157 -110
  3. package/README.zh-CN.md +84 -84
  4. package/agents/ez-plan-checker.md +2 -2
  5. package/agents/ez-research-synthesizer.md +1 -1
  6. package/agents/ez-ui-auditor.md +0 -2
  7. package/agents/ez-ui-checker.md +2 -4
  8. package/agents/ez-ui-researcher.md +0 -2
  9. package/agents/ez-verifier.md +1 -1
  10. package/bin/install.js +211 -211
  11. package/commands/ez/debug.md +1 -1
  12. package/commands/ez/map-codebase.md +1 -1
  13. package/commands/ez/reapply-patches.md +3 -3
  14. package/commands/ez/research-phase.md +1 -1
  15. package/{get-shit-done → ez-agents}/bin/ez-tools.cjs +1 -1
  16. package/{get-shit-done → ez-agents}/bin/lib/assistant-adapter.cjs +205 -205
  17. package/{get-shit-done → ez-agents}/bin/lib/audit-exec.cjs +150 -150
  18. package/{get-shit-done → ez-agents}/bin/lib/auth.cjs +175 -175
  19. package/{get-shit-done → ez-agents}/bin/lib/circuit-breaker.cjs +118 -118
  20. package/{get-shit-done → ez-agents}/bin/lib/commands.cjs +666 -666
  21. package/{get-shit-done → ez-agents}/bin/lib/config.cjs +183 -183
  22. package/{get-shit-done → ez-agents}/bin/lib/core.cjs +495 -495
  23. package/{get-shit-done → ez-agents}/bin/lib/file-lock.cjs +236 -236
  24. package/{get-shit-done → ez-agents}/bin/lib/frontmatter.cjs +299 -299
  25. package/{get-shit-done → ez-agents}/bin/lib/fs-utils.cjs +153 -153
  26. package/{get-shit-done → ez-agents}/bin/lib/git-utils.cjs +203 -203
  27. package/{get-shit-done → ez-agents}/bin/lib/health-check.cjs +163 -163
  28. package/{get-shit-done → ez-agents}/bin/lib/index.cjs +113 -113
  29. package/{get-shit-done → ez-agents}/bin/lib/init.cjs +710 -710
  30. package/{get-shit-done → ez-agents}/bin/lib/logger.cjs +117 -117
  31. package/{get-shit-done → ez-agents}/bin/lib/milestone.cjs +241 -241
  32. package/{get-shit-done → ez-agents}/bin/lib/model-provider.cjs +146 -146
  33. package/{get-shit-done → ez-agents}/bin/lib/phase.cjs +908 -908
  34. package/{get-shit-done → ez-agents}/bin/lib/retry.cjs +119 -119
  35. package/{get-shit-done → ez-agents}/bin/lib/roadmap.cjs +305 -305
  36. package/{get-shit-done → ez-agents}/bin/lib/safe-exec.cjs +128 -128
  37. package/{get-shit-done → ez-agents}/bin/lib/safe-path.cjs +130 -130
  38. package/{get-shit-done → ez-agents}/bin/lib/state.cjs +721 -721
  39. package/{get-shit-done → ez-agents}/bin/lib/temp-file.cjs +239 -239
  40. package/{get-shit-done → ez-agents}/bin/lib/template.cjs +222 -222
  41. package/{get-shit-done → ez-agents}/bin/lib/test-file-lock.cjs +112 -112
  42. package/{get-shit-done → ez-agents}/bin/lib/test-graceful.cjs +93 -93
  43. package/{get-shit-done → ez-agents}/bin/lib/test-logger.cjs +60 -60
  44. package/{get-shit-done → ez-agents}/bin/lib/test-safe-exec.cjs +38 -38
  45. package/{get-shit-done → ez-agents}/bin/lib/test-safe-path.cjs +33 -33
  46. package/{get-shit-done → ez-agents}/bin/lib/test-temp-file.cjs +125 -125
  47. package/{get-shit-done → ez-agents}/bin/lib/timeout-exec.cjs +62 -62
  48. package/{get-shit-done → ez-agents}/bin/lib/verify.cjs +820 -820
  49. package/{get-shit-done → ez-agents}/references/checkpoints.md +776 -776
  50. package/{get-shit-done → ez-agents}/references/questioning.md +162 -162
  51. package/{get-shit-done → ez-agents}/references/tdd.md +263 -263
  52. package/{get-shit-done → ez-agents}/templates/codebase/concerns.md +310 -310
  53. package/{get-shit-done → ez-agents}/templates/codebase/conventions.md +307 -307
  54. package/{get-shit-done → ez-agents}/templates/codebase/integrations.md +280 -280
  55. package/{get-shit-done → ez-agents}/templates/codebase/stack.md +186 -186
  56. package/{get-shit-done → ez-agents}/templates/codebase/testing.md +480 -480
  57. package/{get-shit-done → ez-agents}/templates/config.json +37 -37
  58. package/{get-shit-done → ez-agents}/templates/continue-here.md +78 -78
  59. package/{get-shit-done → ez-agents}/templates/milestone-archive.md +123 -123
  60. package/{get-shit-done → ez-agents}/templates/milestone.md +115 -115
  61. package/{get-shit-done → ez-agents}/templates/requirements.md +231 -231
  62. package/{get-shit-done → ez-agents}/templates/research-project/ARCHITECTURE.md +204 -204
  63. package/{get-shit-done → ez-agents}/templates/research-project/FEATURES.md +147 -147
  64. package/{get-shit-done → ez-agents}/templates/research-project/PITFALLS.md +200 -200
  65. package/{get-shit-done → ez-agents}/templates/research-project/STACK.md +120 -120
  66. package/{get-shit-done → ez-agents}/templates/research-project/SUMMARY.md +170 -170
  67. package/{get-shit-done → ez-agents}/templates/retrospective.md +54 -54
  68. package/{get-shit-done → ez-agents}/templates/roadmap.md +202 -202
  69. package/{get-shit-done → ez-agents}/templates/summary-minimal.md +41 -41
  70. package/{get-shit-done → ez-agents}/templates/summary-standard.md +48 -48
  71. package/{get-shit-done → ez-agents}/templates/summary.md +248 -248
  72. package/{get-shit-done → ez-agents}/templates/user-setup.md +311 -311
  73. package/{get-shit-done → ez-agents}/templates/verification-report.md +322 -322
  74. package/{get-shit-done → ez-agents}/workflows/add-phase.md +112 -112
  75. package/{get-shit-done → ez-agents}/workflows/add-tests.md +351 -351
  76. package/{get-shit-done → ez-agents}/workflows/add-todo.md +158 -158
  77. package/{get-shit-done → ez-agents}/workflows/audit-milestone.md +332 -332
  78. package/{get-shit-done → ez-agents}/workflows/autonomous.md +743 -743
  79. package/{get-shit-done → ez-agents}/workflows/check-todos.md +177 -177
  80. package/{get-shit-done → ez-agents}/workflows/cleanup.md +152 -152
  81. package/{get-shit-done → ez-agents}/workflows/complete-milestone.md +766 -766
  82. package/ez-agents/workflows/debug.md +0 -0
  83. package/{get-shit-done → ez-agents}/workflows/diagnose-issues.md +219 -219
  84. package/{get-shit-done → ez-agents}/workflows/discovery-phase.md +289 -289
  85. package/{get-shit-done → ez-agents}/workflows/discuss-phase.md +762 -762
  86. package/{get-shit-done → ez-agents}/workflows/execute-phase.md +468 -468
  87. package/{get-shit-done → ez-agents}/workflows/execute-plan.md +483 -483
  88. package/{get-shit-done → ez-agents}/workflows/health.md +159 -159
  89. package/{get-shit-done → ez-agents}/workflows/help.md +492 -492
  90. package/{get-shit-done → ez-agents}/workflows/insert-phase.md +130 -130
  91. package/{get-shit-done → ez-agents}/workflows/list-phase-assumptions.md +178 -178
  92. package/{get-shit-done → ez-agents}/workflows/map-codebase.md +316 -316
  93. package/{get-shit-done → ez-agents}/workflows/new-milestone.md +384 -384
  94. package/{get-shit-done → ez-agents}/workflows/new-project.md +1111 -1111
  95. package/{get-shit-done → ez-agents}/workflows/node-repair.md +92 -92
  96. package/{get-shit-done → ez-agents}/workflows/pause-work.md +122 -122
  97. package/{get-shit-done → ez-agents}/workflows/plan-milestone-gaps.md +274 -274
  98. package/{get-shit-done → ez-agents}/workflows/plan-phase.md +651 -651
  99. package/{get-shit-done → ez-agents}/workflows/progress.md +382 -382
  100. package/{get-shit-done → ez-agents}/workflows/quick.md +610 -610
  101. package/{get-shit-done → ez-agents}/workflows/remove-phase.md +155 -155
  102. package/{get-shit-done → ez-agents}/workflows/research-phase.md +74 -74
  103. package/{get-shit-done → ez-agents}/workflows/resume-project.md +307 -307
  104. package/{get-shit-done → ez-agents}/workflows/set-profile.md +81 -81
  105. package/{get-shit-done → ez-agents}/workflows/settings.md +242 -242
  106. package/{get-shit-done → ez-agents}/workflows/stats.md +57 -57
  107. package/{get-shit-done → ez-agents}/workflows/transition.md +544 -544
  108. package/{get-shit-done → ez-agents}/workflows/ui-phase.md +290 -290
  109. package/{get-shit-done → ez-agents}/workflows/ui-review.md +157 -157
  110. package/{get-shit-done → ez-agents}/workflows/update.md +320 -320
  111. package/{get-shit-done → ez-agents}/workflows/validate-phase.md +167 -167
  112. package/{get-shit-done → ez-agents}/workflows/verify-phase.md +243 -243
  113. package/{get-shit-done → ez-agents}/workflows/verify-work.md +5 -5
  114. package/hooks/dist/ez-check-update.js +81 -0
  115. package/hooks/dist/ez-context-monitor.js +141 -0
  116. package/hooks/dist/ez-statusline.js +115 -0
  117. package/package.json +13 -3
  118. package/scripts/build-hooks.js +43 -43
  119. package/scripts/run-tests.cjs +29 -29
  120. /package/{get-shit-done → ez-agents}/references/continuation-format.md +0 -0
  121. /package/{get-shit-done → ez-agents}/references/decimal-phase-calculation.md +0 -0
  122. /package/{get-shit-done → ez-agents}/references/git-integration.md +0 -0
  123. /package/{get-shit-done → ez-agents}/references/git-planning-commit.md +0 -0
  124. /package/{get-shit-done → ez-agents}/references/model-profile-resolution.md +0 -0
  125. /package/{get-shit-done → ez-agents}/references/model-profiles.md +0 -0
  126. /package/{get-shit-done → ez-agents}/references/phase-argument-parsing.md +0 -0
  127. /package/{get-shit-done → ez-agents}/references/planning-config.md +0 -0
  128. /package/{get-shit-done → ez-agents}/references/ui-brand.md +0 -0
  129. /package/{get-shit-done → ez-agents}/references/verification-patterns.md +0 -0
  130. /package/{get-shit-done → ez-agents}/templates/DEBUG.md +0 -0
  131. /package/{get-shit-done → ez-agents}/templates/UAT.md +0 -0
  132. /package/{get-shit-done → ez-agents}/templates/UI-SPEC.md +0 -0
  133. /package/{get-shit-done → ez-agents}/templates/VALIDATION.md +0 -0
  134. /package/{get-shit-done → ez-agents}/templates/codebase/architecture.md +0 -0
  135. /package/{get-shit-done → ez-agents}/templates/codebase/structure.md +0 -0
  136. /package/{get-shit-done → ez-agents}/templates/context.md +0 -0
  137. /package/{get-shit-done → ez-agents}/templates/copilot-instructions.md +0 -0
  138. /package/{get-shit-done → ez-agents}/templates/debug-subagent-prompt.md +0 -0
  139. /package/{get-shit-done → ez-agents}/templates/discovery.md +0 -0
  140. /package/{get-shit-done → ez-agents}/templates/phase-prompt.md +0 -0
  141. /package/{get-shit-done → ez-agents}/templates/planner-subagent-prompt.md +0 -0
  142. /package/{get-shit-done → ez-agents}/templates/project.md +0 -0
  143. /package/{get-shit-done → ez-agents}/templates/research.md +0 -0
  144. /package/{get-shit-done → ez-agents}/templates/state.md +0 -0
  145. /package/{get-shit-done → ez-agents}/templates/summary-complex.md +0 -0
@@ -1,320 +1,320 @@
1
- <purpose>
2
- Check for GSD updates via npm, display changelog for versions between installed and latest, obtain user confirmation, and execute clean installation with cache clearing.
3
- </purpose>
4
-
5
- <required_reading>
6
- Read all files referenced by the invoking prompt's execution_context before starting.
7
- </required_reading>
8
-
9
- <process>
10
-
11
- <step name="get_installed_version">
12
- Detect whether GSD is installed locally or globally by checking both locations and validating install integrity.
13
-
14
- First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
15
- - Path contains `/.codex/` -> `codex`
16
- - Path contains `/.gemini/` -> `gemini`
17
- - Path contains `/.config/opencode/` or `/.opencode/` -> `opencode`
18
- - Otherwise -> `claude`
19
-
20
- Use `PREFERRED_RUNTIME` as the first runtime checked so `/ez:update` targets the runtime that invoked it.
21
-
22
- ```bash
23
- # Runtime candidates: "<runtime>:<config-dir>"
24
- RUNTIME_DIRS="claude:.claude opencode:.config/opencode opencode:.opencode gemini:.gemini codex:.codex"
25
-
26
- # PREFERRED_RUNTIME should be set from execution_context before running this block.
27
- # If not set, infer from runtime env vars; fallback to claude.
28
- if [ -z "$PREFERRED_RUNTIME" ]; then
29
- if [ -n "$CODEX_HOME" ]; then
30
- PREFERRED_RUNTIME="codex"
31
- elif [ -n "$GEMINI_CONFIG_DIR" ]; then
32
- PREFERRED_RUNTIME="gemini"
33
- elif [ -n "$OPENCODE_CONFIG_DIR" ] || [ -n "$OPENCODE_CONFIG" ]; then
34
- PREFERRED_RUNTIME="opencode"
35
- elif [ -n "$CLAUDE_CONFIG_DIR" ]; then
36
- PREFERRED_RUNTIME="claude"
37
- else
38
- PREFERRED_RUNTIME="claude"
39
- fi
40
- fi
41
-
42
- # Reorder entries so preferred runtime is checked first.
43
- ORDERED_RUNTIME_DIRS=""
44
- for entry in $RUNTIME_DIRS; do
45
- runtime="${entry%%:*}"
46
- if [ "$runtime" = "$PREFERRED_RUNTIME" ]; then
47
- ORDERED_RUNTIME_DIRS="$ORDERED_RUNTIME_DIRS $entry"
48
- fi
49
- done
50
- for entry in $RUNTIME_DIRS; do
51
- runtime="${entry%%:*}"
52
- if [ "$runtime" != "$PREFERRED_RUNTIME" ]; then
53
- ORDERED_RUNTIME_DIRS="$ORDERED_RUNTIME_DIRS $entry"
54
- fi
55
- done
56
-
57
- # Check local first (takes priority only if valid and distinct from global)
58
- LOCAL_VERSION_FILE="" LOCAL_MARKER_FILE="" LOCAL_DIR="" LOCAL_RUNTIME=""
59
- for entry in $ORDERED_RUNTIME_DIRS; do
60
- runtime="${entry%%:*}"
61
- dir="${entry#*:}"
62
- if [ -f "./$dir/get-shit-done/VERSION" ] || [ -f "./$dir/get-shit-done/workflows/update.md" ]; then
63
- LOCAL_RUNTIME="$runtime"
64
- LOCAL_VERSION_FILE="./$dir/get-shit-done/VERSION"
65
- LOCAL_MARKER_FILE="./$dir/get-shit-done/workflows/update.md"
66
- LOCAL_DIR="$(cd "./$dir" 2>/dev/null && pwd)"
67
- break
68
- fi
69
- done
70
-
71
- GLOBAL_VERSION_FILE="" GLOBAL_MARKER_FILE="" GLOBAL_DIR="" GLOBAL_RUNTIME=""
72
- for entry in $ORDERED_RUNTIME_DIRS; do
73
- runtime="${entry%%:*}"
74
- dir="${entry#*:}"
75
- if [ -f "$HOME/$dir/get-shit-done/VERSION" ] || [ -f "$HOME/$dir/get-shit-done/workflows/update.md" ]; then
76
- GLOBAL_RUNTIME="$runtime"
77
- GLOBAL_VERSION_FILE="$HOME/$dir/get-shit-done/VERSION"
78
- GLOBAL_MARKER_FILE="$HOME/$dir/get-shit-done/workflows/update.md"
79
- GLOBAL_DIR="$(cd "$HOME/$dir" 2>/dev/null && pwd)"
80
- break
81
- fi
82
- done
83
-
84
- # Only treat as LOCAL if the resolved paths differ (prevents misdetection when CWD=$HOME)
85
- IS_LOCAL=false
86
- if [ -n "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$LOCAL_VERSION_FILE"; then
87
- if [ -z "$GLOBAL_DIR" ] || [ "$LOCAL_DIR" != "$GLOBAL_DIR" ]; then
88
- IS_LOCAL=true
89
- fi
90
- fi
91
-
92
- if [ "$IS_LOCAL" = true ]; then
93
- INSTALLED_VERSION="$(cat "$LOCAL_VERSION_FILE")"
94
- INSTALL_SCOPE="LOCAL"
95
- TARGET_RUNTIME="$LOCAL_RUNTIME"
96
- elif [ -n "$GLOBAL_VERSION_FILE" ] && [ -f "$GLOBAL_VERSION_FILE" ] && [ -f "$GLOBAL_MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$GLOBAL_VERSION_FILE"; then
97
- INSTALLED_VERSION="$(cat "$GLOBAL_VERSION_FILE")"
98
- INSTALL_SCOPE="GLOBAL"
99
- TARGET_RUNTIME="$GLOBAL_RUNTIME"
100
- elif [ -n "$LOCAL_RUNTIME" ] && [ -f "$LOCAL_MARKER_FILE" ]; then
101
- # Runtime detected but VERSION missing/corrupt: treat as unknown version, keep runtime target
102
- INSTALLED_VERSION="0.0.0"
103
- INSTALL_SCOPE="LOCAL"
104
- TARGET_RUNTIME="$LOCAL_RUNTIME"
105
- elif [ -n "$GLOBAL_RUNTIME" ] && [ -f "$GLOBAL_MARKER_FILE" ]; then
106
- INSTALLED_VERSION="0.0.0"
107
- INSTALL_SCOPE="GLOBAL"
108
- TARGET_RUNTIME="$GLOBAL_RUNTIME"
109
- else
110
- INSTALLED_VERSION="0.0.0"
111
- INSTALL_SCOPE="UNKNOWN"
112
- TARGET_RUNTIME="claude"
113
- fi
114
-
115
- echo "$INSTALLED_VERSION"
116
- echo "$INSTALL_SCOPE"
117
- echo "$TARGET_RUNTIME"
118
- ```
119
-
120
- Parse output:
121
- - Line 1 = installed version (`0.0.0` means unknown version)
122
- - Line 2 = install scope (`LOCAL`, `GLOBAL`, or `UNKNOWN`)
123
- - Line 3 = target runtime (`claude`, `opencode`, `gemini`, or `codex`)
124
- - If scope is `UNKNOWN`, proceed to install step using `--claude --global` fallback.
125
-
126
- If multiple runtime installs are detected and the invoking runtime cannot be determined from execution_context, ask the user which runtime to update before running install.
127
-
128
- **If VERSION file missing:**
129
- ```
130
- ## GSD Update
131
-
132
- **Installed version:** Unknown
133
-
134
- Your installation doesn't include version tracking.
135
-
136
- Running fresh install...
137
- ```
138
-
139
- Proceed to install step (treat as version 0.0.0 for comparison).
140
- </step>
141
-
142
- <step name="check_latest_version">
143
- Check npm for latest version:
144
-
145
- ```bash
146
- npm view get-shit-done-cc version 2>/dev/null
147
- ```
148
-
149
- **If npm check fails:**
150
- ```
151
- Couldn't check for updates (offline or npm unavailable).
152
-
153
- To update manually: `npx get-shit-done-cc --global`
154
- ```
155
-
156
- Exit.
157
- </step>
158
-
159
- <step name="compare_versions">
160
- Compare installed vs latest:
161
-
162
- **If installed == latest:**
163
- ```
164
- ## GSD Update
165
-
166
- **Installed:** X.Y.Z
167
- **Latest:** X.Y.Z
168
-
169
- You're already on the latest version.
170
- ```
171
-
172
- Exit.
173
-
174
- **If installed > latest:**
175
- ```
176
- ## GSD Update
177
-
178
- **Installed:** X.Y.Z
179
- **Latest:** A.B.C
180
-
181
- You're ahead of the latest release (development version?).
182
- ```
183
-
184
- Exit.
185
- </step>
186
-
187
- <step name="show_changes_and_confirm">
188
- **If update available**, fetch and show what's new BEFORE updating:
189
-
190
- 1. Fetch changelog from GitHub raw URL
191
- 2. Extract entries between installed and latest versions
192
- 3. Display preview and ask for confirmation:
193
-
194
- ```
195
- ## GSD Update Available
196
-
197
- **Installed:** 1.5.10
198
- **Latest:** 1.5.15
199
-
200
- ### What's New
201
- ────────────────────────────────────────────────────────────
202
-
203
- ## [1.5.15] - 2026-01-20
204
-
205
- ### Added
206
- - Feature X
207
-
208
- ## [1.5.14] - 2026-01-18
209
-
210
- ### Fixed
211
- - Bug fix Y
212
-
213
- ────────────────────────────────────────────────────────────
214
-
215
- ⚠️ **Note:** The installer performs a clean install of GSD folders:
216
- - `commands/gsd/` will be wiped and replaced
217
- - `get-shit-done/` will be wiped and replaced
218
- - `agents/gsd-*` files will be replaced
219
-
220
- (Paths are relative to detected runtime install location:
221
- global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, or `~/.codex/`
222
- local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, or `./.codex/`)
223
-
224
- Your custom files in other locations are preserved:
225
- - Custom commands not in `commands/gsd/` ✓
226
- - Custom agents not prefixed with `gsd-` ✓
227
- - Custom hooks ✓
228
- - Your CLAUDE.md files ✓
229
-
230
- If you've modified any GSD files directly, they'll be automatically backed up to `gsd-local-patches/` and can be reapplied with `/ez:reapply-patches` after the update.
231
- ```
232
-
233
- Use AskUserQuestion:
234
- - Question: "Proceed with update?"
235
- - Options:
236
- - "Yes, update now"
237
- - "No, cancel"
238
-
239
- **If user cancels:** Exit.
240
- </step>
241
-
242
- <step name="run_update">
243
- Run the update using the install type detected in step 1:
244
-
245
- Build runtime flag from step 1:
246
- ```bash
247
- RUNTIME_FLAG="--$TARGET_RUNTIME"
248
- ```
249
-
250
- **If LOCAL install:**
251
- ```bash
252
- npx -y get-shit-done-cc@latest "$RUNTIME_FLAG" --local
253
- ```
254
-
255
- **If GLOBAL install:**
256
- ```bash
257
- npx -y get-shit-done-cc@latest "$RUNTIME_FLAG" --global
258
- ```
259
-
260
- **If UNKNOWN install:**
261
- ```bash
262
- npx -y get-shit-done-cc@latest --claude --global
263
- ```
264
-
265
- Capture output. If install fails, show error and exit.
266
-
267
- Clear the update cache so statusline indicator disappears:
268
-
269
- ```bash
270
- # Clear update cache across all runtime directories
271
- for dir in .claude .config/opencode .opencode .gemini .codex; do
272
- rm -f "./$dir/cache/gsd-update-check.json"
273
- rm -f "$HOME/$dir/cache/gsd-update-check.json"
274
- done
275
- ```
276
-
277
- The SessionStart hook (`gsd-check-update.js`) writes to the detected runtime's cache directory, so all paths must be cleared to prevent stale update indicators.
278
- </step>
279
-
280
- <step name="display_result">
281
- Format completion message (changelog was already shown in confirmation step):
282
-
283
- ```
284
- ╔═══════════════════════════════════════════════════════════╗
285
- GSD Updated: v1.5.10 → v1.5.15
286
- ╚═══════════════════════════════════════════════════════════╝
287
-
288
- ⚠️ Restart your runtime to pick up the new commands.
289
-
290
- [View full changelog](https://github.com/glittercowboy/get-shit-done/blob/main/CHANGELOG.md)
291
- ```
292
- </step>
293
-
294
-
295
- <step name="check_local_patches">
296
- After update completes, check if the installer detected and backed up any locally modified files:
297
-
298
- Check for gsd-local-patches/backup-meta.json in the config directory.
299
-
300
- **If patches found:**
301
-
302
- ```
303
- Local patches were backed up before the update.
304
- Run /ez:reapply-patches to merge your modifications into the new version.
305
- ```
306
-
307
- **If no patches:** Continue normally.
308
- </step>
309
- </process>
310
-
311
- <success_criteria>
312
- - [ ] Installed version read correctly
313
- - [ ] Latest version checked via npm
314
- - [ ] Update skipped if already current
315
- - [ ] Changelog fetched and displayed BEFORE update
316
- - [ ] Clean install warning shown
317
- - [ ] User confirmation obtained
318
- - [ ] Update executed successfully
319
- - [ ] Restart reminder shown
320
- </success_criteria>
1
+ <purpose>
2
+ Check for EZ Agents updates via npm, display changelog for versions between installed and latest, obtain user confirmation, and execute clean installation with cache clearing.
3
+ </purpose>
4
+
5
+ <required_reading>
6
+ Read all files referenced by the invoking prompt's execution_context before starting.
7
+ </required_reading>
8
+
9
+ <process>
10
+
11
+ <step name="get_installed_version">
12
+ Detect whether EZ Agents is installed locally or globally by checking both locations and validating install integrity.
13
+
14
+ First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
15
+ - Path contains `/.codex/` -> `codex`
16
+ - Path contains `/.gemini/` -> `gemini`
17
+ - Path contains `/.config/opencode/` or `/.opencode/` -> `opencode`
18
+ - Otherwise -> `claude`
19
+
20
+ Use `PREFERRED_RUNTIME` as the first runtime checked so `/ez:update` targets the runtime that invoked it.
21
+
22
+ ```bash
23
+ # Runtime candidates: "<runtime>:<config-dir>"
24
+ RUNTIME_DIRS="claude:.claude opencode:.config/opencode opencode:.opencode gemini:.gemini codex:.codex"
25
+
26
+ # PREFERRED_RUNTIME should be set from execution_context before running this block.
27
+ # If not set, infer from runtime env vars; fallback to claude.
28
+ if [ -z "$PREFERRED_RUNTIME" ]; then
29
+ if [ -n "$CODEX_HOME" ]; then
30
+ PREFERRED_RUNTIME="codex"
31
+ elif [ -n "$GEMINI_CONFIG_DIR" ]; then
32
+ PREFERRED_RUNTIME="gemini"
33
+ elif [ -n "$OPENCODE_CONFIG_DIR" ] || [ -n "$OPENCODE_CONFIG" ]; then
34
+ PREFERRED_RUNTIME="opencode"
35
+ elif [ -n "$CLAUDE_CONFIG_DIR" ]; then
36
+ PREFERRED_RUNTIME="claude"
37
+ else
38
+ PREFERRED_RUNTIME="claude"
39
+ fi
40
+ fi
41
+
42
+ # Reorder entries so preferred runtime is checked first.
43
+ ORDERED_RUNTIME_DIRS=""
44
+ for entry in $RUNTIME_DIRS; do
45
+ runtime="${entry%%:*}"
46
+ if [ "$runtime" = "$PREFERRED_RUNTIME" ]; then
47
+ ORDERED_RUNTIME_DIRS="$ORDERED_RUNTIME_DIRS $entry"
48
+ fi
49
+ done
50
+ for entry in $RUNTIME_DIRS; do
51
+ runtime="${entry%%:*}"
52
+ if [ "$runtime" != "$PREFERRED_RUNTIME" ]; then
53
+ ORDERED_RUNTIME_DIRS="$ORDERED_RUNTIME_DIRS $entry"
54
+ fi
55
+ done
56
+
57
+ # Check local first (takes priority only if valid and distinct from global)
58
+ LOCAL_VERSION_FILE="" LOCAL_MARKER_FILE="" LOCAL_DIR="" LOCAL_RUNTIME=""
59
+ for entry in $ORDERED_RUNTIME_DIRS; do
60
+ runtime="${entry%%:*}"
61
+ dir="${entry#*:}"
62
+ if [ -f "./$dir/ez-agents/VERSION" ] || [ -f "./$dir/ez-agents/workflows/update.md" ]; then
63
+ LOCAL_RUNTIME="$runtime"
64
+ LOCAL_VERSION_FILE="./$dir/ez-agents/VERSION"
65
+ LOCAL_MARKER_FILE="./$dir/ez-agents/workflows/update.md"
66
+ LOCAL_DIR="$(cd "./$dir" 2>/dev/null && pwd)"
67
+ break
68
+ fi
69
+ done
70
+
71
+ GLOBAL_VERSION_FILE="" GLOBAL_MARKER_FILE="" GLOBAL_DIR="" GLOBAL_RUNTIME=""
72
+ for entry in $ORDERED_RUNTIME_DIRS; do
73
+ runtime="${entry%%:*}"
74
+ dir="${entry#*:}"
75
+ if [ -f "$HOME/$dir/ez-agents/VERSION" ] || [ -f "$HOME/$dir/ez-agents/workflows/update.md" ]; then
76
+ GLOBAL_RUNTIME="$runtime"
77
+ GLOBAL_VERSION_FILE="$HOME/$dir/ez-agents/VERSION"
78
+ GLOBAL_MARKER_FILE="$HOME/$dir/ez-agents/workflows/update.md"
79
+ GLOBAL_DIR="$(cd "$HOME/$dir" 2>/dev/null && pwd)"
80
+ break
81
+ fi
82
+ done
83
+
84
+ # Only treat as LOCAL if the resolved paths differ (prevents misdetection when CWD=$HOME)
85
+ IS_LOCAL=false
86
+ if [ -n "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$LOCAL_VERSION_FILE"; then
87
+ if [ -z "$GLOBAL_DIR" ] || [ "$LOCAL_DIR" != "$GLOBAL_DIR" ]; then
88
+ IS_LOCAL=true
89
+ fi
90
+ fi
91
+
92
+ if [ "$IS_LOCAL" = true ]; then
93
+ INSTALLED_VERSION="$(cat "$LOCAL_VERSION_FILE")"
94
+ INSTALL_SCOPE="LOCAL"
95
+ TARGET_RUNTIME="$LOCAL_RUNTIME"
96
+ elif [ -n "$GLOBAL_VERSION_FILE" ] && [ -f "$GLOBAL_VERSION_FILE" ] && [ -f "$GLOBAL_MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$GLOBAL_VERSION_FILE"; then
97
+ INSTALLED_VERSION="$(cat "$GLOBAL_VERSION_FILE")"
98
+ INSTALL_SCOPE="GLOBAL"
99
+ TARGET_RUNTIME="$GLOBAL_RUNTIME"
100
+ elif [ -n "$LOCAL_RUNTIME" ] && [ -f "$LOCAL_MARKER_FILE" ]; then
101
+ # Runtime detected but VERSION missing/corrupt: treat as unknown version, keep runtime target
102
+ INSTALLED_VERSION="0.0.0"
103
+ INSTALL_SCOPE="LOCAL"
104
+ TARGET_RUNTIME="$LOCAL_RUNTIME"
105
+ elif [ -n "$GLOBAL_RUNTIME" ] && [ -f "$GLOBAL_MARKER_FILE" ]; then
106
+ INSTALLED_VERSION="0.0.0"
107
+ INSTALL_SCOPE="GLOBAL"
108
+ TARGET_RUNTIME="$GLOBAL_RUNTIME"
109
+ else
110
+ INSTALLED_VERSION="0.0.0"
111
+ INSTALL_SCOPE="UNKNOWN"
112
+ TARGET_RUNTIME="claude"
113
+ fi
114
+
115
+ echo "$INSTALLED_VERSION"
116
+ echo "$INSTALL_SCOPE"
117
+ echo "$TARGET_RUNTIME"
118
+ ```
119
+
120
+ Parse output:
121
+ - Line 1 = installed version (`0.0.0` means unknown version)
122
+ - Line 2 = install scope (`LOCAL`, `GLOBAL`, or `UNKNOWN`)
123
+ - Line 3 = target runtime (`claude`, `opencode`, `gemini`, or `codex`)
124
+ - If scope is `UNKNOWN`, proceed to install step using `--claude --global` fallback.
125
+
126
+ If multiple runtime installs are detected and the invoking runtime cannot be determined from execution_context, ask the user which runtime to update before running install.
127
+
128
+ **If VERSION file missing:**
129
+ ```
130
+ ## GSD Update
131
+
132
+ **Installed version:** Unknown
133
+
134
+ Your installation doesn't include version tracking.
135
+
136
+ Running fresh install...
137
+ ```
138
+
139
+ Proceed to install step (treat as version 0.0.0 for comparison).
140
+ </step>
141
+
142
+ <step name="check_latest_version">
143
+ Check npm for latest version:
144
+
145
+ ```bash
146
+ npm view @howlil/ez-agents version 2>/dev/null
147
+ ```
148
+
149
+ **If npm check fails:**
150
+ ```
151
+ Couldn't check for updates (offline or npm unavailable).
152
+
153
+ To update manually: `npx ez-agents --global`
154
+ ```
155
+
156
+ Exit.
157
+ </step>
158
+
159
+ <step name="compare_versions">
160
+ Compare installed vs latest:
161
+
162
+ **If installed == latest:**
163
+ ```
164
+ ## EZ Agents Update
165
+
166
+ **Installed:** X.Y.Z
167
+ **Latest:** X.Y.Z
168
+
169
+ You're already on the latest version.
170
+ ```
171
+
172
+ Exit.
173
+
174
+ **If installed > latest:**
175
+ ```
176
+ ## EZ Agents Update
177
+
178
+ **Installed:** X.Y.Z
179
+ **Latest:** A.B.C
180
+
181
+ You're ahead of the latest release (development version?).
182
+ ```
183
+
184
+ Exit.
185
+ </step>
186
+
187
+ <step name="show_changes_and_confirm">
188
+ **If update available**, fetch and show what's new BEFORE updating:
189
+
190
+ 1. Fetch changelog from GitHub raw URL
191
+ 2. Extract entries between installed and latest versions
192
+ 3. Display preview and ask for confirmation:
193
+
194
+ ```
195
+ ## EZ Agents Update Available
196
+
197
+ **Installed:** 1.5.10
198
+ **Latest:** 1.5.15
199
+
200
+ ### What's New
201
+ ────────────────────────────────────────────────────────────
202
+
203
+ ## [1.5.15] - 2026-01-20
204
+
205
+ ### Added
206
+ - Feature X
207
+
208
+ ## [1.5.14] - 2026-01-18
209
+
210
+ ### Fixed
211
+ - Bug fix Y
212
+
213
+ ────────────────────────────────────────────────────────────
214
+
215
+ ⚠️ **Note:** The installer performs a clean install of EZ Agents folders:
216
+ - `commands/ez/` will be wiped and replaced
217
+ - `ez-agents/` will be wiped and replaced
218
+ - `agents/ez-*` files will be replaced
219
+
220
+ (Paths are relative to detected runtime install location:
221
+ global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, or `~/.codex/`
222
+ local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, or `./.codex/`)
223
+
224
+ Your custom files in other locations are preserved:
225
+ - Custom commands not in `commands/ez/` ✓
226
+ - Custom agents not prefixed with `ez-` ✓
227
+ - Custom hooks ✓
228
+ - Your CLAUDE.md files ✓
229
+
230
+ If you've modified any EZ Agents files directly, they'll be automatically backed up to `ez-agents-local-patches/` and can be reapplied with `/ez:reapply-patches` after the update.
231
+ ```
232
+
233
+ Use AskUserQuestion:
234
+ - Question: "Proceed with update?"
235
+ - Options:
236
+ - "Yes, update now"
237
+ - "No, cancel"
238
+
239
+ **If user cancels:** Exit.
240
+ </step>
241
+
242
+ <step name="run_update">
243
+ Run the update using the install type detected in step 1:
244
+
245
+ Build runtime flag from step 1:
246
+ ```bash
247
+ RUNTIME_FLAG="--$TARGET_RUNTIME"
248
+ ```
249
+
250
+ **If LOCAL install:**
251
+ ```bash
252
+ npx -y @howlil/ez-agents@latest "$RUNTIME_FLAG" --local
253
+ ```
254
+
255
+ **If GLOBAL install:**
256
+ ```bash
257
+ npx -y @howlil/ez-agents@latest "$RUNTIME_FLAG" --global
258
+ ```
259
+
260
+ **If UNKNOWN install:**
261
+ ```bash
262
+ npx -y @howlil/ez-agents@latest --claude --global
263
+ ```
264
+
265
+ Capture output. If install fails, show error and exit.
266
+
267
+ Clear the update cache so statusline indicator disappears:
268
+
269
+ ```bash
270
+ # Clear update cache across all runtime directories
271
+ for dir in .claude .config/opencode .opencode .gemini .codex; do
272
+ rm -f "./$dir/cache/ez-update-check.json"
273
+ rm -f "$HOME/$dir/cache/ez-update-check.json"
274
+ done
275
+ ```
276
+
277
+ The SessionStart hook (`ez-check-update.js`) writes to the detected runtime's cache directory, so all paths must be cleared to prevent stale update indicators.
278
+ </step>
279
+
280
+ <step name="display_result">
281
+ Format completion message (changelog was already shown in confirmation step):
282
+
283
+ ```
284
+ ╔═══════════════════════════════════════════════════════════╗
285
+ EZ Agents Updated: v1.5.10 → v1.5.15
286
+ ╚═══════════════════════════════════════════════════════════╝
287
+
288
+ ⚠️ Restart your runtime to pick up the new commands.
289
+
290
+ [View full changelog](https://github.com/howlil/ez-agents/blob/main/CHANGELOG.md)
291
+ ```
292
+ </step>
293
+
294
+
295
+ <step name="check_local_patches">
296
+ After update completes, check if the installer detected and backed up any locally modified files:
297
+
298
+ Check for ez-agents-local-patches/backup-meta.json in the config directory.
299
+
300
+ **If patches found:**
301
+
302
+ ```
303
+ Local patches were backed up before the update.
304
+ Run /ez:reapply-patches to merge your modifications into the new version.
305
+ ```
306
+
307
+ **If no patches:** Continue normally.
308
+ </step>
309
+ </process>
310
+
311
+ <success_criteria>
312
+ - [ ] Installed version read correctly
313
+ - [ ] Latest version checked via npm
314
+ - [ ] Update skipped if already current
315
+ - [ ] Changelog fetched and displayed BEFORE update
316
+ - [ ] Clean install warning shown
317
+ - [ ] User confirmation obtained
318
+ - [ ] Update executed successfully
319
+ - [ ] Restart reminder shown
320
+ </success_criteria>