cleargate 0.14.0 → 0.15.1

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 (150) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/MANIFEST.json +72 -16
  3. package/dist/admin-api/index.cjs +0 -1
  4. package/dist/admin-api/index.js +1 -2
  5. package/dist/auth/factory.cjs +0 -1
  6. package/dist/auth/factory.js +2 -3
  7. package/dist/auth/require-token.cjs +0 -1
  8. package/dist/auth/require-token.js +1 -2
  9. package/dist/auth/token-store.cjs +0 -1
  10. package/dist/auth/token-store.js +1 -2
  11. package/dist/{bootstrap-root-QKSA5V75.js → bootstrap-root-2H5HVTCC.js} +1 -2
  12. package/dist/{chunk-PDE37WFQ.js → chunk-A7MSQUU7.js} +2 -3
  13. package/dist/{chunk-BTSZOEWC.js → chunk-P6KEDAK2.js} +0 -1
  14. package/dist/{chunk-E3X7IE5E.js → chunk-PY6FHGV5.js} +1 -2
  15. package/dist/{chunk-5DI2Z3C2.js → chunk-Y53ZZYYU.js} +1 -2
  16. package/dist/cli.cjs +1564 -1414
  17. package/dist/cli.js +1514 -1364
  18. package/dist/lib/ledger.cjs +0 -1
  19. package/dist/lib/ledger.js +1 -2
  20. package/dist/lib/lifecycle-reconcile.cjs +0 -1
  21. package/dist/lib/lifecycle-reconcile.js +2 -3
  22. package/dist/{whoami-EANGN46Z.js → whoami-JKQQPABQ.js} +3 -4
  23. package/package.json +4 -3
  24. package/templates/cleargate-planning/.claude/agents/architect-synth.md +2 -0
  25. package/templates/cleargate-planning/.claude/agents/architect.md +4 -2
  26. package/templates/cleargate-planning/.claude/agents/developer.md +4 -11
  27. package/templates/cleargate-planning/.claude/agents/qa.md +14 -6
  28. package/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +2 -2
  29. package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +19 -1
  30. package/templates/cleargate-planning/.cleargate/config.example.yml +16 -0
  31. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.deferred-verify.red.node.test.ts +245 -0
  32. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +227 -0
  33. package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +5 -4
  34. package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +75 -2
  35. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +48 -0
  36. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +57 -1
  37. package/templates/cleargate-planning/.cleargate/scripts/provision_worktree_config.sh +155 -0
  38. package/templates/cleargate-planning/.cleargate/scripts/qa_red_lint.mjs +380 -0
  39. package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +34 -1
  40. package/templates/cleargate-planning/.cleargate/scripts/test/cr077_eviction.red.sh +113 -0
  41. package/templates/cleargate-planning/.cleargate/scripts/test/cr078_init.test.sh +309 -0
  42. package/templates/cleargate-planning/.cleargate/scripts/test/cr079_provision.red.sh +262 -0
  43. package/templates/cleargate-planning/.cleargate/scripts/test/cr080_wrapper.test.sh +177 -0
  44. package/templates/cleargate-planning/.cleargate/scripts/test/cr081_qa_red_lint.red.sh +348 -0
  45. package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/.session-totals.json +1 -0
  46. package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/token-ledger.jsonl +222 -0
  47. package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +17 -0
  48. package/templates/cleargate-planning/.cleargate/templates/story.md +1 -0
  49. package/templates/cleargate-planning/MANIFEST.json +72 -16
  50. package/dist/admin-api/index.cjs.map +0 -1
  51. package/dist/admin-api/index.js.map +0 -1
  52. package/dist/auth/factory.cjs.map +0 -1
  53. package/dist/auth/factory.js.map +0 -1
  54. package/dist/auth/require-token.cjs.map +0 -1
  55. package/dist/auth/require-token.js.map +0 -1
  56. package/dist/auth/token-store.cjs.map +0 -1
  57. package/dist/auth/token-store.js.map +0 -1
  58. package/dist/bootstrap-root-QKSA5V75.js.map +0 -1
  59. package/dist/chunk-5DI2Z3C2.js.map +0 -1
  60. package/dist/chunk-BTSZOEWC.js.map +0 -1
  61. package/dist/chunk-E3X7IE5E.js.map +0 -1
  62. package/dist/chunk-PDE37WFQ.js.map +0 -1
  63. package/dist/cli.cjs.map +0 -1
  64. package/dist/cli.js.map +0 -1
  65. package/dist/lib/ledger.cjs.map +0 -1
  66. package/dist/lib/ledger.js.map +0 -1
  67. package/dist/lib/lifecycle-reconcile.cjs.map +0 -1
  68. package/dist/lib/lifecycle-reconcile.js.map +0 -1
  69. package/dist/templates/cleargate-planning/.claude/agents/architect-reader.md +0 -61
  70. package/dist/templates/cleargate-planning/.claude/agents/architect-synth.md +0 -124
  71. package/dist/templates/cleargate-planning/.claude/agents/architect.md +0 -230
  72. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +0 -108
  73. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +0 -194
  74. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +0 -261
  75. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-query.md +0 -143
  76. package/dist/templates/cleargate-planning/.claude/agents/developer.md +0 -185
  77. package/dist/templates/cleargate-planning/.claude/agents/devops.md +0 -257
  78. package/dist/templates/cleargate-planning/.claude/agents/qa.md +0 -171
  79. package/dist/templates/cleargate-planning/.claude/agents/reporter.md +0 -274
  80. package/dist/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +0 -209
  81. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +0 -33
  82. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +0 -58
  83. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit.sh +0 -19
  84. package/dist/templates/cleargate-planning/.claude/hooks/pre-edit-gate.sh +0 -162
  85. package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-autonomy.sh +0 -58
  86. package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +0 -148
  87. package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +0 -75
  88. package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +0 -43
  89. package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +0 -590
  90. package/dist/templates/cleargate-planning/.claude/settings.json +0 -68
  91. package/dist/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +0 -102
  92. package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +0 -742
  93. package/dist/templates/cleargate-planning/.cleargate/FLASHCARD.md +0 -7
  94. package/dist/templates/cleargate-planning/.cleargate/config.example.yml +0 -67
  95. package/dist/templates/cleargate-planning/.cleargate/config.yml +0 -18
  96. package/dist/templates/cleargate-planning/.cleargate/delivery/archive/.gitkeep +0 -0
  97. package/dist/templates/cleargate-planning/.cleargate/delivery/pending-sync/.gitkeep +0 -0
  98. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +0 -551
  99. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +0 -878
  100. package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +0 -160
  101. package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +0 -213
  102. package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +0 -71
  103. package/dist/templates/cleargate-planning/.cleargate/scripts/_migrate-schema-v3.mjs +0 -120
  104. package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +0 -265
  105. package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +0 -1012
  106. package/dist/templates/cleargate-planning/.cleargate/scripts/collision_surface.sh +0 -114
  107. package/dist/templates/cleargate-planning/.cleargate/scripts/constants.mjs +0 -62
  108. package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +0 -219
  109. package/dist/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +0 -320
  110. package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +0 -15
  111. package/dist/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +0 -38
  112. package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +0 -240
  113. package/dist/templates/cleargate-planning/.cleargate/scripts/launch_wave.mjs +0 -341
  114. package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +0 -54
  115. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +0 -206
  116. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +0 -371
  117. package/dist/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +0 -280
  118. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +0 -378
  119. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +0 -888
  120. package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +0 -209
  121. package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +0 -71
  122. package/dist/templates/cleargate-planning/.cleargate/scripts/state.schema.json +0 -127
  123. package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +0 -717
  124. package/dist/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +0 -27
  125. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +0 -261
  126. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +0 -210
  127. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +0 -190
  128. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +0 -482
  129. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +0 -327
  130. package/dist/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +0 -261
  131. package/dist/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +0 -246
  132. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +0 -111
  133. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +0 -184
  134. package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +0 -172
  135. package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +0 -126
  136. package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +0 -130
  137. package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +0 -137
  138. package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +0 -166
  139. package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +0 -111
  140. package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +0 -122
  141. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +0 -50
  142. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +0 -224
  143. package/dist/templates/cleargate-planning/.cleargate/templates/story.md +0 -213
  144. package/dist/templates/cleargate-planning/CLAUDE.md +0 -66
  145. package/dist/templates/cleargate-planning/MANIFEST.json +0 -503
  146. package/dist/templates/synthesis/active-sprint.md +0 -30
  147. package/dist/templates/synthesis/open-gates.md +0 -38
  148. package/dist/templates/synthesis/product-state.md +0 -31
  149. package/dist/templates/synthesis/roadmap.md +0 -63
  150. package/dist/whoami-EANGN46Z.js.map +0 -1
@@ -1,209 +0,0 @@
1
- #!/usr/bin/env bash
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
-
29
- set -euo pipefail
30
-
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
38
-
39
- # ---------------------------------------------------------------------------
40
- # Usage guard
41
- # ---------------------------------------------------------------------------
42
- if [[ $# -lt 1 ]]; then
43
- echo "Usage: bash run_script.sh <command> [args...]" >&2
44
- exit 2
45
- fi
46
-
47
- # ---------------------------------------------------------------------------
48
- # Resolve project root for incident file path
49
- # ---------------------------------------------------------------------------
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
- }
67
-
68
- PROJECT_ROOT="$(_resolve_project_root)"
69
- SPRINT_RUNS_DIR="${PROJECT_ROOT}/.cleargate/sprint-runs"
70
- ACTIVE_FILE="${SPRINT_RUNS_DIR}/.active"
71
-
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"
79
- fi
80
-
81
- # ---------------------------------------------------------------------------
82
- # Capture stdout + stderr to temp files
83
- # ---------------------------------------------------------------------------
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
90
-
91
- EXIT_CODE=0
92
- "$@" >"$STDOUT_TMP" 2>"$STDERR_TMP" || EXIT_CODE=$?
93
-
94
- # ---------------------------------------------------------------------------
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
102
- # ---------------------------------------------------------------------------
103
- if [[ $EXIT_CODE -eq 0 ]]; then
104
- exit 0
105
- fi
106
-
107
- # ---------------------------------------------------------------------------
108
- # On failure: write structured JSON incident file
109
- # ---------------------------------------------------------------------------
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}\""
172
- fi
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
196
- {
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
208
-
209
- exit $EXIT_CODE
@@ -1,71 +0,0 @@
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();
@@ -1,127 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://cleargate.dev/schemas/state.v3.json",
4
- "title": "ClearGate Sprint State v3",
5
- "description": "Schema for .cleargate/sprint-runs/<sprint-id>/state.json. schema_version=3 removes execution_mode (retired by STORY-070-01 — single always-enforced behavior). Migrated from v2 by _migrate-schema-v3.mjs on first read.",
6
- "type": "object",
7
- "required": [
8
- "schema_version",
9
- "sprint_id",
10
- "sprint_status",
11
- "stories",
12
- "last_action",
13
- "updated_at"
14
- ],
15
- "additionalProperties": true,
16
- "properties": {
17
- "schema_version": {
18
- "type": "integer",
19
- "const": 3,
20
- "description": "Schema version. Must be 3 for v3 state files. Bumped from v2 by _migrate-schema-v3.mjs."
21
- },
22
- "sprint_id": {
23
- "type": "string",
24
- "description": "Sprint identifier, e.g. SPRINT-09",
25
- "examples": ["SPRINT-09", "SPRINT-10"]
26
- },
27
- "sprint_status": {
28
- "type": "string",
29
- "description": "Overall sprint status",
30
- "examples": ["Active", "Closed"]
31
- },
32
- "stories": {
33
- "type": "object",
34
- "description": "Map of story ID to story state entry",
35
- "additionalProperties": {
36
- "$ref": "#/definitions/StoryEntry"
37
- }
38
- },
39
- "last_action": {
40
- "type": "string",
41
- "description": "Human-readable description of the last operation performed"
42
- },
43
- "updated_at": {
44
- "type": "string",
45
- "format": "date-time",
46
- "description": "ISO-8601 timestamp of last top-level update"
47
- }
48
- },
49
- "definitions": {
50
- "StoryEntry": {
51
- "type": "object",
52
- "required": [
53
- "state",
54
- "qa_bounces",
55
- "arch_bounces",
56
- "worktree",
57
- "updated_at",
58
- "notes",
59
- "lane",
60
- "lane_assigned_by",
61
- "lane_demoted_at",
62
- "lane_demotion_reason"
63
- ],
64
- "additionalProperties": true,
65
- "properties": {
66
- "state": {
67
- "type": "string",
68
- "enum": [
69
- "Ready to Bounce",
70
- "Bouncing",
71
- "QA Passed",
72
- "Architect Passed",
73
- "Sprint Review",
74
- "Done",
75
- "Escalated",
76
- "Parking Lot"
77
- ],
78
- "description": "Current lifecycle state of the story"
79
- },
80
- "qa_bounces": {
81
- "type": "integer",
82
- "minimum": 0,
83
- "maximum": 3,
84
- "description": "Number of QA bounce cycles. Reaching 3 triggers auto-escalation."
85
- },
86
- "arch_bounces": {
87
- "type": "integer",
88
- "minimum": 0,
89
- "maximum": 3,
90
- "description": "Number of Architect bounce cycles. Reaching 3 triggers auto-escalation."
91
- },
92
- "worktree": {
93
- "type": ["string", "null"],
94
- "description": "Path to the story's git worktree checkout, or null if not in a worktree"
95
- },
96
- "updated_at": {
97
- "type": "string",
98
- "format": "date-time",
99
- "description": "ISO-8601 timestamp of last update to this story entry"
100
- },
101
- "notes": {
102
- "type": "string",
103
- "description": "Free-form notes for this story (escalation reason, QA comments, etc.)"
104
- },
105
- "lane": {
106
- "type": "string",
107
- "enum": ["standard", "fast"],
108
- "description": "Execution lane for this story. Default 'standard'. Set by Architect at sprint design or via --lane flag."
109
- },
110
- "lane_assigned_by": {
111
- "type": "string",
112
- "enum": ["architect", "human-override", "migration-default"],
113
- "description": "Who assigned the lane value. 'migration-default' for stories migrated from v1."
114
- },
115
- "lane_demoted_at": {
116
- "type": ["string", "null"],
117
- "format": "date-time",
118
- "description": "ISO-8601 timestamp when the story was demoted from fast to standard, or null if never demoted."
119
- },
120
- "lane_demotion_reason": {
121
- "type": ["string", "null"],
122
- "description": "Human-readable reason for lane demotion, or null if never demoted."
123
- }
124
- }
125
- }
126
- }
127
- }