cleargate 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/MANIFEST.json +71 -15
  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.md +4 -2
  25. package/templates/cleargate-planning/.claude/agents/developer.md +4 -11
  26. package/templates/cleargate-planning/.claude/agents/qa.md +14 -6
  27. package/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +2 -2
  28. package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +19 -1
  29. package/templates/cleargate-planning/.cleargate/config.example.yml +16 -0
  30. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.deferred-verify.red.node.test.ts +245 -0
  31. package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +227 -0
  32. package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +5 -4
  33. package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +75 -2
  34. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +48 -0
  35. package/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +57 -1
  36. package/templates/cleargate-planning/.cleargate/scripts/provision_worktree_config.sh +155 -0
  37. package/templates/cleargate-planning/.cleargate/scripts/qa_red_lint.mjs +380 -0
  38. package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +34 -1
  39. package/templates/cleargate-planning/.cleargate/scripts/test/cr077_eviction.red.sh +113 -0
  40. package/templates/cleargate-planning/.cleargate/scripts/test/cr078_init.test.sh +309 -0
  41. package/templates/cleargate-planning/.cleargate/scripts/test/cr079_provision.red.sh +262 -0
  42. package/templates/cleargate-planning/.cleargate/scripts/test/cr080_wrapper.test.sh +177 -0
  43. package/templates/cleargate-planning/.cleargate/scripts/test/cr081_qa_red_lint.red.sh +348 -0
  44. package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/.session-totals.json +1 -0
  45. package/templates/cleargate-planning/.cleargate/sprint-runs/_off-sprint/token-ledger.jsonl +27 -0
  46. package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +17 -0
  47. package/templates/cleargate-planning/.cleargate/templates/story.md +1 -0
  48. package/templates/cleargate-planning/MANIFEST.json +71 -15
  49. package/dist/admin-api/index.cjs.map +0 -1
  50. package/dist/admin-api/index.js.map +0 -1
  51. package/dist/auth/factory.cjs.map +0 -1
  52. package/dist/auth/factory.js.map +0 -1
  53. package/dist/auth/require-token.cjs.map +0 -1
  54. package/dist/auth/require-token.js.map +0 -1
  55. package/dist/auth/token-store.cjs.map +0 -1
  56. package/dist/auth/token-store.js.map +0 -1
  57. package/dist/bootstrap-root-QKSA5V75.js.map +0 -1
  58. package/dist/chunk-5DI2Z3C2.js.map +0 -1
  59. package/dist/chunk-BTSZOEWC.js.map +0 -1
  60. package/dist/chunk-E3X7IE5E.js.map +0 -1
  61. package/dist/chunk-PDE37WFQ.js.map +0 -1
  62. package/dist/cli.cjs.map +0 -1
  63. package/dist/cli.js.map +0 -1
  64. package/dist/lib/ledger.cjs.map +0 -1
  65. package/dist/lib/ledger.js.map +0 -1
  66. package/dist/lib/lifecycle-reconcile.cjs.map +0 -1
  67. package/dist/lib/lifecycle-reconcile.js.map +0 -1
  68. package/dist/templates/cleargate-planning/.claude/agents/architect-reader.md +0 -61
  69. package/dist/templates/cleargate-planning/.claude/agents/architect-synth.md +0 -124
  70. package/dist/templates/cleargate-planning/.claude/agents/architect.md +0 -230
  71. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +0 -108
  72. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +0 -194
  73. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +0 -261
  74. package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-query.md +0 -143
  75. package/dist/templates/cleargate-planning/.claude/agents/developer.md +0 -185
  76. package/dist/templates/cleargate-planning/.claude/agents/devops.md +0 -257
  77. package/dist/templates/cleargate-planning/.claude/agents/qa.md +0 -171
  78. package/dist/templates/cleargate-planning/.claude/agents/reporter.md +0 -274
  79. package/dist/templates/cleargate-planning/.claude/hooks/pending-task-sentinel.sh +0 -209
  80. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +0 -33
  81. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-test-ratchet.sh +0 -58
  82. package/dist/templates/cleargate-planning/.claude/hooks/pre-commit.sh +0 -19
  83. package/dist/templates/cleargate-planning/.claude/hooks/pre-edit-gate.sh +0 -162
  84. package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-autonomy.sh +0 -58
  85. package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +0 -148
  86. package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +0 -75
  87. package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +0 -43
  88. package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +0 -590
  89. package/dist/templates/cleargate-planning/.claude/settings.json +0 -68
  90. package/dist/templates/cleargate-planning/.claude/skills/flashcard/SKILL.md +0 -102
  91. package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +0 -742
  92. package/dist/templates/cleargate-planning/.cleargate/FLASHCARD.md +0 -7
  93. package/dist/templates/cleargate-planning/.cleargate/config.example.yml +0 -67
  94. package/dist/templates/cleargate-planning/.cleargate/config.yml +0 -18
  95. package/dist/templates/cleargate-planning/.cleargate/delivery/archive/.gitkeep +0 -0
  96. package/dist/templates/cleargate-planning/.cleargate/delivery/pending-sync/.gitkeep +0 -0
  97. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +0 -551
  98. package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +0 -878
  99. package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +0 -160
  100. package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +0 -213
  101. package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +0 -71
  102. package/dist/templates/cleargate-planning/.cleargate/scripts/_migrate-schema-v3.mjs +0 -120
  103. package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +0 -265
  104. package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +0 -1012
  105. package/dist/templates/cleargate-planning/.cleargate/scripts/collision_surface.sh +0 -114
  106. package/dist/templates/cleargate-planning/.cleargate/scripts/constants.mjs +0 -62
  107. package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +0 -219
  108. package/dist/templates/cleargate-planning/.cleargate/scripts/file_surface_diff.sh +0 -320
  109. package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +0 -15
  110. package/dist/templates/cleargate-planning/.cleargate/scripts/init_gate_config.sh +0 -38
  111. package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +0 -240
  112. package/dist/templates/cleargate-planning/.cleargate/scripts/launch_wave.mjs +0 -341
  113. package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +0 -54
  114. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_common.sh +0 -206
  115. package/dist/templates/cleargate-planning/.cleargate/scripts/pre_gate_runner.sh +0 -371
  116. package/dist/templates/cleargate-planning/.cleargate/scripts/prefill_report.mjs +0 -280
  117. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +0 -378
  118. package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +0 -888
  119. package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +0 -209
  120. package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +0 -71
  121. package/dist/templates/cleargate-planning/.cleargate/scripts/state.schema.json +0 -127
  122. package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +0 -717
  123. package/dist/templates/cleargate-planning/.cleargate/scripts/surface-whitelist.txt +0 -27
  124. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_assert_story_files.sh +0 -261
  125. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_file_surface.sh +0 -210
  126. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_flashcard_gate.sh +0 -190
  127. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +0 -482
  128. package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_test_ratchet.sh +0 -327
  129. package/dist/templates/cleargate-planning/.cleargate/scripts/test_ratchet.mjs +0 -261
  130. package/dist/templates/cleargate-planning/.cleargate/scripts/update_state.mjs +0 -246
  131. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_bounce_readiness.mjs +0 -111
  132. package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +0 -184
  133. package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +0 -172
  134. package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +0 -126
  135. package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +0 -130
  136. package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +0 -137
  137. package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +0 -166
  138. package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +0 -111
  139. package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +0 -122
  140. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +0 -50
  141. package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +0 -224
  142. package/dist/templates/cleargate-planning/.cleargate/templates/story.md +0 -213
  143. package/dist/templates/cleargate-planning/CLAUDE.md +0 -66
  144. package/dist/templates/cleargate-planning/MANIFEST.json +0 -503
  145. package/dist/templates/synthesis/active-sprint.md +0 -30
  146. package/dist/templates/synthesis/open-gates.md +0 -38
  147. package/dist/templates/synthesis/product-state.md +0 -31
  148. package/dist/templates/synthesis/roadmap.md +0 -63
  149. 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
- }