@jonit-dev/night-watch-cli 1.7.78 → 1.7.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/scripts/night-watch-audit-cron.sh +16 -12
- package/dist/scripts/night-watch-cron.sh +13 -12
- package/dist/scripts/night-watch-helpers.sh +75 -1
- package/dist/scripts/night-watch-pr-reviewer-cron.sh +8 -9
- package/dist/scripts/night-watch-qa-cron.sh +8 -9
- package/dist/scripts/night-watch-slicer-cron.sh +3 -4
- package/package.json +1 -1
|
@@ -23,21 +23,13 @@ SCRIPT_TYPE="audit"
|
|
|
23
23
|
PROVIDER_LABEL="${NW_PROVIDER_LABEL:-}"
|
|
24
24
|
SCRIPT_START_TIME=$(date +%s)
|
|
25
25
|
|
|
26
|
-
# Ensure NVM / Node / Claude are on PATH
|
|
27
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
28
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
29
|
-
|
|
30
26
|
mkdir -p "${LOG_DIR}"
|
|
31
27
|
|
|
32
28
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
33
29
|
# shellcheck source=night-watch-helpers.sh
|
|
34
30
|
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
35
|
-
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
36
|
-
# NOTE: Lock file path must match auditLockPath() in src/utils/status-data.ts
|
|
37
|
-
LOCK_FILE="/tmp/night-watch-audit-${PROJECT_RUNTIME_KEY}.lock"
|
|
38
|
-
AUDIT_PROMPT_TEMPLATE="${SCRIPT_DIR}/../templates/audit.md"
|
|
39
|
-
PROVIDER_MODEL_DISPLAY=$(resolve_provider_model_display "${PROVIDER_CMD}" "${PROVIDER_LABEL}")
|
|
40
31
|
|
|
32
|
+
# emit_result helper - must be defined before use
|
|
41
33
|
emit_result() {
|
|
42
34
|
local status="${1:?status required}"
|
|
43
35
|
local details="${2:-}"
|
|
@@ -48,13 +40,25 @@ emit_result() {
|
|
|
48
40
|
fi
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
# Validate provider
|
|
43
|
+
# Validate provider name first (must be claude or codex)
|
|
52
44
|
if ! validate_provider "${PROVIDER_CMD}"; then
|
|
53
45
|
echo "ERROR: Unknown provider: ${PROVIDER_CMD}" >&2
|
|
54
46
|
emit_result "failure" "reason=unknown_provider"
|
|
55
47
|
exit 1
|
|
56
48
|
fi
|
|
57
49
|
|
|
50
|
+
# Ensure provider CLI is on PATH (nvm, fnm, volta, common bin dirs)
|
|
51
|
+
if ! ensure_provider_on_path "${PROVIDER_CMD}"; then
|
|
52
|
+
echo "ERROR: Provider '${PROVIDER_CMD}' not found in PATH or common installation locations" >&2
|
|
53
|
+
emit_result "failure" "reason=provider_not_found"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
57
|
+
# NOTE: Lock file path must match auditLockPath() in src/utils/status-data.ts
|
|
58
|
+
LOCK_FILE="/tmp/night-watch-audit-${PROJECT_RUNTIME_KEY}.lock"
|
|
59
|
+
AUDIT_PROMPT_TEMPLATE="${SCRIPT_DIR}/../templates/audit.md"
|
|
60
|
+
PROVIDER_MODEL_DISPLAY=$(resolve_provider_model_display "${PROVIDER_CMD}" "${PROVIDER_LABEL}")
|
|
61
|
+
|
|
58
62
|
# Global gate: if queue is enabled and we can't acquire the global lock,
|
|
59
63
|
# enqueue the job and exit. The dispatcher will run it later.
|
|
60
64
|
if [ "${NW_QUEUE_ENABLED:-0}" = "1" ]; then
|
|
@@ -166,7 +170,7 @@ for AUDIT_ATTEMPT in $(seq 1 "${AUDIT_MAX_RETRIES}"); do
|
|
|
166
170
|
cd "${AUDIT_WORKTREE_DIR}" && timeout "${MAX_RUNTIME}" \
|
|
167
171
|
claude -p "${AUDIT_PROMPT}" \
|
|
168
172
|
--dangerously-skip-permissions \
|
|
169
|
-
|
|
173
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
170
174
|
); then
|
|
171
175
|
EXIT_CODE=0
|
|
172
176
|
else
|
|
@@ -180,7 +184,7 @@ for AUDIT_ATTEMPT in $(seq 1 "${AUDIT_MAX_RETRIES}"); do
|
|
|
180
184
|
-C "${AUDIT_WORKTREE_DIR}" \
|
|
181
185
|
--yolo \
|
|
182
186
|
"${AUDIT_PROMPT}" \
|
|
183
|
-
|
|
187
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
184
188
|
); then
|
|
185
189
|
EXIT_CODE=0
|
|
186
190
|
else
|
|
@@ -8,7 +8,7 @@ set -euo pipefail
|
|
|
8
8
|
# NOTE: This script expects environment variables to be set by the caller.
|
|
9
9
|
# The Node.js CLI will inject config values via environment variables.
|
|
10
10
|
# Required env vars (with defaults shown):
|
|
11
|
-
# NW_MAX_RUNTIME=
|
|
11
|
+
# NW_MAX_RUNTIME=14400 - Maximum runtime in seconds (4 hours)
|
|
12
12
|
# NW_PROVIDER_CMD=claude - AI provider CLI to use (claude, codex, etc.)
|
|
13
13
|
# NW_DRY_RUN=0 - Set to 1 for dry-run mode (prints diagnostics only)
|
|
14
14
|
|
|
@@ -22,7 +22,7 @@ else
|
|
|
22
22
|
fi
|
|
23
23
|
LOG_DIR="${PROJECT_DIR}/logs"
|
|
24
24
|
LOG_FILE="${LOG_DIR}/executor.log"
|
|
25
|
-
MAX_RUNTIME="${NW_MAX_RUNTIME:-
|
|
25
|
+
MAX_RUNTIME="${NW_MAX_RUNTIME:-14400}" # 4 hours — used for cooldowns and eligibility
|
|
26
26
|
SESSION_MAX_RUNTIME="${NW_SESSION_MAX_RUNTIME:-${MAX_RUNTIME}}" # per-invocation timeout; defaults to MAX_RUNTIME
|
|
27
27
|
MAX_LOG_SIZE="524288" # 512 KB
|
|
28
28
|
PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
|
|
@@ -34,19 +34,18 @@ EFFECTIVE_PROVIDER_LABEL="${PROVIDER_LABEL}"
|
|
|
34
34
|
BRANCH_PREFIX="${NW_BRANCH_PREFIX:-night-watch}"
|
|
35
35
|
SCRIPT_START_TIME=$(date +%s)
|
|
36
36
|
|
|
37
|
-
# Ensure NVM / Node / Claude are on PATH
|
|
38
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
39
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
40
|
-
|
|
41
|
-
# NOTE: Environment variables should be set by the caller (Node.js CLI).
|
|
42
|
-
# The .env.night-watch sourcing has been removed - config is now injected via env vars.
|
|
43
|
-
|
|
44
37
|
mkdir -p "${LOG_DIR}"
|
|
45
38
|
|
|
46
39
|
# Load shared helpers
|
|
47
40
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
48
41
|
# shellcheck source=night-watch-helpers.sh
|
|
49
42
|
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
43
|
+
|
|
44
|
+
# Ensure provider CLI is on PATH (nvm, fnm, volta, common bin dirs)
|
|
45
|
+
if ! ensure_provider_on_path "${PROVIDER_CMD}"; then
|
|
46
|
+
echo "ERROR: Provider '${PROVIDER_CMD}' not found in PATH or common installation locations" >&2
|
|
47
|
+
exit 127
|
|
48
|
+
fi
|
|
50
49
|
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
51
50
|
# NOTE: Lock file path must match executorLockPath() in src/utils/status-data.ts
|
|
52
51
|
LOCK_FILE="/tmp/night-watch-${PROJECT_RUNTIME_KEY}.lock"
|
|
@@ -548,7 +547,7 @@ while [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; do
|
|
|
548
547
|
cd "${WORKTREE_DIR}" && timeout "${SESSION_MAX_RUNTIME}" \
|
|
549
548
|
claude -p "${PROMPT}" \
|
|
550
549
|
--dangerously-skip-permissions \
|
|
551
|
-
|
|
550
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
552
551
|
); then
|
|
553
552
|
EXIT_CODE=0
|
|
554
553
|
else
|
|
@@ -562,7 +561,7 @@ while [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; do
|
|
|
562
561
|
-C "${WORKTREE_DIR}" \
|
|
563
562
|
--yolo \
|
|
564
563
|
"${PROMPT}" \
|
|
565
|
-
|
|
564
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
566
565
|
); then
|
|
567
566
|
EXIT_CODE=0
|
|
568
567
|
else
|
|
@@ -629,7 +628,7 @@ if [ "${RATE_LIMIT_FALLBACK_TRIGGERED}" = "1" ]; then
|
|
|
629
628
|
claude -p "${PROMPT}" \
|
|
630
629
|
--dangerously-skip-permissions \
|
|
631
630
|
--model "${FALLBACK_MODEL}" \
|
|
632
|
-
|
|
631
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
633
632
|
); then
|
|
634
633
|
EXIT_CODE=0
|
|
635
634
|
else
|
|
@@ -667,6 +666,7 @@ if [ ${EXIT_CODE} -eq 0 ]; then
|
|
|
667
666
|
fi
|
|
668
667
|
"${NW_CLI}" board close-issue "${ISSUE_NUMBER}" 2>>"${LOG_FILE}" || \
|
|
669
668
|
"${NW_CLI}" board move-issue "${ISSUE_NUMBER}" --column "Done" 2>>"${LOG_FILE}" || true
|
|
669
|
+
log "SUCCESS: PR opened and ready for review — ${PR_URL}"
|
|
670
670
|
emit_result "success_open_pr" "prd=${ELIGIBLE_PRD}|branch=${BRANCH_NAME}"
|
|
671
671
|
elif finalize_prd_done "implemented, PR opened on ${BRANCH_NAME}"; then
|
|
672
672
|
# Non-board mode: post attribution comment to the PR
|
|
@@ -675,6 +675,7 @@ if [ ${EXIT_CODE} -eq 0 ]; then
|
|
|
675
675
|
if [ -n "${NON_BOARD_PR_URL}" ]; then
|
|
676
676
|
gh pr comment "${NON_BOARD_PR_URL}" --body "> 🤖 Implemented by ${EFFECTIVE_PROVIDER_LABEL}" 2>>"${LOG_FILE}" || true
|
|
677
677
|
fi
|
|
678
|
+
log "SUCCESS: PR opened and ready for review — ${NON_BOARD_PR_URL}"
|
|
678
679
|
emit_result "success_open_pr" "prd=${ELIGIBLE_PRD}|branch=${BRANCH_NAME}"
|
|
679
680
|
else
|
|
680
681
|
night_watch_history record "${PROJECT_DIR}" "${ELIGIBLE_PRD}" failure --exit-code 1 2>/dev/null || true
|
|
@@ -2,6 +2,78 @@
|
|
|
2
2
|
# Night Watch helper functions — shared by cron scripts.
|
|
3
3
|
# Source this file, don't execute it directly.
|
|
4
4
|
|
|
5
|
+
# ── Provider PATH resolution ─────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
# Ensure AI provider CLI (claude, codex, etc.) and Node.js tooling are
|
|
8
|
+
# discoverable on PATH. Sources common Node version managers and probes
|
|
9
|
+
# well-known bin directories so the script works regardless of how the
|
|
10
|
+
# provider was installed (nvm, fnm, volta, npm global, Homebrew, etc.).
|
|
11
|
+
# Returns 0 if the provider is found, 1 otherwise.
|
|
12
|
+
ensure_provider_on_path() {
|
|
13
|
+
local provider="${1:-claude}"
|
|
14
|
+
|
|
15
|
+
# Already available — nothing to do
|
|
16
|
+
if command -v "${provider}" >/dev/null 2>&1; then
|
|
17
|
+
return 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# ── Node version managers ──────────────────────────────────────────────
|
|
21
|
+
# nvm
|
|
22
|
+
export NVM_DIR="${NVM_DIR:-${HOME}/.nvm}"
|
|
23
|
+
if [ -s "${NVM_DIR}/nvm.sh" ]; then
|
|
24
|
+
# shellcheck source=/dev/null
|
|
25
|
+
. "${NVM_DIR}/nvm.sh"
|
|
26
|
+
if command -v "${provider}" >/dev/null 2>&1; then return 0; fi
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# fnm (Fast Node Manager)
|
|
30
|
+
if command -v fnm >/dev/null 2>&1; then
|
|
31
|
+
eval "$(fnm env 2>/dev/null)" || true
|
|
32
|
+
elif [ -x "${HOME}/.local/share/fnm/fnm" ]; then
|
|
33
|
+
export PATH="${HOME}/.local/share/fnm:${PATH}"
|
|
34
|
+
eval "$(fnm env 2>/dev/null)" || true
|
|
35
|
+
fi
|
|
36
|
+
if command -v "${provider}" >/dev/null 2>&1; then return 0; fi
|
|
37
|
+
|
|
38
|
+
# volta
|
|
39
|
+
if [ -d "${HOME}/.volta/bin" ]; then
|
|
40
|
+
export PATH="${HOME}/.volta/bin:${PATH}"
|
|
41
|
+
if command -v "${provider}" >/dev/null 2>&1; then return 0; fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# mise / asdf
|
|
45
|
+
if [ -d "${HOME}/.local/share/mise/shims" ]; then
|
|
46
|
+
export PATH="${HOME}/.local/share/mise/shims:${PATH}"
|
|
47
|
+
if command -v "${provider}" >/dev/null 2>&1; then return 0; fi
|
|
48
|
+
fi
|
|
49
|
+
if [ -d "${HOME}/.asdf/shims" ]; then
|
|
50
|
+
export PATH="${HOME}/.asdf/shims:${PATH}"
|
|
51
|
+
if command -v "${provider}" >/dev/null 2>&1; then return 0; fi
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# ── Well-known bin directories ─────────────────────────────────────────
|
|
55
|
+
local candidate_dirs=(
|
|
56
|
+
"${HOME}/.npm-global/bin"
|
|
57
|
+
"${HOME}/.local/bin"
|
|
58
|
+
"${HOME}/.claude/bin"
|
|
59
|
+
"/usr/local/bin"
|
|
60
|
+
"${HOME}/.yarn/bin"
|
|
61
|
+
"${HOME}/.bun/bin"
|
|
62
|
+
"${HOME}/.local/share/pnpm"
|
|
63
|
+
"/home/linuxbrew/.linuxbrew/bin"
|
|
64
|
+
"/opt/homebrew/bin"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
for dir in "${candidate_dirs[@]}"; do
|
|
68
|
+
if [ -x "${dir}/${provider}" ]; then
|
|
69
|
+
export PATH="${dir}:${PATH}"
|
|
70
|
+
return 0
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
|
|
74
|
+
return 1
|
|
75
|
+
}
|
|
76
|
+
|
|
5
77
|
# ── Provider validation ───────────────────────────────────────────────────────
|
|
6
78
|
|
|
7
79
|
# Validates that the provider command is supported.
|
|
@@ -168,7 +240,9 @@ log() {
|
|
|
168
240
|
_esec=$(( _elapsed % 60 ))
|
|
169
241
|
elapsed_str=" [+${_emin}m${_esec}s]"
|
|
170
242
|
fi
|
|
171
|
-
|
|
243
|
+
local msg="[$(date '+%Y-%m-%d %H:%M:%S')] [PID:$$]${elapsed_str} $*"
|
|
244
|
+
echo "${msg}" >> "${log_file}"
|
|
245
|
+
echo "${msg}" >&2
|
|
172
246
|
}
|
|
173
247
|
|
|
174
248
|
# Write a visual separator line to the log to delimit separate runs.
|
|
@@ -54,18 +54,17 @@ if [ "${REVIEWER_RETRY_DELAY}" -gt 300 ]; then
|
|
|
54
54
|
REVIEWER_RETRY_DELAY="300"
|
|
55
55
|
fi
|
|
56
56
|
|
|
57
|
-
# Ensure NVM / Node / Claude are on PATH
|
|
58
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
59
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
60
|
-
|
|
61
|
-
# NOTE: Environment variables should be set by the caller (Node.js CLI).
|
|
62
|
-
# The .env.night-watch sourcing has been removed - config is now injected via env vars.
|
|
63
|
-
|
|
64
57
|
mkdir -p "${LOG_DIR}"
|
|
65
58
|
|
|
66
59
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
67
60
|
# shellcheck source=night-watch-helpers.sh
|
|
68
61
|
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
62
|
+
|
|
63
|
+
# Ensure provider CLI is on PATH (nvm, fnm, volta, common bin dirs)
|
|
64
|
+
if ! ensure_provider_on_path "${PROVIDER_CMD}"; then
|
|
65
|
+
echo "ERROR: Provider '${PROVIDER_CMD}' not found in PATH or common installation locations" >&2
|
|
66
|
+
exit 127
|
|
67
|
+
fi
|
|
69
68
|
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
70
69
|
PROVIDER_MODEL_DISPLAY=$(resolve_provider_model_display "${PROVIDER_CMD}" "${PROVIDER_LABEL}")
|
|
71
70
|
GLOBAL_LOCK_FILE="/tmp/night-watch-pr-reviewer-${PROJECT_RUNTIME_KEY}.lock"
|
|
@@ -1078,7 +1077,7 @@ for ATTEMPT in $(seq 1 "${TOTAL_ATTEMPTS}"); do
|
|
|
1078
1077
|
cd "${REVIEW_WORKTREE_DIR}" && timeout "${ATTEMPT_TIMEOUT}" \
|
|
1079
1078
|
claude -p "${REVIEWER_PROMPT}" \
|
|
1080
1079
|
--dangerously-skip-permissions \
|
|
1081
|
-
|
|
1080
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
1082
1081
|
); then
|
|
1083
1082
|
EXIT_CODE=0
|
|
1084
1083
|
else
|
|
@@ -1092,7 +1091,7 @@ for ATTEMPT in $(seq 1 "${TOTAL_ATTEMPTS}"); do
|
|
|
1092
1091
|
-C "${REVIEW_WORKTREE_DIR}" \
|
|
1093
1092
|
--yolo \
|
|
1094
1093
|
"${REVIEWER_PROMPT}" \
|
|
1095
|
-
|
|
1094
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
1096
1095
|
); then
|
|
1097
1096
|
EXIT_CODE=0
|
|
1098
1097
|
else
|
|
@@ -29,18 +29,17 @@ QA_ARTIFACTS="${NW_QA_ARTIFACTS:-both}"
|
|
|
29
29
|
QA_AUTO_INSTALL_PLAYWRIGHT="${NW_QA_AUTO_INSTALL_PLAYWRIGHT:-1}"
|
|
30
30
|
SCRIPT_START_TIME=$(date +%s)
|
|
31
31
|
|
|
32
|
-
# Ensure NVM / Node / Claude are on PATH
|
|
33
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
34
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
35
|
-
|
|
36
|
-
# NOTE: Environment variables should be set by the caller (Node.js CLI).
|
|
37
|
-
# The .env.night-watch sourcing has been removed - config is now injected via env vars.
|
|
38
|
-
|
|
39
32
|
mkdir -p "${LOG_DIR}"
|
|
40
33
|
|
|
41
34
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
42
35
|
# shellcheck source=night-watch-helpers.sh
|
|
43
36
|
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
37
|
+
|
|
38
|
+
# Ensure provider CLI is on PATH (nvm, fnm, volta, common bin dirs)
|
|
39
|
+
if ! ensure_provider_on_path "${PROVIDER_CMD}"; then
|
|
40
|
+
echo "ERROR: Provider '${PROVIDER_CMD}' not found in PATH or common installation locations" >&2
|
|
41
|
+
exit 127
|
|
42
|
+
fi
|
|
44
43
|
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
45
44
|
# NOTE: Lock file path must match qaLockPath() in src/utils/status-data.ts
|
|
46
45
|
LOCK_FILE="/tmp/night-watch-qa-${PROJECT_RUNTIME_KEY}.lock"
|
|
@@ -598,7 +597,7 @@ Action: generating QA tests and evidence."
|
|
|
598
597
|
cd "${QA_WORKTREE_DIR}" && timeout "${MAX_RUNTIME}" \
|
|
599
598
|
claude -p "${QA_PROMPT}" \
|
|
600
599
|
--dangerously-skip-permissions \
|
|
601
|
-
|
|
600
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
602
601
|
); then
|
|
603
602
|
PROVIDER_OK=1
|
|
604
603
|
else
|
|
@@ -625,7 +624,7 @@ Action: generating QA tests and evidence."
|
|
|
625
624
|
-C "${QA_WORKTREE_DIR}" \
|
|
626
625
|
--yolo \
|
|
627
626
|
"${QA_PROMPT}" \
|
|
628
|
-
|
|
627
|
+
2>&1 | tee -a "${LOG_FILE}"
|
|
629
628
|
); then
|
|
630
629
|
PROVIDER_OK=1
|
|
631
630
|
else
|
|
@@ -25,15 +25,14 @@ PROVIDER_CMD="${NW_PROVIDER_CMD:-claude}"
|
|
|
25
25
|
PROVIDER_LABEL="${NW_PROVIDER_LABEL:-}"
|
|
26
26
|
SCRIPT_START_TIME=$(date +%s)
|
|
27
27
|
|
|
28
|
-
# Ensure NVM / Node / Night Watch CLI are on PATH
|
|
29
|
-
export NVM_DIR="${HOME}/.nvm"
|
|
30
|
-
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
|
|
31
|
-
|
|
32
28
|
mkdir -p "${LOG_DIR}"
|
|
33
29
|
|
|
34
30
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
35
31
|
# shellcheck source=night-watch-helpers.sh
|
|
36
32
|
source "${SCRIPT_DIR}/night-watch-helpers.sh"
|
|
33
|
+
|
|
34
|
+
# Ensure provider CLI is on PATH (nvm, fnm, volta, common bin dirs)
|
|
35
|
+
ensure_provider_on_path "${PROVIDER_CMD}" || true
|
|
37
36
|
PROJECT_RUNTIME_KEY=$(project_runtime_key "${PROJECT_DIR}")
|
|
38
37
|
LOCK_FILE="/tmp/night-watch-slicer-${PROJECT_RUNTIME_KEY}.lock"
|
|
39
38
|
PROVIDER_MODEL_DISPLAY=$(resolve_provider_model_display "${PROVIDER_CMD}" "${PROVIDER_LABEL}")
|