sprinty-mcp 0.1.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 (59) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +76 -0
  3. package/dist/dashboard/page.d.ts +1 -0
  4. package/dist/dashboard/page.js +19 -0
  5. package/dist/dashboard/page.js.map +1 -0
  6. package/dist/dashboard/server.d.ts +6 -0
  7. package/dist/dashboard/server.js +23 -0
  8. package/dist/dashboard/server.js.map +1 -0
  9. package/dist/domain/enums.d.ts +13 -0
  10. package/dist/domain/enums.js +11 -0
  11. package/dist/domain/enums.js.map +1 -0
  12. package/dist/domain/events.d.ts +488 -0
  13. package/dist/domain/events.js +49 -0
  14. package/dist/domain/events.js.map +1 -0
  15. package/dist/domain/gates.d.ts +29 -0
  16. package/dist/domain/gates.js +13 -0
  17. package/dist/domain/gates.js.map +1 -0
  18. package/dist/domain/ids.d.ts +2 -0
  19. package/dist/domain/ids.js +7 -0
  20. package/dist/domain/ids.js.map +1 -0
  21. package/dist/domain/projection.d.ts +37 -0
  22. package/dist/domain/projection.js +66 -0
  23. package/dist/domain/projection.js.map +1 -0
  24. package/dist/domain/search.d.ts +8 -0
  25. package/dist/domain/search.js +25 -0
  26. package/dist/domain/search.js.map +1 -0
  27. package/dist/gates/run.d.ts +3 -0
  28. package/dist/gates/run.js +18 -0
  29. package/dist/gates/run.js.map +1 -0
  30. package/dist/git/git.d.ts +6 -0
  31. package/dist/git/git.js +31 -0
  32. package/dist/git/git.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +7 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/ledger/book.d.ts +10 -0
  37. package/dist/ledger/book.js +36 -0
  38. package/dist/ledger/book.js.map +1 -0
  39. package/dist/ledger/ledger.d.ts +10 -0
  40. package/dist/ledger/ledger.js +23 -0
  41. package/dist/ledger/ledger.js.map +1 -0
  42. package/dist/server.d.ts +1 -0
  43. package/dist/server.js +58 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/store/store.d.ts +61 -0
  46. package/dist/store/store.js +162 -0
  47. package/dist/store/store.js.map +1 -0
  48. package/dist/tools/current.d.ts +8 -0
  49. package/dist/tools/current.js +13 -0
  50. package/dist/tools/current.js.map +1 -0
  51. package/dist/tools/register.d.ts +9 -0
  52. package/dist/tools/register.js +32 -0
  53. package/dist/tools/register.js.map +1 -0
  54. package/dist/tools/schemas.d.ts +189 -0
  55. package/dist/tools/schemas.js +40 -0
  56. package/dist/tools/schemas.js.map +1 -0
  57. package/package.json +33 -0
  58. package/skills/how-to-run-a-sprint/SKILL.md +39 -0
  59. package/skills/using-sprinty/SKILL.md +31 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"current.js","sourceRoot":"","sources":["../../src/tools/current.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,aAAa,CAAC,IAAgB,EAAE,IAAY,EAAE,MAAc;IAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;IACzE,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;QACpC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC;QAC3B,iBAAiB,EAAE,OAAO;KAC3B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ import { SprintStore } from "../store/store.js";
3
+ export interface ToolDef {
4
+ description: string;
5
+ schema: z.ZodObject<z.ZodRawShape>;
6
+ handler: (raw: unknown) => Promise<unknown>;
7
+ }
8
+ export type ToolHandlers = Record<string, ToolDef>;
9
+ export declare function buildToolHandlers(store: SprintStore, openDashboard: () => Promise<string>): ToolHandlers;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import { SprintStore } from "../store/store.js";
3
+ import { windowCurrent } from "./current.js";
4
+ import * as S from "./schemas.js";
5
+ function def(schema, description, run) {
6
+ return { description, schema, handler: async (raw) => run(schema.parse(raw)) };
7
+ }
8
+ export function buildToolHandlers(store, openDashboard) {
9
+ return {
10
+ sprint_new: def(S.SprintNewInput, "Start a sprint; returns orientation (skills + how this works).", (i) => ({ ...store.createSprint(i.goal), orientation: orientation() })),
11
+ sprint_close: def(S.SprintCloseInput, "Close the sprint after a programmatic re-check of all gates.", () => store.closeSprint()),
12
+ info: def(S.InfoInput, "The one status read: sprint, subsprints, statuses.", () => store.read()),
13
+ current: def(S.CurrentInput, "Focus window: last closed item + next N, notes scoped to current subsprint.", (i) => windowCurrent(store.read(), i.past, i.future)),
14
+ subsprint_new: def(S.SubsprintNewInput, "Create a subsprint (description, goals, gates).", (i) => store.createSubsprint(i)),
15
+ add: def(S.AddInput, "Add an item (description, code locations, gates — all required).", (i) => store.addItem(i)),
16
+ update: def(S.UpdateInput, "Attach intermediate info to an item or subsprint.", (i) => store.updateItem(i)),
17
+ done: def(S.DoneInput, "Resolve an item as completed with commit id + gate results.", (i) => store.done(i)),
18
+ split: def(S.SplitInput, "Resolve an item as split, creating a seeded subsprint atomically.", (i) => store.split(i)),
19
+ deprecate: def(S.DeprecateInput, "Resolve an item as deprecated with a reason.", (i) => store.deprecate(i)),
20
+ note: def(S.NoteInput, "Add a note to an item or subsprint.", (i) => store.addNote(i)),
21
+ search: def(S.SearchInput, "Regex search over the current sprint's immutable ledger, with context lines.", (i) => store.search(i.pattern, i.context_lines)),
22
+ dashboard: def(S.DashboardInput, "Start (once) and return the follow-along dashboard URL.", async () => ({ url: await openDashboard() })),
23
+ };
24
+ }
25
+ function orientation() {
26
+ return {
27
+ skills: ["how-to-run-a-sprint", "using-sprinty"],
28
+ how: "One sprint per session. Build item-driven: subsprint_new -> add -> done/split/deprecate. " +
29
+ "Items need description + code_locations + gates. Resolve every item, then sprint_close re-runs gates.",
30
+ };
31
+ }
32
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ import { z } from "zod";
2
+ export declare const SprintNewInput: z.ZodObject<{
3
+ goal: z.ZodString;
4
+ }, "strip", z.ZodTypeAny, {
5
+ goal: string;
6
+ }, {
7
+ goal: string;
8
+ }>;
9
+ export declare const SprintCloseInput: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
10
+ export declare const InfoInput: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
11
+ export declare const CurrentInput: z.ZodObject<{
12
+ past: z.ZodDefault<z.ZodNumber>;
13
+ future: z.ZodDefault<z.ZodNumber>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ past: number;
16
+ future: number;
17
+ }, {
18
+ past?: number | undefined;
19
+ future?: number | undefined;
20
+ }>;
21
+ export declare const SubsprintNewInput: z.ZodObject<{
22
+ description: z.ZodString;
23
+ goals: z.ZodArray<z.ZodString, "many">;
24
+ gates: z.ZodArray<z.ZodObject<{
25
+ kind: z.ZodEnum<["test", "typecheck", "build", "command", "manual"]>;
26
+ spec: z.ZodString;
27
+ }, "strip", z.ZodTypeAny, {
28
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
29
+ spec: string;
30
+ }, {
31
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
32
+ spec: string;
33
+ }>, "many">;
34
+ }, "strip", z.ZodTypeAny, {
35
+ description: string;
36
+ goals: string[];
37
+ gates: {
38
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
39
+ spec: string;
40
+ }[];
41
+ }, {
42
+ description: string;
43
+ goals: string[];
44
+ gates: {
45
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
46
+ spec: string;
47
+ }[];
48
+ }>;
49
+ export declare const AddInput: z.ZodObject<{
50
+ subsprint: z.ZodString;
51
+ description: z.ZodString;
52
+ code_locations: z.ZodArray<z.ZodString, "many">;
53
+ gates: z.ZodArray<z.ZodObject<{
54
+ kind: z.ZodEnum<["test", "typecheck", "build", "command", "manual"]>;
55
+ spec: z.ZodString;
56
+ }, "strip", z.ZodTypeAny, {
57
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
58
+ spec: string;
59
+ }, {
60
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
61
+ spec: string;
62
+ }>, "many">;
63
+ }, "strip", z.ZodTypeAny, {
64
+ description: string;
65
+ gates: {
66
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
67
+ spec: string;
68
+ }[];
69
+ code_locations: string[];
70
+ subsprint: string;
71
+ }, {
72
+ description: string;
73
+ gates: {
74
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
75
+ spec: string;
76
+ }[];
77
+ code_locations: string[];
78
+ subsprint: string;
79
+ }>;
80
+ export declare const UpdateInput: z.ZodObject<{
81
+ target: z.ZodString;
82
+ note: z.ZodString;
83
+ }, "strip", z.ZodTypeAny, {
84
+ note: string;
85
+ target: string;
86
+ }, {
87
+ note: string;
88
+ target: string;
89
+ }>;
90
+ export declare const DoneInput: z.ZodObject<{
91
+ item: z.ZodString;
92
+ commit_id: z.ZodString;
93
+ gate_results: z.ZodArray<z.ZodObject<{
94
+ kind: z.ZodEnum<["test", "typecheck", "build", "command", "manual"]>;
95
+ spec: z.ZodString;
96
+ passed: z.ZodBoolean;
97
+ evidence: z.ZodString;
98
+ }, "strip", z.ZodTypeAny, {
99
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
100
+ spec: string;
101
+ passed: boolean;
102
+ evidence: string;
103
+ }, {
104
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
105
+ spec: string;
106
+ passed: boolean;
107
+ evidence: string;
108
+ }>, "many">;
109
+ }, "strip", z.ZodTypeAny, {
110
+ commit_id: string;
111
+ gate_results: {
112
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
113
+ spec: string;
114
+ passed: boolean;
115
+ evidence: string;
116
+ }[];
117
+ item: string;
118
+ }, {
119
+ commit_id: string;
120
+ gate_results: {
121
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
122
+ spec: string;
123
+ passed: boolean;
124
+ evidence: string;
125
+ }[];
126
+ item: string;
127
+ }>;
128
+ export declare const SplitInput: z.ZodObject<{
129
+ item: z.ZodString;
130
+ description: z.ZodString;
131
+ goals: z.ZodArray<z.ZodString, "many">;
132
+ gates: z.ZodArray<z.ZodObject<{
133
+ kind: z.ZodEnum<["test", "typecheck", "build", "command", "manual"]>;
134
+ spec: z.ZodString;
135
+ }, "strip", z.ZodTypeAny, {
136
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
137
+ spec: string;
138
+ }, {
139
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
140
+ spec: string;
141
+ }>, "many">;
142
+ }, "strip", z.ZodTypeAny, {
143
+ description: string;
144
+ goals: string[];
145
+ gates: {
146
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
147
+ spec: string;
148
+ }[];
149
+ item: string;
150
+ }, {
151
+ description: string;
152
+ goals: string[];
153
+ gates: {
154
+ kind: "test" | "typecheck" | "build" | "command" | "manual";
155
+ spec: string;
156
+ }[];
157
+ item: string;
158
+ }>;
159
+ export declare const DeprecateInput: z.ZodObject<{
160
+ item: z.ZodString;
161
+ reason: z.ZodString;
162
+ }, "strip", z.ZodTypeAny, {
163
+ reason: string;
164
+ item: string;
165
+ }, {
166
+ reason: string;
167
+ item: string;
168
+ }>;
169
+ export declare const NoteInput: z.ZodObject<{
170
+ element: z.ZodString;
171
+ text: z.ZodString;
172
+ }, "strip", z.ZodTypeAny, {
173
+ text: string;
174
+ element: string;
175
+ }, {
176
+ text: string;
177
+ element: string;
178
+ }>;
179
+ export declare const SearchInput: z.ZodObject<{
180
+ pattern: z.ZodString;
181
+ context_lines: z.ZodDefault<z.ZodNumber>;
182
+ }, "strip", z.ZodTypeAny, {
183
+ pattern: string;
184
+ context_lines: number;
185
+ }, {
186
+ pattern: string;
187
+ context_lines?: number | undefined;
188
+ }>;
189
+ export declare const DashboardInput: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import { Gate, GateResult } from "../domain/gates.js";
3
+ export const SprintNewInput = z.object({ goal: z.string().min(1) });
4
+ export const SprintCloseInput = z.object({});
5
+ export const InfoInput = z.object({});
6
+ export const CurrentInput = z.object({
7
+ past: z.number().int().nonnegative().default(1),
8
+ future: z.number().int().nonnegative().default(3),
9
+ });
10
+ export const SubsprintNewInput = z.object({
11
+ description: z.string().min(1),
12
+ goals: z.array(z.string().min(1)).min(1),
13
+ gates: z.array(Gate).min(1),
14
+ });
15
+ export const AddInput = z.object({
16
+ subsprint: z.string().min(1),
17
+ description: z.string().min(1),
18
+ code_locations: z.array(z.string().min(1)).min(1),
19
+ gates: z.array(Gate).min(1),
20
+ });
21
+ export const UpdateInput = z.object({ target: z.string().min(1), note: z.string().min(1) });
22
+ export const DoneInput = z.object({
23
+ item: z.string().min(1),
24
+ commit_id: z.string().min(7),
25
+ gate_results: z.array(GateResult).min(1),
26
+ });
27
+ export const SplitInput = z.object({
28
+ item: z.string().min(1),
29
+ description: z.string().min(1),
30
+ goals: z.array(z.string().min(1)).min(1),
31
+ gates: z.array(Gate).min(1),
32
+ });
33
+ export const DeprecateInput = z.object({ item: z.string().min(1), reason: z.string().min(1) });
34
+ export const NoteInput = z.object({ element: z.string().min(1), text: z.string().min(1) });
35
+ export const SearchInput = z.object({
36
+ pattern: z.string().min(1),
37
+ context_lines: z.number().int().nonnegative().default(0),
38
+ });
39
+ export const DashboardInput = z.object({});
40
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/tools/schemas.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "sprinty-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Disciplined sprint MCP for Claude Code, Codex, and Gemini",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "author": "Elie Bursztein",
8
+ "homepage": "https://github.com/ebursztein/sprinty",
9
+ "repository": { "type": "git", "url": "git+https://github.com/ebursztein/sprinty.git" },
10
+ "bugs": { "url": "https://github.com/ebursztein/sprinty/issues" },
11
+ "bin": { "sprinty-mcp": "dist/index.js" },
12
+ "files": ["dist", "skills"],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "pretest": "npm run build",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "test:coverage": "vitest run --coverage",
19
+ "typecheck": "tsc -p tsconfig.json --noEmit",
20
+ "start": "node dist/index.js"
21
+ },
22
+ "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^1.0.0",
24
+ "zod": "^3.23.0"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.5.0",
28
+ "vitest": "^2.0.0",
29
+ "@vitest/coverage-v8": "^2.0.0",
30
+ "@types/node": "^22.0.0"
31
+ },
32
+ "engines": { "node": ">=20" }
33
+ }
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: how-to-run-a-sprint
3
+ description: Use at the start of any non-trivial change to run a disciplined, ledgered sprint via the sprinty MCP. Covers the open -> item-driven build -> resolve -> close loop and the gates.
4
+ ---
5
+
6
+ # How to run a sprint
7
+
8
+ A sprint is one focused unit of work for this session. It is item-driven: you do not
9
+ write prose plans, you create structured items the sprinty MCP records in an immutable ledger.
10
+
11
+ ## The loop
12
+
13
+ 1. **`sprint_new(goal)`** — one sentence of intent. Returns the skills to use and a primer.
14
+ Call **`info()`** any time to re-orient (especially after a context reset).
15
+ 2. **`subsprint_new(description, goals[], gates[])`** — carve the work into a goal-bearing unit.
16
+ A gate is always *about something*: `{ kind: test|typecheck|build|command|manual, spec }`.
17
+ 3. **`add(subsprint, description, code_locations[], gates[])`** — add an item. All three are
18
+ required. The item's gates are what proves it; a `test`-kind gate is the test you must write.
19
+ 4. Work the item. Use **`update(target, note)`** to record intermediate discoveries, and
20
+ **`note(element, text)`** for observations on an item or subsprint.
21
+ 5. Resolve every item exactly one way:
22
+ - **`done(item, commit_id, gate_results[])`** — completed. Requires a *real* commit and
23
+ passing gate results. The server verifies the commit exists.
24
+ - **`split(item, description, goals[], gates[])`** — the item was too big; it becomes a new
25
+ subsprint (atomically resolved as `split`). Then `add` items into the new subsprint.
26
+ - **`deprecate(item, reason)`** — drop it, on the record, with a real reason.
27
+ 6. **`sprint_close()`** — the teeth. It re-runs every executable gate and refuses to close if any
28
+ item is unresolved, any completed item lacks a commit, or any gate fails. Read the blockers,
29
+ fix them, close again.
30
+
31
+ ## Rules
32
+
33
+ - Never invent an id. The server mints `S01`, `S01-001`. Read them back from tool results.
34
+ - No item without a description, at least one code location, and at least one gate.
35
+ - Don't go out of order: orient with `info()`/`current()` before adding or resolving.
36
+ - The ledger is append-only. You cannot un-say a resolution — resolve honestly.
37
+ - Want to watch it live? **`dashboard()`** returns a URL that auto-refreshes.
38
+ - Search the immutable record anytime with **`search(pattern, context_lines)`** (regex + grep-style context).
39
+ - One sprint open at a time. Start a new sprint only after `sprint_close()` accepts the current one.
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: using-sprinty
3
+ description: Reference for the sprinty MCP tools — exact inputs, what each returns, and the failure modes. Use when you need the precise contract of a sprinty tool.
4
+ ---
5
+
6
+ # Using sprinty (tool reference)
7
+
8
+ | Tool | Input | Returns / Rejects |
9
+ |---|---|---|
10
+ | `sprint_new` | `{ goal }` | sprint view + orientation. Rejects if a sprint is already open. |
11
+ | `info` | `{}` | full sprint view (subsprints + items + statuses). |
12
+ | `current` | `{ past?=1, future?=3 }` | last resolved items, next open items, current subsprint notes. |
13
+ | `subsprint_new` | `{ description, goals[], gates[] }` | `{ id: "S0N", … }`. |
14
+ | `add` | `{ subsprint, description, code_locations[], gates[] }` | `{ id: "S0N-00M", … }`. Rejects unknown subsprint. |
15
+ | `update` | `{ target, note }` | view. Rejects unknown target. |
16
+ | `done` | `{ item, commit_id, gate_results[] }` | view. Rejects fake commit / failing gate / already resolved. |
17
+ | `split` | `{ item, description, goals[], gates[] }` | view. Item → `split`, new subsprint seeded. |
18
+ | `deprecate` | `{ item, reason }` | view. Requires non-empty reason. |
19
+ | `note` | `{ element, text }` | view. `element` is an item or subsprint id. |
20
+ | `search` | `{ pattern, context_lines?=0 }` | regex matches over the current sprint ledger, with context lines. |
21
+ | `sprint_close` | `{}` | closed view, or an error listing every blocker. |
22
+ | `dashboard` | `{}` | `{ url }` — read-only live view. |
23
+
24
+ **Gate shape:** `{ kind: "test"|"typecheck"|"build"|"command"|"manual", spec }`.
25
+ Executable kinds are re-run at `sprint_close`; `manual` relies on recorded evidence.
26
+
27
+ **GateResult shape (for `done`):** `{ kind, spec, passed, evidence }`. `passed:false` is rejected.
28
+
29
+ **Storage:** one append-only JSONL ledger per sprint under `.sprinty/`, with a `.sprinty/current`
30
+ pointer naming the active sprint (this enforces one-open-sprint unicity). `.sprinty/` is per
31
+ working tree, so git worktrees run independent sprints.