sprinty-mcp 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/clients/claude/.claude-plugin/plugin.json +1 -1
- package/clients/gemini/GEMINI.md +2 -2
- package/clients/gemini/gemini-extension.json +1 -1
- package/dist/dashboard/ui/chart-windows.d.ts +53 -0
- package/dist/dashboard/ui/chart-windows.js +179 -0
- package/dist/dashboard/ui/chart-windows.js.map +1 -0
- package/dist/dashboard-ui/assets/index-CfXG9Q6x.js +83 -0
- package/dist/dashboard-ui/assets/{index-BIVuXR8M.css → index-Wj1tS6k7.css} +1 -1
- package/dist/dashboard-ui/index.html +2 -2
- package/dist/server.js +2 -2
- package/dist/tools/register.js +4 -4
- package/dist/tools/register.js.map +1 -1
- package/package.json +1 -1
- package/skills/how-to-run-a-sprint/SKILL.md +4 -2
- package/skills/using-sprinty/SKILL.md +2 -2
- package/dist/dashboard-ui/assets/index-CCeVwilw.js +0 -83
package/README.md
CHANGED
|
@@ -121,8 +121,8 @@ subsprint_new({ description, goals, gates, dependencies? })
|
|
|
121
121
|
item_add({ subsprint, title, description, code_locations, gates, dependencies?, high_priority? })
|
|
122
122
|
next({})
|
|
123
123
|
item_done({ id, commit_id, gate_results, changelog: { verb: "added" | "fixed" | "changed" | "removed" | "deprecated" | "security", line } })
|
|
124
|
-
changelog({ path? }) -> { path }
|
|
125
|
-
sprint_close({ coverage: { path, format: "lcov", command? } })
|
|
124
|
+
changelog({ path? }) -> { path } // generates SemVer Markdown
|
|
125
|
+
sprint_close({ coverage: { path, format: "lcov", command? } }) // after changelog generation
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
Use `item_split` when an item is too large and `item_deprecate` when an item is intentionally
|
|
@@ -161,12 +161,12 @@ Dashboard tools:
|
|
|
161
161
|
| `sprint_resume` | Reattach to an existing sprint after an MCP restart; returns dashboard info. |
|
|
162
162
|
| `sprint_list` | List ledgers in a `data_dir` without creating a sprint. |
|
|
163
163
|
| `sprint_detach` | Clear this MCP process binding and stop the dashboard. |
|
|
164
|
-
| `sprint_close` |
|
|
164
|
+
| `sprint_close` | After `changelog({ path? })` has generated SemVer Markdown, re-run gates, require coverage evidence, and close only when all work is resolved. |
|
|
165
165
|
| `sprint_archive` | Archive an active sprint with a recovery reason. |
|
|
166
166
|
| `overview` | Compact sprint summary for orientation. |
|
|
167
167
|
| `next` | Compact active work window with available and blocked items. |
|
|
168
168
|
| `search` | Regex search over the immutable sprint ledger. |
|
|
169
|
-
| `changelog` |
|
|
169
|
+
| `changelog` | Generate the SemVer Markdown changelog at `path` or the sprint data dir and return only the path. |
|
|
170
170
|
|
|
171
171
|
### Work Tools
|
|
172
172
|
|
|
@@ -209,8 +209,9 @@ keep it out of git unless you intentionally want to preserve it elsewhere. Sprin
|
|
|
209
209
|
ledger into compact read models for agents and into the dashboard for humans.
|
|
210
210
|
|
|
211
211
|
Completed items record the commit id, gate results, changelog entry, and Git-backed file change map.
|
|
212
|
-
`
|
|
213
|
-
|
|
212
|
+
Call `changelog({ path? })` before close to generate the SemVer Markdown file from those entries.
|
|
213
|
+
`sprint_close` then re-checks commits, re-runs executable gates, requires coverage evidence, and
|
|
214
|
+
refuses to close while any item is still open.
|
|
214
215
|
|
|
215
216
|
## More Documentation
|
|
216
217
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprinty",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Disciplined sprint workflow: dashboard-at-start, feature subsprints, artifacts, bug-id follow-ups, spike investigations, an immutable git-anchored ledger, and programmatic close gates.",
|
|
5
5
|
"author": { "name": "Elie Bursztein" },
|
|
6
6
|
"homepage": "https://github.com/ebursztein/sprinty",
|
package/clients/gemini/GEMINI.md
CHANGED
|
@@ -34,8 +34,8 @@ subsprint should be one feature; use `spike()` for feature investigations, then
|
|
|
34
34
|
outputs and `follow_up()` with bug ids for bugs found while moving fast. `next()` returns the active
|
|
35
35
|
work window with relevant artifacts and recent activity: all available `high_priority` items first
|
|
36
36
|
by default, then normal available items per subsprint. `item_update({ id, dependencies })` replaces
|
|
37
|
-
dependencies, so pass `dependencies: []` to remove a bad edge. `done` records a Git-backed change map. `changelog()`
|
|
38
|
-
|
|
37
|
+
dependencies, so pass `dependencies: []` to remove a bad edge. `done` records a Git-backed change map and each item's SemVer changelog entry. `changelog({ path? })` generates the SemVer Markdown file with
|
|
38
|
+
sections, item entries, commits, coverage, and change-map tables; run it before `sprint_close`. `sprint_close` rechecks commits, re-runs executable gates, requires
|
|
39
39
|
an LCOV coverage report path, and refuses to close on any blocker. Use `search(pattern,
|
|
40
40
|
context_lines)` to query the immutable ledger. Show the dashboard URL returned by `sprint_new()` or
|
|
41
41
|
`sprint_resume()` to the human so they can watch the sprint timeline; use `dashboard_info()` to
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprinty",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Disciplined sprint workflow with dashboard-at-start, feature subsprints, artifacts, bug-id follow-ups, spike investigations, an immutable git-anchored ledger, and close gates.",
|
|
5
5
|
"contextFileName": "GEMINI.md",
|
|
6
6
|
"mcpServers": {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { TimelineEntry } from "../../domain/projection.js";
|
|
2
|
+
export type EventSegment = {
|
|
3
|
+
category: string;
|
|
4
|
+
count: number;
|
|
5
|
+
};
|
|
6
|
+
export type EventBucket = {
|
|
7
|
+
label: string;
|
|
8
|
+
total: number;
|
|
9
|
+
segments: EventSegment[];
|
|
10
|
+
};
|
|
11
|
+
export type CompletionPoint = {
|
|
12
|
+
time: number;
|
|
13
|
+
movingAverageMs: number;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
};
|
|
16
|
+
export type CompletionRatePoint = {
|
|
17
|
+
time: number;
|
|
18
|
+
percent: number;
|
|
19
|
+
completed: number;
|
|
20
|
+
};
|
|
21
|
+
export interface CompletionSummary {
|
|
22
|
+
points: CompletionPoint[];
|
|
23
|
+
ratePoints: CompletionRatePoint[];
|
|
24
|
+
rateStart: number | null;
|
|
25
|
+
rateEnd: number | null;
|
|
26
|
+
avgMs: number | null;
|
|
27
|
+
medianMs: number | null;
|
|
28
|
+
minMs: number | null;
|
|
29
|
+
maxMs: number | null;
|
|
30
|
+
etaMs: number | null;
|
|
31
|
+
etaAt: string | null;
|
|
32
|
+
projectedAt: number | null;
|
|
33
|
+
openItems: number;
|
|
34
|
+
remainingItems: number;
|
|
35
|
+
}
|
|
36
|
+
export declare function parseTs(ts: string | null | undefined): number | null;
|
|
37
|
+
export declare function recentTimelineWindow(entries: TimelineEntry[], windowMs: number, nowMs: number, sprintStartedAtMs?: number | null): TimelineEntry[];
|
|
38
|
+
export declare function buildEventBuckets(entries: TimelineEntry[], options: {
|
|
39
|
+
nowMs: number;
|
|
40
|
+
windowMs: number;
|
|
41
|
+
sprintStartedAtMs?: number | null;
|
|
42
|
+
bucketCount: number;
|
|
43
|
+
categories: string[];
|
|
44
|
+
formatLabel: (ts: number) => string;
|
|
45
|
+
}): EventBucket[];
|
|
46
|
+
export declare function eventAction(entry: TimelineEntry): string | null;
|
|
47
|
+
export declare function buildCompletionSummary(entries: TimelineEntry[], openItems: number, totalItems: number, options: {
|
|
48
|
+
nowMs: number;
|
|
49
|
+
windowMs: number;
|
|
50
|
+
sprintStartedAtMs?: number | null;
|
|
51
|
+
movingAverageWindow: number;
|
|
52
|
+
formatEta: (ts: number) => string;
|
|
53
|
+
}): CompletionSummary;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
export function parseTs(ts) {
|
|
2
|
+
if (!ts)
|
|
3
|
+
return null;
|
|
4
|
+
const value = Date.parse(ts);
|
|
5
|
+
return Number.isNaN(value) ? null : value;
|
|
6
|
+
}
|
|
7
|
+
export function recentTimelineWindow(entries, windowMs, nowMs, sprintStartedAtMs) {
|
|
8
|
+
const cutoff = fixedWindowStart({ nowMs, windowMs, sprintStartedAtMs });
|
|
9
|
+
return entries.filter((entry) => {
|
|
10
|
+
const time = parseTs(entry.ts);
|
|
11
|
+
return time !== null && time >= cutoff && time <= nowMs;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function buildEventBuckets(entries, options) {
|
|
15
|
+
const bucketCount = Math.max(1, options.bucketCount);
|
|
16
|
+
const windowStart = fixedWindowStart(options);
|
|
17
|
+
const effectiveWindowMs = Math.max(1, options.nowMs - windowStart);
|
|
18
|
+
const bucketMs = Math.max(1, effectiveWindowMs / bucketCount);
|
|
19
|
+
const buckets = Array.from({ length: bucketCount }, (_, index) => ({
|
|
20
|
+
label: options.formatLabel(windowStart + index * bucketMs),
|
|
21
|
+
total: 0,
|
|
22
|
+
counts: new Map(),
|
|
23
|
+
}));
|
|
24
|
+
const normalized = entries
|
|
25
|
+
.map((entry) => ({ entry, time: parseTs(entry.ts) }))
|
|
26
|
+
.filter((row) => row.time !== null && row.time >= windowStart && row.time <= options.nowMs)
|
|
27
|
+
.sort((a, b) => a.time - b.time);
|
|
28
|
+
for (const { entry, time } of normalized) {
|
|
29
|
+
const category = eventAction(entry);
|
|
30
|
+
if (!category)
|
|
31
|
+
continue;
|
|
32
|
+
const bucketIndex = Math.min(bucketCount - 1, Math.max(0, Math.floor((time - windowStart) / bucketMs)));
|
|
33
|
+
const bucket = buckets[bucketIndex];
|
|
34
|
+
if (!bucket)
|
|
35
|
+
continue;
|
|
36
|
+
bucket.total += 1;
|
|
37
|
+
bucket.counts.set(category, (bucket.counts.get(category) ?? 0) + 1);
|
|
38
|
+
}
|
|
39
|
+
return buckets.map((bucket) => ({
|
|
40
|
+
label: bucket.label,
|
|
41
|
+
total: bucket.total,
|
|
42
|
+
segments: options.categories
|
|
43
|
+
.map((category) => ({ category, count: bucket.counts.get(category) ?? 0 }))
|
|
44
|
+
.filter((segment) => segment.count > 0),
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
export function eventAction(entry) {
|
|
48
|
+
if (entry.type === "sprint_created" ||
|
|
49
|
+
entry.type === "subsprint_created" ||
|
|
50
|
+
entry.type === "item_added" ||
|
|
51
|
+
entry.type === "artifact_added" ||
|
|
52
|
+
entry.type === "follow_up_added" ||
|
|
53
|
+
entry.type === "dependencies_added")
|
|
54
|
+
return "added";
|
|
55
|
+
if (entry.type === "item_updated" ||
|
|
56
|
+
entry.type === "note_added" ||
|
|
57
|
+
entry.type === "note_updated" ||
|
|
58
|
+
entry.type === "dependencies_replaced" ||
|
|
59
|
+
entry.type === "artifact_amended")
|
|
60
|
+
return "edited";
|
|
61
|
+
if (entry.type === "sprint_closed" ||
|
|
62
|
+
entry.type === "sprint_archived" ||
|
|
63
|
+
entry.type === "item_resolved" ||
|
|
64
|
+
entry.type === "artifact_deprecated" ||
|
|
65
|
+
entry.type === "spike_concluded" ||
|
|
66
|
+
entry.type === "spike_deprecated")
|
|
67
|
+
return "closed";
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
export function buildCompletionSummary(entries, openItems, totalItems, options) {
|
|
71
|
+
const historyStart = fixedHistoryStart(options);
|
|
72
|
+
const normalized = entries
|
|
73
|
+
.map((entry) => ({ entry, time: parseTs(entry.ts) }))
|
|
74
|
+
.filter((row) => row.time !== null && row.time >= historyStart && row.time <= options.nowMs)
|
|
75
|
+
.sort((a, b) => a.time - b.time);
|
|
76
|
+
const windowStart = fixedWindowStart(options);
|
|
77
|
+
const starts = new Map();
|
|
78
|
+
const points = [];
|
|
79
|
+
const ratePoints = [];
|
|
80
|
+
const cadenceDurations = [];
|
|
81
|
+
const rateTotal = Math.max(0, totalItems);
|
|
82
|
+
const remainingItems = Math.max(0, openItems);
|
|
83
|
+
let completedItems = 0;
|
|
84
|
+
let lastResolvedAt = null;
|
|
85
|
+
if (rateTotal > 0) {
|
|
86
|
+
completedItems = Math.min(rateTotal, normalized.filter((row) => row.entry.type === "item_resolved" && row.time < windowStart).length);
|
|
87
|
+
ratePoints.push({ time: windowStart, percent: percent(completedItems, rateTotal), completed: completedItems });
|
|
88
|
+
}
|
|
89
|
+
for (const { entry, time } of normalized) {
|
|
90
|
+
if (entry.type === "item_added") {
|
|
91
|
+
starts.set(entry.id, time);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (entry.type !== "item_resolved")
|
|
95
|
+
continue;
|
|
96
|
+
if (time < windowStart) {
|
|
97
|
+
starts.delete(entry.id);
|
|
98
|
+
lastResolvedAt = time;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const previousResolvedAt = lastResolvedAt;
|
|
102
|
+
const durationMs = previousResolvedAt === null ? 0 : Math.max(0, time - previousResolvedAt);
|
|
103
|
+
if (previousResolvedAt !== null)
|
|
104
|
+
cadenceDurations.push(durationMs);
|
|
105
|
+
lastResolvedAt = time;
|
|
106
|
+
starts.delete(entry.id);
|
|
107
|
+
points.push({ time, durationMs, movingAverageMs: 0 });
|
|
108
|
+
if (rateTotal > 0) {
|
|
109
|
+
completedItems = Math.min(rateTotal, completedItems + 1);
|
|
110
|
+
ratePoints.push({ time, percent: percent(completedItems, rateTotal), completed: completedItems });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (rateTotal > 0 && remainingItems > 0) {
|
|
114
|
+
const last = ratePoints[ratePoints.length - 1];
|
|
115
|
+
if (last && last.time < options.nowMs) {
|
|
116
|
+
ratePoints.push({ time: options.nowMs, percent: percent(completedItems, rateTotal), completed: completedItems });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (let i = 0; i < points.length; i++) {
|
|
120
|
+
const start = Math.max(0, i - options.movingAverageWindow + 1);
|
|
121
|
+
const window = points.slice(start, i + 1);
|
|
122
|
+
const sum = window.reduce((acc, point) => acc + point.durationMs, 0);
|
|
123
|
+
points[i] = { ...points[i], movingAverageMs: Math.round(sum / window.length) };
|
|
124
|
+
}
|
|
125
|
+
const stats = durationStats(cadenceDurations);
|
|
126
|
+
const etaMs = stats.avgMs && stats.avgMs > 0 ? stats.avgMs * remainingItems : null;
|
|
127
|
+
const projectedAt = etaMs && remainingItems > 0 ? options.nowMs + etaMs : null;
|
|
128
|
+
const etaAt = projectedAt ? options.formatEta(projectedAt) : null;
|
|
129
|
+
const lastRatePoint = ratePoints[ratePoints.length - 1];
|
|
130
|
+
const actualRateEnd = rateTotal > 0 && remainingItems === 0 && lastRatePoint ? lastRatePoint.time : options.nowMs;
|
|
131
|
+
const rateEnd = projectedAt && projectedAt > actualRateEnd ? projectedAt : actualRateEnd;
|
|
132
|
+
return {
|
|
133
|
+
points,
|
|
134
|
+
ratePoints,
|
|
135
|
+
rateStart: windowStart,
|
|
136
|
+
rateEnd,
|
|
137
|
+
avgMs: stats.avgMs,
|
|
138
|
+
medianMs: stats.medianMs,
|
|
139
|
+
minMs: stats.minMs,
|
|
140
|
+
maxMs: stats.maxMs,
|
|
141
|
+
etaMs,
|
|
142
|
+
etaAt,
|
|
143
|
+
projectedAt,
|
|
144
|
+
openItems,
|
|
145
|
+
remainingItems,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function fixedWindowStart(options) {
|
|
149
|
+
const requested = options.nowMs - options.windowMs;
|
|
150
|
+
if (options.sprintStartedAtMs === null || options.sprintStartedAtMs === undefined)
|
|
151
|
+
return requested;
|
|
152
|
+
const sprintStart = Math.min(options.nowMs, options.sprintStartedAtMs);
|
|
153
|
+
return Math.max(requested, sprintStart);
|
|
154
|
+
}
|
|
155
|
+
function fixedHistoryStart(options) {
|
|
156
|
+
if (options.sprintStartedAtMs === null || options.sprintStartedAtMs === undefined)
|
|
157
|
+
return Number.NEGATIVE_INFINITY;
|
|
158
|
+
return Math.min(options.nowMs, options.sprintStartedAtMs);
|
|
159
|
+
}
|
|
160
|
+
function percent(done, total) {
|
|
161
|
+
return total <= 0 ? 0 : Math.round((done / total) * 100);
|
|
162
|
+
}
|
|
163
|
+
function durationStats(durations) {
|
|
164
|
+
if (!durations.length)
|
|
165
|
+
return { avgMs: null, medianMs: null, minMs: null, maxMs: null };
|
|
166
|
+
const avgMs = Math.round(durations.reduce((sum, value) => sum + value, 0) / durations.length);
|
|
167
|
+
const sorted = [...durations].sort((a, b) => a - b);
|
|
168
|
+
const mid = Math.floor(sorted.length / 2);
|
|
169
|
+
const medianMs = sorted.length % 2 === 1
|
|
170
|
+
? sorted[mid]
|
|
171
|
+
: (sorted[mid - 1] + sorted[mid]) / 2;
|
|
172
|
+
return {
|
|
173
|
+
avgMs,
|
|
174
|
+
medianMs,
|
|
175
|
+
minMs: sorted[0],
|
|
176
|
+
maxMs: sorted[sorted.length - 1],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=chart-windows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-windows.js","sourceRoot":"","sources":["../../../src/dashboard/ui/chart-windows.ts"],"names":[],"mappings":"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"}
|