cleargate 0.8.2 → 0.11.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/CHANGELOG.md +210 -0
- package/README.md +22 -1
- package/dist/MANIFEST.json +276 -31
- package/dist/chunk-HZPJ5QX4.js +459 -0
- package/dist/chunk-HZPJ5QX4.js.map +1 -0
- package/dist/{chunk-OM4FAEA7.js → chunk-Q3BTSXCK.js} +69 -3
- package/dist/chunk-Q3BTSXCK.js.map +1 -0
- package/dist/cli.cjs +2888 -598
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2481 -619
- package/dist/cli.js.map +1 -1
- package/dist/lib/ledger.cjs +120 -0
- package/dist/lib/ledger.cjs.map +1 -0
- package/dist/lib/ledger.d.cts +64 -0
- package/dist/lib/ledger.d.ts +64 -0
- package/dist/lib/ledger.js +96 -0
- package/dist/lib/ledger.js.map +1 -0
- package/dist/lib/lifecycle-reconcile.cjs +497 -0
- package/dist/lib/lifecycle-reconcile.cjs.map +1 -0
- package/dist/lib/lifecycle-reconcile.d.cts +136 -0
- package/dist/lib/lifecycle-reconcile.d.ts +136 -0
- package/dist/lib/lifecycle-reconcile.js +20 -0
- package/dist/lib/lifecycle-reconcile.js.map +1 -0
- package/dist/templates/cleargate-planning/.claude/agents/architect.md +65 -10
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
- package/dist/templates/cleargate-planning/.claude/agents/developer.md +51 -2
- package/dist/templates/cleargate-planning/.claude/agents/devops.md +249 -0
- package/dist/templates/cleargate-planning/.claude/agents/qa.md +91 -1
- package/dist/templates/cleargate-planning/.claude/agents/reporter.md +72 -14
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +21 -0
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
- package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
- package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +12 -1
- package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +334 -96
- package/dist/templates/cleargate-planning/.claude/settings.json +4 -0
- package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +644 -0
- package/dist/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
- package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +160 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +72 -9
- package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
- package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +471 -29
- package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +3 -3
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +86 -10
- package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +173 -87
- package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +483 -13
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +32 -8
- package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +136 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +27 -1
- package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +35 -1
- package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
- package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +40 -3
- package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +53 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
- package/dist/templates/cleargate-planning/.cleargate/templates/proposal.md +17 -4
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +8 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
- package/dist/templates/cleargate-planning/.cleargate/templates/story.md +58 -3
- package/dist/templates/cleargate-planning/CLAUDE.md +30 -10
- package/dist/templates/cleargate-planning/MANIFEST.json +276 -31
- package/dist/{whoami-CX7CXJD5.js → whoami-W4U6DPVG.js} +17 -17
- package/dist/whoami-W4U6DPVG.js.map +1 -0
- package/package.json +20 -6
- package/templates/cleargate-planning/.claude/agents/architect.md +65 -10
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
- package/templates/cleargate-planning/.claude/agents/developer.md +51 -2
- package/templates/cleargate-planning/.claude/agents/devops.md +249 -0
- package/templates/cleargate-planning/.claude/agents/qa.md +91 -1
- package/templates/cleargate-planning/.claude/agents/reporter.md +72 -14
- package/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +21 -0
- package/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
- package/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
- package/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +12 -1
- package/templates/cleargate-planning/.claude/hooks/token-ledger.sh +334 -96
- package/templates/cleargate-planning/.claude/settings.json +4 -0
- package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +644 -0
- package/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
- package/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
- package/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
- package/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +160 -0
- package/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +72 -9
- package/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
- package/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +471 -29
- package/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
- package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +3 -3
- package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +86 -10
- package/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
- package/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
- package/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
- package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +173 -87
- package/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
- package/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +483 -13
- package/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
- package/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +32 -8
- package/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +136 -0
- package/templates/cleargate-planning/.cleargate/templates/Bug.md +27 -1
- package/templates/cleargate-planning/.cleargate/templates/CR.md +35 -1
- package/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
- package/templates/cleargate-planning/.cleargate/templates/epic.md +40 -3
- package/templates/cleargate-planning/.cleargate/templates/hotfix.md +53 -0
- package/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
- package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +8 -0
- package/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
- package/templates/cleargate-planning/.cleargate/templates/story.md +58 -3
- package/templates/cleargate-planning/CLAUDE.md +30 -10
- package/templates/cleargate-planning/MANIFEST.json +276 -31
- package/dist/chunk-OM4FAEA7.js.map +0 -1
- package/dist/whoami-CX7CXJD5.js.map +0 -1
- package/templates/cleargate-planning/.cleargate/templates/proposal.md +0 -61
|
@@ -1,123 +1,209 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# run_script.sh —
|
|
3
|
-
# structured
|
|
4
|
-
#
|
|
5
|
-
#
|
|
2
|
+
# run_script.sh — Arbitrary-command wrapper that captures stdout/stderr independently
|
|
3
|
+
# and writes a structured JSON incident file on non-zero exit.
|
|
4
|
+
#
|
|
5
|
+
# Interface: bash run_script.sh <command> [args...]
|
|
6
|
+
# <command> — any executable on PATH (e.g. node, bash, sh, true, false)
|
|
7
|
+
# [args...] — forwarded to the command unchanged
|
|
8
|
+
#
|
|
9
|
+
# Example (node script):
|
|
10
|
+
# bash run_script.sh node .cleargate/scripts/update_state.mjs STORY-01 Done
|
|
11
|
+
# Example (bash script):
|
|
12
|
+
# bash run_script.sh bash .cleargate/scripts/pre_gate_runner.sh qa .worktrees/X sprint/S-01
|
|
13
|
+
#
|
|
14
|
+
# On success (exit 0): stdout+stderr are passed through; no incident file written.
|
|
15
|
+
# On failure (exit ≠ 0): stdout+stderr are passed through AND a JSON incident is
|
|
16
|
+
# written to .cleargate/sprint-runs/<active-sprint>/.script-incidents/<ts>-<hash>.json
|
|
17
|
+
#
|
|
18
|
+
# Self-exemption: if RUN_SCRIPT_ACTIVE=1 is already set, the wrapper is already
|
|
19
|
+
# running — do not nest. Execute the command directly to avoid infinite recursion.
|
|
20
|
+
# This guard implements the self-exempt contract documented in SKILL.md §C.x.
|
|
21
|
+
#
|
|
22
|
+
# Env vars read:
|
|
23
|
+
# ORCHESTRATOR_PROJECT_DIR — project root override (falls back to CLAUDE_PROJECT_DIR,
|
|
24
|
+
# then to git rev-parse --show-toplevel, then script dir ancestor)
|
|
25
|
+
# AGENT_TYPE — populates incident JSON agent_type field (null if empty)
|
|
26
|
+
# WORK_ITEM_ID — populates incident JSON work_item_id field (null if empty)
|
|
27
|
+
# RUN_SCRIPT_ACTIVE — self-exemption guard (set to 1 by this wrapper)
|
|
28
|
+
|
|
6
29
|
set -euo pipefail
|
|
7
30
|
|
|
8
|
-
|
|
31
|
+
# ---------------------------------------------------------------------------
|
|
32
|
+
# Self-exemption guard — do not wrap recursively
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
if [[ "${RUN_SCRIPT_ACTIVE:-}" == "1" ]]; then
|
|
35
|
+
# Already inside a wrapper invocation; pass through directly, no JSON capture
|
|
36
|
+
exec "$@"
|
|
37
|
+
fi
|
|
9
38
|
|
|
10
39
|
# ---------------------------------------------------------------------------
|
|
11
40
|
# Usage guard
|
|
12
41
|
# ---------------------------------------------------------------------------
|
|
13
42
|
if [[ $# -lt 1 ]]; then
|
|
14
|
-
echo "Usage: run_script.sh <
|
|
43
|
+
echo "Usage: bash run_script.sh <command> [args...]" >&2
|
|
15
44
|
exit 2
|
|
16
45
|
fi
|
|
17
46
|
|
|
18
|
-
SCRIPT_NAME="$1"
|
|
19
|
-
shift
|
|
20
|
-
SCRIPT_ARGS=()
|
|
21
|
-
if [[ $# -gt 0 ]]; then
|
|
22
|
-
SCRIPT_ARGS=("$@")
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
47
|
# ---------------------------------------------------------------------------
|
|
26
|
-
# Resolve
|
|
48
|
+
# Resolve project root for incident file path
|
|
27
49
|
# ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
50
|
+
_resolve_project_root() {
|
|
51
|
+
# Priority: ORCHESTRATOR_PROJECT_DIR → CLAUDE_PROJECT_DIR → git toplevel → script dir ancestor
|
|
52
|
+
if [[ -n "${ORCHESTRATOR_PROJECT_DIR:-}" ]]; then
|
|
53
|
+
echo "$ORCHESTRATOR_PROJECT_DIR"
|
|
54
|
+
return
|
|
55
|
+
fi
|
|
56
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
|
|
57
|
+
echo "$CLAUDE_PROJECT_DIR"
|
|
58
|
+
return
|
|
59
|
+
fi
|
|
60
|
+
if _root=$(git rev-parse --show-toplevel 2>/dev/null); then
|
|
61
|
+
echo "$_root"
|
|
62
|
+
return
|
|
63
|
+
fi
|
|
64
|
+
# Fallback: assume run_script.sh lives in <repo>/.cleargate/scripts/
|
|
65
|
+
echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)"
|
|
66
|
+
}
|
|
33
67
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
EXT="${SCRIPT_NAME##*.}"
|
|
38
|
-
case "$EXT" in
|
|
39
|
-
mjs) RUNNER="node" ;;
|
|
40
|
-
sh) RUNNER="bash" ;;
|
|
41
|
-
*)
|
|
42
|
-
echo "unsupported extension: .${EXT}" >&2
|
|
43
|
-
exit 2
|
|
44
|
-
;;
|
|
45
|
-
esac
|
|
68
|
+
PROJECT_ROOT="$(_resolve_project_root)"
|
|
69
|
+
SPRINT_RUNS_DIR="${PROJECT_ROOT}/.cleargate/sprint-runs"
|
|
70
|
+
ACTIVE_FILE="${SPRINT_RUNS_DIR}/.active"
|
|
46
71
|
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
72
|
+
# Determine sprint incident dir
|
|
73
|
+
if [[ -f "$ACTIVE_FILE" ]]; then
|
|
74
|
+
SPRINT_ID="$(cat "$ACTIVE_FILE" | tr -d '[:space:]')"
|
|
75
|
+
INCIDENTS_DIR="${SPRINT_RUNS_DIR}/${SPRINT_ID}/.script-incidents"
|
|
76
|
+
else
|
|
77
|
+
# No active sprint sentinel → write to _off-sprint bucket
|
|
78
|
+
INCIDENTS_DIR="${SPRINT_RUNS_DIR}/_off-sprint/.script-incidents"
|
|
53
79
|
fi
|
|
54
80
|
|
|
55
81
|
# ---------------------------------------------------------------------------
|
|
56
82
|
# Capture stdout + stderr to temp files
|
|
57
83
|
# ---------------------------------------------------------------------------
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
trap 'rm -f "$
|
|
84
|
+
STDOUT_TMP="$(mktemp)"
|
|
85
|
+
STDERR_TMP="$(mktemp)"
|
|
86
|
+
trap 'rm -f "$STDOUT_TMP" "$STDERR_TMP"' EXIT
|
|
87
|
+
|
|
88
|
+
# Mark self as active before running the wrapped command
|
|
89
|
+
export RUN_SCRIPT_ACTIVE=1
|
|
61
90
|
|
|
62
91
|
EXIT_CODE=0
|
|
63
|
-
|
|
64
|
-
"$RUNNER" "$SCRIPT_PATH" "${SCRIPT_ARGS[@]}" > "$STDOUT_FILE" 2> "$STDERR_FILE" || EXIT_CODE=$?
|
|
65
|
-
else
|
|
66
|
-
"$RUNNER" "$SCRIPT_PATH" > "$STDOUT_FILE" 2> "$STDERR_FILE" || EXIT_CODE=$?
|
|
67
|
-
fi
|
|
92
|
+
"$@" >"$STDOUT_TMP" 2>"$STDERR_TMP" || EXIT_CODE=$?
|
|
68
93
|
|
|
69
94
|
# ---------------------------------------------------------------------------
|
|
70
|
-
#
|
|
95
|
+
# Always pass through stdout + stderr to the caller
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
cat "$STDOUT_TMP"
|
|
98
|
+
cat "$STDERR_TMP" >&2
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
# On success: nothing more to do
|
|
71
102
|
# ---------------------------------------------------------------------------
|
|
72
103
|
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
73
|
-
cat "$STDOUT_FILE"
|
|
74
|
-
cat "$STDERR_FILE" >&2
|
|
75
104
|
exit 0
|
|
76
105
|
fi
|
|
77
106
|
|
|
78
107
|
# ---------------------------------------------------------------------------
|
|
79
|
-
# On failure:
|
|
108
|
+
# On failure: write structured JSON incident file
|
|
80
109
|
# ---------------------------------------------------------------------------
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
MAX_BYTES=4096
|
|
111
|
+
TRUNCATION_SUFFIX="... [truncated]"
|
|
112
|
+
|
|
113
|
+
_truncate_stream() {
|
|
114
|
+
# Byte-correct truncation: use head -c for POSIX byte-count (not bash ${var:0:N}
|
|
115
|
+
# which is char-index — wrong for UTF-8 multi-byte input).
|
|
116
|
+
# Trade-off: output may end with a partial multi-byte char boundary; downstream
|
|
117
|
+
# Node.js JSON.stringify escapes the partial sequence, producing valid JSON.
|
|
118
|
+
local file="$1"
|
|
119
|
+
local file_bytes
|
|
120
|
+
file_bytes="$(wc -c < "$file")"
|
|
121
|
+
if [[ $file_bytes -le $MAX_BYTES ]]; then
|
|
122
|
+
# File fits within budget — emit as-is (no suffix)
|
|
123
|
+
head -c "$MAX_BYTES" "$file"
|
|
124
|
+
else
|
|
125
|
+
# Truncation occurred — emit first MAX_BYTES bytes then TRUNCATION_SUFFIX
|
|
126
|
+
printf '%s' "$(head -c "$MAX_BYTES" "$file")${TRUNCATION_SUFFIX}"
|
|
127
|
+
fi
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
STDOUT_CAPTURED="$(_truncate_stream "$STDOUT_TMP")"
|
|
131
|
+
STDERR_CAPTURED="$(_truncate_stream "$STDERR_TMP")"
|
|
132
|
+
|
|
133
|
+
# Build filename: <ts>-<hash>.json
|
|
134
|
+
TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
135
|
+
TS_FILE="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
136
|
+
# Hash the full command string (first arg + all args)
|
|
137
|
+
HASH="$(printf '%s' "$*" | shasum -a 1 | cut -c1-12)"
|
|
138
|
+
INCIDENT_FILE="${INCIDENTS_DIR}/${TS_FILE}-${HASH}.json"
|
|
139
|
+
|
|
140
|
+
# Ensure incident directory exists
|
|
141
|
+
mkdir -p "$INCIDENTS_DIR"
|
|
142
|
+
|
|
143
|
+
# Collect context
|
|
144
|
+
COMMAND="$1"
|
|
145
|
+
shift
|
|
146
|
+
ARGS_JSON="["
|
|
147
|
+
FIRST=1
|
|
148
|
+
for ARG in "$@"; do
|
|
149
|
+
if [[ $FIRST -eq 1 ]]; then
|
|
150
|
+
FIRST=0
|
|
151
|
+
else
|
|
152
|
+
ARGS_JSON="${ARGS_JSON},"
|
|
153
|
+
fi
|
|
154
|
+
# JSON-escape the arg: replace \ with \\, " with \", newlines with \n
|
|
155
|
+
ARG_ESCAPED="${ARG//\\/\\\\}"
|
|
156
|
+
ARG_ESCAPED="${ARG_ESCAPED//\"/\\\"}"
|
|
157
|
+
ARG_ESCAPED="${ARG_ESCAPED//$'\n'/\\n}"
|
|
158
|
+
ARGS_JSON="${ARGS_JSON}\"${ARG_ESCAPED}\""
|
|
159
|
+
done
|
|
160
|
+
ARGS_JSON="${ARGS_JSON}]"
|
|
161
|
+
|
|
162
|
+
CWD="$(pwd)"
|
|
163
|
+
|
|
164
|
+
# Encode agent_type + work_item_id (null if empty)
|
|
165
|
+
AGENT_TYPE_VAL="${AGENT_TYPE:-}"
|
|
166
|
+
WORK_ITEM_ID_VAL="${WORK_ITEM_ID:-}"
|
|
167
|
+
|
|
168
|
+
if [[ -z "$AGENT_TYPE_VAL" ]]; then
|
|
169
|
+
AGENT_TYPE_JSON="null"
|
|
170
|
+
else
|
|
171
|
+
AGENT_TYPE_JSON="\"${AGENT_TYPE_VAL}\""
|
|
106
172
|
fi
|
|
107
173
|
|
|
174
|
+
if [[ -z "$WORK_ITEM_ID_VAL" ]]; then
|
|
175
|
+
WORK_ITEM_ID_JSON="null"
|
|
176
|
+
else
|
|
177
|
+
WORK_ITEM_ID_JSON="\"${WORK_ITEM_ID_VAL}\""
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# JSON-encode captured streams (escape backslash, double-quote, and newlines)
|
|
181
|
+
_json_str() {
|
|
182
|
+
local s="$1"
|
|
183
|
+
s="${s//\\/\\\\}"
|
|
184
|
+
s="${s//\"/\\\"}"
|
|
185
|
+
s="${s//$'\n'/\\n}"
|
|
186
|
+
s="${s//$'\r'/\\r}"
|
|
187
|
+
printf '%s' "$s"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
STDOUT_JSON="$(_json_str "$STDOUT_CAPTURED")"
|
|
191
|
+
STDERR_JSON="$(_json_str "$STDERR_CAPTURED")"
|
|
192
|
+
COMMAND_JSON="$(_json_str "$COMMAND")"
|
|
193
|
+
CWD_JSON="$(_json_str "$CWD")"
|
|
194
|
+
|
|
195
|
+
cat > "$INCIDENT_FILE" <<JSON
|
|
108
196
|
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
echo "## End Incident"
|
|
121
|
-
} >&2
|
|
197
|
+
"ts": "${TS}",
|
|
198
|
+
"command": "${COMMAND_JSON}",
|
|
199
|
+
"args": ${ARGS_JSON},
|
|
200
|
+
"cwd": "${CWD_JSON}",
|
|
201
|
+
"exit_code": ${EXIT_CODE},
|
|
202
|
+
"stdout": "${STDOUT_JSON}",
|
|
203
|
+
"stderr": "${STDERR_JSON}",
|
|
204
|
+
"agent_type": ${AGENT_TYPE_JSON},
|
|
205
|
+
"work_item_id": ${WORK_ITEM_ID_JSON}
|
|
206
|
+
}
|
|
207
|
+
JSON
|
|
122
208
|
|
|
123
209
|
exit $EXIT_CODE
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sprint_trends.mjs — Sprint trends stub (full implementation deferred to CR-027)
|
|
4
|
+
*
|
|
5
|
+
* Usage: node sprint_trends.mjs <sprint-id>
|
|
6
|
+
*
|
|
7
|
+
* Counts sibling Completed sprints and appends a placeholder Trends section
|
|
8
|
+
* to the current sprint's improvement-suggestions.md.
|
|
9
|
+
*
|
|
10
|
+
* Test seams:
|
|
11
|
+
* CLEARGATE_SPRINT_DIR=<path> — override sprint dir resolution
|
|
12
|
+
* CLEARGATE_SPRINT_RUNS_DIR=<path> — override .cleargate/sprint-runs/ root for sibling counting
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
|
|
19
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
21
|
+
|
|
22
|
+
function main() {
|
|
23
|
+
const sprintId = process.argv[2];
|
|
24
|
+
if (!sprintId) {
|
|
25
|
+
process.stderr.write('Usage: node sprint_trends.mjs <sprint-id>\n');
|
|
26
|
+
process.exit(2);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const sprintDir = process.env.CLEARGATE_SPRINT_DIR
|
|
30
|
+
? path.resolve(process.env.CLEARGATE_SPRINT_DIR)
|
|
31
|
+
: path.join(REPO_ROOT, '.cleargate', 'sprint-runs', sprintId);
|
|
32
|
+
|
|
33
|
+
const sprintRunsDir = process.env.CLEARGATE_SPRINT_RUNS_DIR
|
|
34
|
+
? path.resolve(process.env.CLEARGATE_SPRINT_RUNS_DIR)
|
|
35
|
+
: path.dirname(sprintDir);
|
|
36
|
+
|
|
37
|
+
// Count sibling sprint dirs whose state.json has sprint_status === 'Completed'
|
|
38
|
+
let completedCount = 0;
|
|
39
|
+
if (fs.existsSync(sprintRunsDir)) {
|
|
40
|
+
for (const entry of fs.readdirSync(sprintRunsDir)) {
|
|
41
|
+
if (entry === path.basename(sprintDir)) continue;
|
|
42
|
+
const siblingState = path.join(sprintRunsDir, entry, 'state.json');
|
|
43
|
+
if (!fs.existsSync(siblingState)) continue;
|
|
44
|
+
try {
|
|
45
|
+
const state = JSON.parse(fs.readFileSync(siblingState, 'utf8'));
|
|
46
|
+
if (state.sprint_status === 'Completed') completedCount++;
|
|
47
|
+
} catch { /* skip malformed state.json */ }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const suggestionsFile = path.join(sprintDir, 'improvement-suggestions.md');
|
|
52
|
+
const trendsSection = `\n## Trends\n\nTrends: ${completedCount} closed sprints visible — full analysis deferred to CR-027.\n`;
|
|
53
|
+
|
|
54
|
+
if (!fs.existsSync(suggestionsFile)) {
|
|
55
|
+
const header = `# Improvement Suggestions — ${sprintId}\n\n`;
|
|
56
|
+
const tmpFile = `${suggestionsFile}.tmp.${process.pid}`;
|
|
57
|
+
fs.writeFileSync(tmpFile, header + trendsSection, 'utf8');
|
|
58
|
+
fs.renameSync(tmpFile, suggestionsFile);
|
|
59
|
+
} else {
|
|
60
|
+
const existing = fs.readFileSync(suggestionsFile, 'utf8');
|
|
61
|
+
const tmpFile = `${suggestionsFile}.tmp.${process.pid}`;
|
|
62
|
+
fs.writeFileSync(tmpFile, existing.trimEnd() + trendsSection, 'utf8');
|
|
63
|
+
fs.renameSync(tmpFile, suggestionsFile);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
process.stdout.write(
|
|
67
|
+
`sprint_trends: stub — full implementation deferred to CR-027 (counted ${completedCount} closed sprints).\n`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
main();
|