@howlil/ez-agents 2.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -25
- package/README.zh-CN.md +84 -84
- package/agents/ez-ui-auditor.md +0 -2
- package/agents/ez-ui-checker.md +2 -4
- package/agents/ez-ui-researcher.md +0 -2
- package/bin/install.js +145 -102
- package/commands/ez/debug.md +1 -1
- package/commands/ez/map-codebase.md +1 -1
- package/commands/ez/reapply-patches.md +3 -3
- package/commands/ez/research-phase.md +1 -1
- package/{get-shit-done → ez-agents}/bin/ez-tools.cjs +1 -1
- package/{get-shit-done → ez-agents}/bin/lib/auth.cjs +2 -2
- package/{get-shit-done → ez-agents}/bin/lib/core.cjs +16 -16
- package/{get-shit-done → ez-agents}/bin/lib/init.cjs +20 -20
- package/{get-shit-done → ez-agents}/bin/lib/logger.cjs +2 -2
- package/{get-shit-done → ez-agents}/bin/lib/temp-file.cjs +2 -2
- package/{get-shit-done → ez-agents}/bin/lib/test-file-lock.cjs +1 -1
- package/{get-shit-done → ez-agents}/bin/lib/test-graceful.cjs +1 -1
- package/{get-shit-done → ez-agents}/bin/lib/test-logger.cjs +1 -1
- package/{get-shit-done → ez-agents}/bin/lib/test-temp-file.cjs +2 -2
- package/{get-shit-done → ez-agents}/workflows/add-phase.md +2 -2
- package/{get-shit-done → ez-agents}/workflows/audit-milestone.md +1 -1
- package/{get-shit-done → ez-agents}/workflows/complete-milestone.md +3 -3
- package/ez-agents/workflows/debug.md +0 -0
- package/{get-shit-done → ez-agents}/workflows/discovery-phase.md +5 -5
- package/{get-shit-done → ez-agents}/workflows/discuss-phase.md +2 -2
- package/{get-shit-done → ez-agents}/workflows/execute-phase.md +5 -5
- package/{get-shit-done → ez-agents}/workflows/execute-plan.md +10 -10
- package/{get-shit-done → ez-agents}/workflows/help.md +9 -9
- package/{get-shit-done → ez-agents}/workflows/insert-phase.md +2 -2
- package/{get-shit-done → ez-agents}/workflows/map-codebase.md +3 -3
- package/{get-shit-done → ez-agents}/workflows/new-milestone.md +4 -4
- package/{get-shit-done → ez-agents}/workflows/new-project.md +8 -8
- package/{get-shit-done → ez-agents}/workflows/plan-phase.md +9 -9
- package/{get-shit-done → ez-agents}/workflows/progress.md +2 -2
- package/{get-shit-done → ez-agents}/workflows/quick.md +10 -10
- package/{get-shit-done → ez-agents}/workflows/remove-phase.md +4 -4
- package/{get-shit-done → ez-agents}/workflows/research-phase.md +4 -4
- package/{get-shit-done → ez-agents}/workflows/resume-project.md +1 -1
- package/{get-shit-done → ez-agents}/workflows/set-profile.md +3 -3
- package/{get-shit-done → ez-agents}/workflows/transition.md +3 -3
- package/{get-shit-done → ez-agents}/workflows/ui-phase.md +12 -12
- package/{get-shit-done → ez-agents}/workflows/ui-review.md +6 -6
- package/{get-shit-done → ez-agents}/workflows/update.md +29 -29
- package/{get-shit-done → ez-agents}/workflows/validate-phase.md +5 -5
- package/{get-shit-done → ez-agents}/workflows/verify-phase.md +6 -6
- package/{get-shit-done → ez-agents}/workflows/verify-work.md +5 -5
- package/hooks/dist/ez-check-update.js +81 -0
- package/hooks/dist/ez-context-monitor.js +141 -0
- package/hooks/dist/ez-statusline.js +115 -0
- package/package.json +13 -3
- package/scripts/build-hooks.js +3 -3
- /package/{get-shit-done → ez-agents}/bin/lib/assistant-adapter.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/audit-exec.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/circuit-breaker.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/commands.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/config.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/file-lock.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/frontmatter.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/fs-utils.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/git-utils.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/health-check.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/index.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/milestone.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/model-provider.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/phase.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/retry.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/roadmap.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/safe-exec.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/safe-path.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/state.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/template.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/test-safe-exec.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/test-safe-path.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/timeout-exec.cjs +0 -0
- /package/{get-shit-done → ez-agents}/bin/lib/verify.cjs +0 -0
- /package/{get-shit-done → ez-agents}/references/checkpoints.md +0 -0
- /package/{get-shit-done → ez-agents}/references/continuation-format.md +0 -0
- /package/{get-shit-done → ez-agents}/references/decimal-phase-calculation.md +0 -0
- /package/{get-shit-done → ez-agents}/references/git-integration.md +0 -0
- /package/{get-shit-done → ez-agents}/references/git-planning-commit.md +0 -0
- /package/{get-shit-done → ez-agents}/references/model-profile-resolution.md +0 -0
- /package/{get-shit-done → ez-agents}/references/model-profiles.md +0 -0
- /package/{get-shit-done → ez-agents}/references/phase-argument-parsing.md +0 -0
- /package/{get-shit-done → ez-agents}/references/planning-config.md +0 -0
- /package/{get-shit-done → ez-agents}/references/questioning.md +0 -0
- /package/{get-shit-done → ez-agents}/references/tdd.md +0 -0
- /package/{get-shit-done → ez-agents}/references/ui-brand.md +0 -0
- /package/{get-shit-done → ez-agents}/references/verification-patterns.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/DEBUG.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/UAT.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/UI-SPEC.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/VALIDATION.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/architecture.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/concerns.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/conventions.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/integrations.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/stack.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/structure.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/codebase/testing.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/config.json +0 -0
- /package/{get-shit-done → ez-agents}/templates/context.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/continue-here.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/copilot-instructions.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/debug-subagent-prompt.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/discovery.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/milestone-archive.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/milestone.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/phase-prompt.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/planner-subagent-prompt.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/project.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/requirements.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research-project/ARCHITECTURE.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research-project/FEATURES.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research-project/PITFALLS.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research-project/STACK.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research-project/SUMMARY.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/research.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/retrospective.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/roadmap.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/state.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/summary-complex.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/summary-minimal.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/summary-standard.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/summary.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/user-setup.md +0 -0
- /package/{get-shit-done → ez-agents}/templates/verification-report.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/add-tests.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/add-todo.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/autonomous.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/check-todos.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/cleanup.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/diagnose-issues.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/health.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/list-phase-assumptions.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/node-repair.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/pause-work.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/plan-milestone-gaps.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/settings.md +0 -0
- /package/{get-shit-done → ez-agents}/workflows/stats.md +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Check for
|
|
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
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
@@ -9,7 +9,7 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
9
9
|
<process>
|
|
10
10
|
|
|
11
11
|
<step name="get_installed_version">
|
|
12
|
-
Detect whether
|
|
12
|
+
Detect whether EZ Agents is installed locally or globally by checking both locations and validating install integrity.
|
|
13
13
|
|
|
14
14
|
First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
|
|
15
15
|
- Path contains `/.codex/` -> `codex`
|
|
@@ -59,10 +59,10 @@ LOCAL_VERSION_FILE="" LOCAL_MARKER_FILE="" LOCAL_DIR="" LOCAL_RUNTIME=""
|
|
|
59
59
|
for entry in $ORDERED_RUNTIME_DIRS; do
|
|
60
60
|
runtime="${entry%%:*}"
|
|
61
61
|
dir="${entry#*:}"
|
|
62
|
-
if [ -f "./$dir/
|
|
62
|
+
if [ -f "./$dir/ez-agents/VERSION" ] || [ -f "./$dir/ez-agents/workflows/update.md" ]; then
|
|
63
63
|
LOCAL_RUNTIME="$runtime"
|
|
64
|
-
LOCAL_VERSION_FILE="./$dir/
|
|
65
|
-
LOCAL_MARKER_FILE="./$dir/
|
|
64
|
+
LOCAL_VERSION_FILE="./$dir/ez-agents/VERSION"
|
|
65
|
+
LOCAL_MARKER_FILE="./$dir/ez-agents/workflows/update.md"
|
|
66
66
|
LOCAL_DIR="$(cd "./$dir" 2>/dev/null && pwd)"
|
|
67
67
|
break
|
|
68
68
|
fi
|
|
@@ -72,10 +72,10 @@ GLOBAL_VERSION_FILE="" GLOBAL_MARKER_FILE="" GLOBAL_DIR="" GLOBAL_RUNTIME=""
|
|
|
72
72
|
for entry in $ORDERED_RUNTIME_DIRS; do
|
|
73
73
|
runtime="${entry%%:*}"
|
|
74
74
|
dir="${entry#*:}"
|
|
75
|
-
if [ -f "$HOME/$dir/
|
|
75
|
+
if [ -f "$HOME/$dir/ez-agents/VERSION" ] || [ -f "$HOME/$dir/ez-agents/workflows/update.md" ]; then
|
|
76
76
|
GLOBAL_RUNTIME="$runtime"
|
|
77
|
-
GLOBAL_VERSION_FILE="$HOME/$dir/
|
|
78
|
-
GLOBAL_MARKER_FILE="$HOME/$dir/
|
|
77
|
+
GLOBAL_VERSION_FILE="$HOME/$dir/ez-agents/VERSION"
|
|
78
|
+
GLOBAL_MARKER_FILE="$HOME/$dir/ez-agents/workflows/update.md"
|
|
79
79
|
GLOBAL_DIR="$(cd "$HOME/$dir" 2>/dev/null && pwd)"
|
|
80
80
|
break
|
|
81
81
|
fi
|
|
@@ -143,14 +143,14 @@ Proceed to install step (treat as version 0.0.0 for comparison).
|
|
|
143
143
|
Check npm for latest version:
|
|
144
144
|
|
|
145
145
|
```bash
|
|
146
|
-
npm view
|
|
146
|
+
npm view @howlil/ez-agents version 2>/dev/null
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
**If npm check fails:**
|
|
150
150
|
```
|
|
151
151
|
Couldn't check for updates (offline or npm unavailable).
|
|
152
152
|
|
|
153
|
-
To update manually: `npx
|
|
153
|
+
To update manually: `npx ez-agents --global`
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
Exit.
|
|
@@ -161,7 +161,7 @@ Compare installed vs latest:
|
|
|
161
161
|
|
|
162
162
|
**If installed == latest:**
|
|
163
163
|
```
|
|
164
|
-
##
|
|
164
|
+
## EZ Agents Update
|
|
165
165
|
|
|
166
166
|
**Installed:** X.Y.Z
|
|
167
167
|
**Latest:** X.Y.Z
|
|
@@ -173,7 +173,7 @@ Exit.
|
|
|
173
173
|
|
|
174
174
|
**If installed > latest:**
|
|
175
175
|
```
|
|
176
|
-
##
|
|
176
|
+
## EZ Agents Update
|
|
177
177
|
|
|
178
178
|
**Installed:** X.Y.Z
|
|
179
179
|
**Latest:** A.B.C
|
|
@@ -192,7 +192,7 @@ Exit.
|
|
|
192
192
|
3. Display preview and ask for confirmation:
|
|
193
193
|
|
|
194
194
|
```
|
|
195
|
-
##
|
|
195
|
+
## EZ Agents Update Available
|
|
196
196
|
|
|
197
197
|
**Installed:** 1.5.10
|
|
198
198
|
**Latest:** 1.5.15
|
|
@@ -212,22 +212,22 @@ Exit.
|
|
|
212
212
|
|
|
213
213
|
────────────────────────────────────────────────────────────
|
|
214
214
|
|
|
215
|
-
⚠️ **Note:** The installer performs a clean install of
|
|
216
|
-
- `commands/
|
|
217
|
-
- `
|
|
218
|
-
- `agents/
|
|
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
219
|
|
|
220
220
|
(Paths are relative to detected runtime install location:
|
|
221
221
|
global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, or `~/.codex/`
|
|
222
222
|
local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, or `./.codex/`)
|
|
223
223
|
|
|
224
224
|
Your custom files in other locations are preserved:
|
|
225
|
-
- Custom commands not in `commands/
|
|
226
|
-
- Custom agents not prefixed with `
|
|
225
|
+
- Custom commands not in `commands/ez/` ✓
|
|
226
|
+
- Custom agents not prefixed with `ez-` ✓
|
|
227
227
|
- Custom hooks ✓
|
|
228
228
|
- Your CLAUDE.md files ✓
|
|
229
229
|
|
|
230
|
-
If you've modified any
|
|
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
231
|
```
|
|
232
232
|
|
|
233
233
|
Use AskUserQuestion:
|
|
@@ -249,17 +249,17 @@ RUNTIME_FLAG="--$TARGET_RUNTIME"
|
|
|
249
249
|
|
|
250
250
|
**If LOCAL install:**
|
|
251
251
|
```bash
|
|
252
|
-
npx -y
|
|
252
|
+
npx -y @howlil/ez-agents@latest "$RUNTIME_FLAG" --local
|
|
253
253
|
```
|
|
254
254
|
|
|
255
255
|
**If GLOBAL install:**
|
|
256
256
|
```bash
|
|
257
|
-
npx -y
|
|
257
|
+
npx -y @howlil/ez-agents@latest "$RUNTIME_FLAG" --global
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
**If UNKNOWN install:**
|
|
261
261
|
```bash
|
|
262
|
-
npx -y
|
|
262
|
+
npx -y @howlil/ez-agents@latest --claude --global
|
|
263
263
|
```
|
|
264
264
|
|
|
265
265
|
Capture output. If install fails, show error and exit.
|
|
@@ -269,12 +269,12 @@ Clear the update cache so statusline indicator disappears:
|
|
|
269
269
|
```bash
|
|
270
270
|
# Clear update cache across all runtime directories
|
|
271
271
|
for dir in .claude .config/opencode .opencode .gemini .codex; do
|
|
272
|
-
rm -f "./$dir/cache/
|
|
273
|
-
rm -f "$HOME/$dir/cache/
|
|
272
|
+
rm -f "./$dir/cache/ez-update-check.json"
|
|
273
|
+
rm -f "$HOME/$dir/cache/ez-update-check.json"
|
|
274
274
|
done
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
The SessionStart hook (`
|
|
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
278
|
</step>
|
|
279
279
|
|
|
280
280
|
<step name="display_result">
|
|
@@ -282,12 +282,12 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
282
282
|
|
|
283
283
|
```
|
|
284
284
|
╔═══════════════════════════════════════════════════════════╗
|
|
285
|
-
║
|
|
285
|
+
║ EZ Agents Updated: v1.5.10 → v1.5.15 ║
|
|
286
286
|
╚═══════════════════════════════════════════════════════════╝
|
|
287
287
|
|
|
288
288
|
⚠️ Restart your runtime to pick up the new commands.
|
|
289
289
|
|
|
290
|
-
[View full changelog](https://github.com/
|
|
290
|
+
[View full changelog](https://github.com/howlil/ez-agents/blob/main/CHANGELOG.md)
|
|
291
291
|
```
|
|
292
292
|
</step>
|
|
293
293
|
|
|
@@ -295,7 +295,7 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
295
295
|
<step name="check_local_patches">
|
|
296
296
|
After update completes, check if the installer detected and backed up any locally modified files:
|
|
297
297
|
|
|
298
|
-
Check for
|
|
298
|
+
Check for ez-agents-local-patches/backup-meta.json in the config directory.
|
|
299
299
|
|
|
300
300
|
**If patches found:**
|
|
301
301
|
|
|
@@ -3,7 +3,7 @@ Audit Nyquist validation gaps for a completed phase. Generate missing tests. Upd
|
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
6
|
-
@~/.claude/
|
|
6
|
+
@~/.claude/ez-agents/references/ui-brand.md
|
|
7
7
|
</required_reading>
|
|
8
8
|
|
|
9
9
|
<process>
|
|
@@ -18,7 +18,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
18
18
|
Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`.
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
AUDITOR_MODEL=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" resolve-model
|
|
21
|
+
AUDITOR_MODEL=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" resolve-model ez-nyquist-auditor --raw)
|
|
22
22
|
NYQUIST_CFG=$(node "$HOME/.claude/ez-agents/bin/ez-tools.cjs" config get workflow.nyquist_validation --raw)
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -82,11 +82,11 @@ Call AskUserQuestion with gap table and options:
|
|
|
82
82
|
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
|
83
83
|
3. "Cancel" → exit
|
|
84
84
|
|
|
85
|
-
## 5. Spawn
|
|
85
|
+
## 5. Spawn ez-nyquist-auditor
|
|
86
86
|
|
|
87
87
|
```
|
|
88
88
|
Task(
|
|
89
|
-
prompt="Read ~/.claude/agents/
|
|
89
|
+
prompt="Read ~/.claude/agents/ez-nyquist-auditor.md for instructions.\n\n" +
|
|
90
90
|
"<files_to_read>{PLAN, SUMMARY, impl files, VALIDATION.md}</files_to_read>" +
|
|
91
91
|
"<gaps>{gap list}</gaps>" +
|
|
92
92
|
"<test_infrastructure>{framework, config, commands}</test_infrastructure>" +
|
|
@@ -105,7 +105,7 @@ Handle return:
|
|
|
105
105
|
## 6. Generate/Update VALIDATION.md
|
|
106
106
|
|
|
107
107
|
**State B (create):**
|
|
108
|
-
1. Read template from `~/.claude/
|
|
108
|
+
1. Read template from `~/.claude/ez-agents/templates/VALIDATION.md`
|
|
109
109
|
2. Fill: frontmatter, Test Infrastructure, Per-Task Map, Manual-Only, Sign-Off
|
|
110
110
|
3. Write to `${PHASE_DIR}/${PADDED_PHASE}-VALIDATION.md`
|
|
111
111
|
|
|
@@ -18,8 +18,8 @@ Then verify each level against the actual codebase.
|
|
|
18
18
|
</core_principle>
|
|
19
19
|
|
|
20
20
|
<required_reading>
|
|
21
|
-
@~/.claude/
|
|
22
|
-
@~/.claude/
|
|
21
|
+
@~/.claude/ez-agents/references/verification-patterns.md
|
|
22
|
+
@~/.claude/ez-agents/templates/verification-report.md
|
|
23
23
|
</required_reading>
|
|
24
24
|
|
|
25
25
|
<process>
|
|
@@ -47,7 +47,7 @@ Extract **phase goal** from ROADMAP.md (the outcome to verify, not tasks) and **
|
|
|
47
47
|
<step name="establish_must_haves">
|
|
48
48
|
**Option A: Must-haves in PLAN frontmatter**
|
|
49
49
|
|
|
50
|
-
Use
|
|
50
|
+
Use ez-tools to extract must_haves from each PLAN:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
for plan in "$PHASE_DIR"/*-PLAN.md; do
|
|
@@ -97,7 +97,7 @@ For each truth: identify supporting artifacts → check artifact status → chec
|
|
|
97
97
|
</step>
|
|
98
98
|
|
|
99
99
|
<step name="verify_artifacts">
|
|
100
|
-
Use
|
|
100
|
+
Use ez-tools for artifact verification against must_haves in each PLAN:
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
103
|
for plan in "$PHASE_DIR"/*-PLAN.md; do
|
|
@@ -129,7 +129,7 @@ WIRED = imported AND used. ORPHANED = exists but not imported/used.
|
|
|
129
129
|
</step>
|
|
130
130
|
|
|
131
131
|
<step name="verify_wiring">
|
|
132
|
-
Use
|
|
132
|
+
Use ez-tools for key link verification against must_haves in each PLAN:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
135
|
for plan in "$PHASE_DIR"/*-PLAN.md; do
|
|
@@ -214,7 +214,7 @@ REPORT_PATH="$PHASE_DIR/${PHASE_NUM}-VERIFICATION.md"
|
|
|
214
214
|
|
|
215
215
|
Fill template sections: frontmatter (phase/timestamp/status/score), goal achievement, artifact table, wiring table, requirements coverage, anti-patterns, human verification, gaps summary, fix plans (if gaps_found), metadata.
|
|
216
216
|
|
|
217
|
-
See ~/.claude/
|
|
217
|
+
See ~/.claude/ez-agents/templates/verification-report.md for complete template.
|
|
218
218
|
</step>
|
|
219
219
|
|
|
220
220
|
<step name="return_to_orchestrator">
|
|
@@ -15,7 +15,7 @@ No Pass/Fail buttons. No severity questions. Just: "Here's what should happen. D
|
|
|
15
15
|
</philosophy>
|
|
16
16
|
|
|
17
17
|
<template>
|
|
18
|
-
@~/.claude/
|
|
18
|
+
@~/.claude/ez-agents/templates/UAT.md
|
|
19
19
|
</template>
|
|
20
20
|
|
|
21
21
|
<process>
|
|
@@ -349,7 +349,7 @@ Spawning parallel debug agents to investigate each issue.
|
|
|
349
349
|
```
|
|
350
350
|
|
|
351
351
|
- Load diagnose-issues workflow
|
|
352
|
-
- Follow @~/.claude/
|
|
352
|
+
- Follow @~/.claude/ez-agents/workflows/diagnose-issues.md
|
|
353
353
|
- Spawn parallel debug agents for each issue
|
|
354
354
|
- Collect root causes
|
|
355
355
|
- Update UAT.md with root causes
|
|
@@ -370,7 +370,7 @@ Display:
|
|
|
370
370
|
◆ Spawning planner for gap closure...
|
|
371
371
|
```
|
|
372
372
|
|
|
373
|
-
Spawn
|
|
373
|
+
Spawn ez-planner in --gaps mode:
|
|
374
374
|
|
|
375
375
|
```
|
|
376
376
|
Task(
|
|
@@ -577,8 +577,8 @@ Default to **major** if unclear. User can correct if needed.
|
|
|
577
577
|
- [ ] Batched writes: on issue, every 5 passes, or completion
|
|
578
578
|
- [ ] Committed on completion
|
|
579
579
|
- [ ] If issues: parallel debug agents diagnose root causes
|
|
580
|
-
- [ ] If issues:
|
|
581
|
-
- [ ] If issues:
|
|
580
|
+
- [ ] If issues: ez-planner creates fix plans (gap_closure mode)
|
|
581
|
+
- [ ] If issues: ez-plan-checker verifies fix plans
|
|
582
582
|
- [ ] If issues: revision loop until plans pass (max 3 iterations)
|
|
583
583
|
- [ ] Ready for `/ez:execute-phase --gaps-only` when complete
|
|
584
584
|
</success_criteria>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Check for EZ Agents updates in background, write result to cache
|
|
3
|
+
// Called by SessionStart hook - runs once per session
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const homeDir = os.homedir();
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
|
|
13
|
+
// Detect runtime config directory (supports Claude, OpenCode, Gemini)
|
|
14
|
+
// Respects CLAUDE_CONFIG_DIR for custom config directory setups
|
|
15
|
+
function detectConfigDir(baseDir) {
|
|
16
|
+
// Check env override first (supports multi-account setups)
|
|
17
|
+
const envDir = process.env.CLAUDE_CONFIG_DIR;
|
|
18
|
+
if (envDir && fs.existsSync(path.join(envDir, 'ez-agents', 'VERSION'))) {
|
|
19
|
+
return envDir;
|
|
20
|
+
}
|
|
21
|
+
for (const dir of ['.config/opencode', '.opencode', '.gemini', '.claude']) {
|
|
22
|
+
if (fs.existsSync(path.join(baseDir, dir, 'ez-agents', 'VERSION'))) {
|
|
23
|
+
return path.join(baseDir, dir);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return envDir || path.join(baseDir, '.claude');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const globalConfigDir = detectConfigDir(homeDir);
|
|
30
|
+
const projectConfigDir = detectConfigDir(cwd);
|
|
31
|
+
const cacheDir = path.join(globalConfigDir, 'cache');
|
|
32
|
+
const cacheFile = path.join(cacheDir, 'ez-update-check.json');
|
|
33
|
+
|
|
34
|
+
// VERSION file locations (check project first, then global)
|
|
35
|
+
const projectVersionFile = path.join(projectConfigDir, 'ez-agents', 'VERSION');
|
|
36
|
+
const globalVersionFile = path.join(globalConfigDir, 'ez-agents', 'VERSION');
|
|
37
|
+
|
|
38
|
+
// Ensure cache directory exists
|
|
39
|
+
if (!fs.existsSync(cacheDir)) {
|
|
40
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Run check in background (spawn background process, windowsHide prevents console flash)
|
|
44
|
+
const child = spawn(process.execPath, ['-e', `
|
|
45
|
+
const fs = require('fs');
|
|
46
|
+
const { execSync } = require('child_process');
|
|
47
|
+
|
|
48
|
+
const cacheFile = ${JSON.stringify(cacheFile)};
|
|
49
|
+
const projectVersionFile = ${JSON.stringify(projectVersionFile)};
|
|
50
|
+
const globalVersionFile = ${JSON.stringify(globalVersionFile)};
|
|
51
|
+
|
|
52
|
+
// Check project directory first (local install), then global
|
|
53
|
+
let installed = '0.0.0';
|
|
54
|
+
try {
|
|
55
|
+
if (fs.existsSync(projectVersionFile)) {
|
|
56
|
+
installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
|
|
57
|
+
} else if (fs.existsSync(globalVersionFile)) {
|
|
58
|
+
installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
|
|
62
|
+
let latest = null;
|
|
63
|
+
try {
|
|
64
|
+
latest = execSync('npm view ez-agents version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
65
|
+
} catch (e) {}
|
|
66
|
+
|
|
67
|
+
const result = {
|
|
68
|
+
update_available: latest && installed !== latest,
|
|
69
|
+
installed,
|
|
70
|
+
latest: latest || 'unknown',
|
|
71
|
+
checked: Math.floor(Date.now() / 1000)
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
75
|
+
`], {
|
|
76
|
+
stdio: 'ignore',
|
|
77
|
+
windowsHide: true,
|
|
78
|
+
detached: true // Required on Windows for proper process detachment
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
child.unref();
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Context Monitor - PostToolUse/AfterTool hook (Gemini uses AfterTool)
|
|
3
|
+
// Reads context metrics from the statusline bridge file and injects
|
|
4
|
+
// warnings when context usage is high. This makes the AGENT aware of
|
|
5
|
+
// context limits (the statusline only shows the user).
|
|
6
|
+
//
|
|
7
|
+
// How it works:
|
|
8
|
+
// 1. The statusline hook writes metrics to /tmp/claude-ctx-{session_id}.json
|
|
9
|
+
// 2. This hook reads those metrics after each tool use
|
|
10
|
+
// 3. When remaining context drops below thresholds, it injects a warning
|
|
11
|
+
// as additionalContext, which the agent sees in its conversation
|
|
12
|
+
//
|
|
13
|
+
// Thresholds:
|
|
14
|
+
// WARNING (remaining <= 35%): Agent should wrap up current task
|
|
15
|
+
// CRITICAL (remaining <= 25%): Agent should stop immediately and save state
|
|
16
|
+
//
|
|
17
|
+
// Debounce: 5 tool uses between warnings to avoid spam
|
|
18
|
+
// Severity escalation bypasses debounce (WARNING -> CRITICAL fires immediately)
|
|
19
|
+
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const os = require('os');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
|
|
24
|
+
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
25
|
+
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
26
|
+
const STALE_SECONDS = 60; // ignore metrics older than 60s
|
|
27
|
+
const DEBOUNCE_CALLS = 5; // min tool uses between warnings
|
|
28
|
+
|
|
29
|
+
let input = '';
|
|
30
|
+
// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on
|
|
31
|
+
// Windows/Git Bash), exit silently instead of hanging until Claude Code
|
|
32
|
+
// kills the process and reports "hook error". See #775.
|
|
33
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
34
|
+
process.stdin.setEncoding('utf8');
|
|
35
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
36
|
+
process.stdin.on('end', () => {
|
|
37
|
+
clearTimeout(stdinTimeout);
|
|
38
|
+
try {
|
|
39
|
+
const data = JSON.parse(input);
|
|
40
|
+
const sessionId = data.session_id;
|
|
41
|
+
|
|
42
|
+
if (!sessionId) {
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const tmpDir = os.tmpdir();
|
|
47
|
+
const metricsPath = path.join(tmpDir, `claude-ctx-${sessionId}.json`);
|
|
48
|
+
|
|
49
|
+
// If no metrics file, this is a subagent or fresh session -- exit silently
|
|
50
|
+
if (!fs.existsSync(metricsPath)) {
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
|
|
55
|
+
const now = Math.floor(Date.now() / 1000);
|
|
56
|
+
|
|
57
|
+
// Ignore stale metrics
|
|
58
|
+
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const remaining = metrics.remaining_percentage;
|
|
63
|
+
const usedPct = metrics.used_pct;
|
|
64
|
+
|
|
65
|
+
// No warning needed
|
|
66
|
+
if (remaining > WARNING_THRESHOLD) {
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Debounce: check if we warned recently
|
|
71
|
+
const warnPath = path.join(tmpDir, `claude-ctx-${sessionId}-warned.json`);
|
|
72
|
+
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
73
|
+
let firstWarn = true;
|
|
74
|
+
|
|
75
|
+
if (fs.existsSync(warnPath)) {
|
|
76
|
+
try {
|
|
77
|
+
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
78
|
+
firstWarn = false;
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// Corrupted file, reset
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
85
|
+
|
|
86
|
+
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
87
|
+
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
88
|
+
|
|
89
|
+
// Emit immediately on first warning, then debounce subsequent ones
|
|
90
|
+
// Severity escalation (WARNING -> CRITICAL) bypasses debounce
|
|
91
|
+
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
92
|
+
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
93
|
+
// Update counter and exit without warning
|
|
94
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Reset debounce counter
|
|
99
|
+
warnData.callsSinceWarn = 0;
|
|
100
|
+
warnData.lastLevel = currentLevel;
|
|
101
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
102
|
+
|
|
103
|
+
// Detect if EZ Agents is active (has .planning/STATE.md in working directory)
|
|
104
|
+
const cwd = data.cwd || process.cwd();
|
|
105
|
+
const isEzActive = fs.existsSync(path.join(cwd, '.planning', 'STATE.md'));
|
|
106
|
+
|
|
107
|
+
// Build advisory warning message (never use imperative commands that
|
|
108
|
+
// override user preferences — see #884)
|
|
109
|
+
let message;
|
|
110
|
+
if (isCritical) {
|
|
111
|
+
message = isEzActive
|
|
112
|
+
? `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
113
|
+
'Context is nearly exhausted. Do NOT start new complex work or write handoff files — ' +
|
|
114
|
+
'EZ Agents state is already tracked in STATE.md. Inform the user so they can run ' +
|
|
115
|
+
'/ez:pause-work at the next natural stopping point.'
|
|
116
|
+
: `CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
117
|
+
'Context is nearly exhausted. Inform the user that context is low and ask how they ' +
|
|
118
|
+
'want to proceed. Do NOT autonomously save state or write handoff files unless the user asks.';
|
|
119
|
+
} else {
|
|
120
|
+
message = isEzActive
|
|
121
|
+
? `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
122
|
+
'Context is getting limited. Avoid starting new complex work. If not between ' +
|
|
123
|
+
'defined plan steps, inform the user so they can prepare to pause.'
|
|
124
|
+
: `CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
125
|
+
'Be aware that context is getting limited. Avoid unnecessary exploration or ' +
|
|
126
|
+
'starting new complex work.';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const output = {
|
|
130
|
+
hookSpecificOutput: {
|
|
131
|
+
hookEventName: process.env.GEMINI_API_KEY ? "AfterTool" : "PostToolUse",
|
|
132
|
+
additionalContext: message
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
process.stdout.write(JSON.stringify(output));
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// Silent fail -- never block tool execution
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code Statusline - EZ Agents Edition
|
|
3
|
+
// Shows: model | current task | directory | context usage
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
// Read JSON from stdin
|
|
10
|
+
let input = '';
|
|
11
|
+
// Timeout guard: if stdin doesn't close within 3s (e.g. pipe issues on
|
|
12
|
+
// Windows/Git Bash), exit silently instead of hanging. See #775.
|
|
13
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
14
|
+
process.stdin.setEncoding('utf8');
|
|
15
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
16
|
+
process.stdin.on('end', () => {
|
|
17
|
+
clearTimeout(stdinTimeout);
|
|
18
|
+
try {
|
|
19
|
+
const data = JSON.parse(input);
|
|
20
|
+
const model = data.model?.display_name || 'Claude';
|
|
21
|
+
const dir = data.workspace?.current_dir || process.cwd();
|
|
22
|
+
const session = data.session_id || '';
|
|
23
|
+
const remaining = data.context_window?.remaining_percentage;
|
|
24
|
+
|
|
25
|
+
// Context window display (shows USED percentage scaled to usable context)
|
|
26
|
+
// Claude Code reserves ~16.5% for autocompact buffer, so usable context
|
|
27
|
+
// is 83.5% of the total window. We normalize to show 100% at that point.
|
|
28
|
+
const AUTO_COMPACT_BUFFER_PCT = 16.5;
|
|
29
|
+
let ctx = '';
|
|
30
|
+
if (remaining != null) {
|
|
31
|
+
// Normalize: subtract buffer from remaining, scale to usable range
|
|
32
|
+
const usableRemaining = Math.max(0, ((remaining - AUTO_COMPACT_BUFFER_PCT) / (100 - AUTO_COMPACT_BUFFER_PCT)) * 100);
|
|
33
|
+
const used = Math.max(0, Math.min(100, Math.round(100 - usableRemaining)));
|
|
34
|
+
|
|
35
|
+
// Write context metrics to bridge file for the context-monitor PostToolUse hook.
|
|
36
|
+
// The monitor reads this file to inject agent-facing warnings when context is low.
|
|
37
|
+
if (session) {
|
|
38
|
+
try {
|
|
39
|
+
const bridgePath = path.join(os.tmpdir(), `claude-ctx-${session}.json`);
|
|
40
|
+
const bridgeData = JSON.stringify({
|
|
41
|
+
session_id: session,
|
|
42
|
+
remaining_percentage: remaining,
|
|
43
|
+
used_pct: used,
|
|
44
|
+
timestamp: Math.floor(Date.now() / 1000)
|
|
45
|
+
});
|
|
46
|
+
fs.writeFileSync(bridgePath, bridgeData);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// Silent fail -- bridge is best-effort, don't break statusline
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Build progress bar (10 segments)
|
|
53
|
+
const filled = Math.floor(used / 10);
|
|
54
|
+
const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
|
|
55
|
+
|
|
56
|
+
// Color based on usable context thresholds
|
|
57
|
+
if (used < 50) {
|
|
58
|
+
ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
|
|
59
|
+
} else if (used < 65) {
|
|
60
|
+
ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
|
|
61
|
+
} else if (used < 80) {
|
|
62
|
+
ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
|
|
63
|
+
} else {
|
|
64
|
+
ctx = ` \x1b[5;31m💀 ${bar} ${used}%\x1b[0m`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Current task from todos
|
|
69
|
+
let task = '';
|
|
70
|
+
const homeDir = os.homedir();
|
|
71
|
+
// Respect CLAUDE_CONFIG_DIR for custom config directory setups (#870)
|
|
72
|
+
const claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(homeDir, '.claude');
|
|
73
|
+
const todosDir = path.join(claudeDir, 'todos');
|
|
74
|
+
if (session && fs.existsSync(todosDir)) {
|
|
75
|
+
try {
|
|
76
|
+
const files = fs.readdirSync(todosDir)
|
|
77
|
+
.filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
|
|
78
|
+
.map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
|
|
79
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
80
|
+
|
|
81
|
+
if (files.length > 0) {
|
|
82
|
+
try {
|
|
83
|
+
const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
|
|
84
|
+
const inProgress = todos.find(t => t.status === 'in_progress');
|
|
85
|
+
if (inProgress) task = inProgress.activeForm || '';
|
|
86
|
+
} catch (e) {}
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
// Silently fail on file system errors - don't break statusline
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// EZ Agents update available?
|
|
94
|
+
let ezUpdate = '';
|
|
95
|
+
const cacheFile = path.join(claudeDir, 'cache', 'ez-update-check.json');
|
|
96
|
+
if (fs.existsSync(cacheFile)) {
|
|
97
|
+
try {
|
|
98
|
+
const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
99
|
+
if (cache.update_available) {
|
|
100
|
+
ezUpdate = '\x1b[33m⬆ /ez:update\x1b[0m │ ';
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Output
|
|
106
|
+
const dirname = path.basename(dir);
|
|
107
|
+
if (task) {
|
|
108
|
+
process.stdout.write(`${ezUpdate}\x1b[2m${model}\x1b[0m │ \x1b[1m${task}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}`);
|
|
109
|
+
} else {
|
|
110
|
+
process.stdout.write(`${ezUpdate}\x1b[2m${model}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}`);
|
|
111
|
+
}
|
|
112
|
+
} catch (e) {
|
|
113
|
+
// Silent fail - don't break statusline on parse errors
|
|
114
|
+
}
|
|
115
|
+
});
|