frontier-mcp 0.3.0 → 0.4.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/LICENSE +21 -0
- package/README.md +29 -15
- package/dist/bin.js +62 -0
- package/dist/bin.js.map +1 -1
- package/dist/domain.d.ts +3 -0
- package/dist/domain.d.ts.map +1 -1
- package/dist/domain.js.map +1 -1
- package/dist/frontier.js +2 -0
- package/dist/frontier.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +49 -10
- package/dist/server.js.map +1 -1
- package/dist/storage/markdown/create.d.ts.map +1 -1
- package/dist/storage/markdown/create.js +3 -0
- package/dist/storage/markdown/create.js.map +1 -1
- package/dist/storage/markdown/driver.d.ts.map +1 -1
- package/dist/storage/markdown/driver.js +12 -9
- package/dist/storage/markdown/driver.js.map +1 -1
- package/dist/storage/markdown/header-doc.js +5 -1
- package/dist/storage/markdown/header-doc.js.map +1 -1
- package/dist/storage/markdown/serialize.d.ts.map +1 -1
- package/dist/storage/markdown/serialize.js +6 -0
- package/dist/storage/markdown/serialize.js.map +1 -1
- package/dist/storage/markdown/ticket.d.ts.map +1 -1
- package/dist/storage/markdown/ticket.js +29 -3
- package/dist/storage/markdown/ticket.js.map +1 -1
- package/dist/storage/markdown/write.d.ts +5 -1
- package/dist/storage/markdown/write.d.ts.map +1 -1
- package/dist/storage/markdown/write.js +32 -2
- package/dist/storage/markdown/write.js.map +1 -1
- package/dist/tools/get-board.js +1 -1
- package/dist/tools/get-board.js.map +1 -1
- package/dist/tools/update-ticket.d.ts +18 -1
- package/dist/tools/update-ticket.d.ts.map +1 -1
- package/dist/tools/update-ticket.js +98 -15
- package/dist/tools/update-ticket.js.map +1 -1
- package/docs/agents/issue-tracker.md +7 -4
- package/package.json +7 -3
- package/scripts/frontier-setup.cjs +1517 -0
|
@@ -19,10 +19,18 @@ export const updateTicketInputSchema = z.object({
|
|
|
19
19
|
.object({ reason: z.string().min(1).describe('Why it is beyond the destination.') })
|
|
20
20
|
.optional()
|
|
21
21
|
.describe('Close the Ticket as work ruled out of scope.'),
|
|
22
|
+
reopen: z
|
|
23
|
+
.object({ reason: z.string().min(1).describe('Why it is being reopened.') })
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Return a resolved or dropped Ticket to open.'),
|
|
26
|
+
release: z
|
|
27
|
+
.literal(true)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe('Release the claim on a claimed Ticket and return it to open. Pass { release: true }.'),
|
|
22
30
|
status: z
|
|
23
31
|
.enum(STATUSES)
|
|
24
32
|
.optional()
|
|
25
|
-
.describe('Not settable directly — use claim, resolve, or
|
|
33
|
+
.describe('Not settable directly — use claim, resolve, drop, reopen, or release. Named here to say so.'),
|
|
26
34
|
triage: z
|
|
27
35
|
.enum(TRIAGE_ROLES)
|
|
28
36
|
.optional()
|
|
@@ -43,12 +51,20 @@ export const updateTicketInputSchema = z.object({
|
|
|
43
51
|
.describe('Acceptance criteria to check off, matched on their text. Wrapped criteria match both ' +
|
|
44
52
|
'as get_tickets returns them and re-joined onto one line. All references resolve before ' +
|
|
45
53
|
'anything is written — one unmatched name fails the whole call and leaves the file untouched.'),
|
|
54
|
+
title: z.string().min(1).optional().describe('Replace the Ticket title.'),
|
|
55
|
+
kind: z.enum(['build', 'decision']).optional().describe('Replace the Ticket kind.'),
|
|
56
|
+
type: z
|
|
57
|
+
.string()
|
|
58
|
+
.min(1)
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Replace the decision type — research, prototype, grilling, or task.'),
|
|
46
61
|
root: z.string().optional().describe('Workspace directory. Defaults to the session workspace.'),
|
|
47
62
|
});
|
|
48
|
-
export const updateTicketDescription = 'Change one Ticket. Lifecycle: claim, resolve with a one-line gist,
|
|
49
|
-
'most one of those per call. Graph: replace the Edges,
|
|
50
|
-
'
|
|
51
|
-
'
|
|
63
|
+
export const updateTicketDescription = 'Change one Ticket. Lifecycle: claim, resolve with a one-line gist, drop with a reason, reopen ' +
|
|
64
|
+
'with a reason, or release a claim — at most one of those per call. Graph: replace the Edges, ' +
|
|
65
|
+
'refused if they close a cycle. Identity: title, kind, and type. Annotations: triage role, a ' +
|
|
66
|
+
'comment, ticking acceptance criteria; these touch no part of the graph. Any of the four groups ' +
|
|
67
|
+
'may accompany the others or stand alone.';
|
|
52
68
|
/**
|
|
53
69
|
* Turn a request into the edit the driver applies, refusing anything the Status
|
|
54
70
|
* model or the Edge graph does not allow. Validation lives here rather than in
|
|
@@ -58,10 +74,12 @@ export const updateTicketDescription = 'Change one Ticket. Lifecycle: claim, res
|
|
|
58
74
|
* cycle can run through an Effort this call never names.
|
|
59
75
|
*/
|
|
60
76
|
export function editFor(ticket, all, request, now) {
|
|
61
|
-
//
|
|
62
|
-
// they ride along with a transition or stand on their own. An Edge
|
|
63
|
-
// graph operation and rides along the same way, having been
|
|
77
|
+
// Identity and annotations are not graph operations. They carry no lifecycle
|
|
78
|
+
// meaning, so they ride along with a transition or stand on their own. An Edge
|
|
79
|
+
// change is a graph operation and rides along the same way, having been
|
|
80
|
+
// validated first.
|
|
64
81
|
const annotations = {
|
|
82
|
+
...identityFor(ticket, request),
|
|
65
83
|
...(request.triage === undefined ? {} : { triage: request.triage }),
|
|
66
84
|
...(request.comment === undefined ? {} : { comment: request.comment }),
|
|
67
85
|
...(request.tick === undefined ? {} : { tick: request.tick }),
|
|
@@ -71,15 +89,23 @@ export function editFor(ticket, all, request, now) {
|
|
|
71
89
|
// silently dropping the field — and `wontfix` is a Triage role, so it is not
|
|
72
90
|
// a Status this would have accepted either way.
|
|
73
91
|
if (request.status !== undefined) {
|
|
74
|
-
throw new Error(`status is not set directly. Use claim, resolve, or
|
|
75
|
-
'is a lifecycle position the server derives
|
|
92
|
+
throw new Error(`status is not set directly. Use claim, resolve, drop, reopen, or release; ` +
|
|
93
|
+
`'${request.status}' is a lifecycle position the server derives.`);
|
|
94
|
+
}
|
|
95
|
+
const actions = [
|
|
96
|
+
request.claim,
|
|
97
|
+
request.resolve,
|
|
98
|
+
request.drop,
|
|
99
|
+
request.reopen,
|
|
100
|
+
request.release,
|
|
101
|
+
].filter(action => action !== undefined);
|
|
102
|
+
if (actions.length > 1) {
|
|
103
|
+
throw new Error('Pass at most one of claim, resolve, drop, reopen, or release.');
|
|
76
104
|
}
|
|
77
|
-
const actions = [request.claim, request.resolve, request.drop].filter(action => action !== undefined);
|
|
78
|
-
if (actions.length > 1)
|
|
79
|
-
throw new Error('Pass at most one of claim, resolve, or drop.');
|
|
80
105
|
if (actions.length === 0) {
|
|
81
106
|
if (Object.keys(annotations).length === 0) {
|
|
82
|
-
throw new Error('Nothing to do: pass a lifecycle change, or blocked_by, triage, comment,
|
|
107
|
+
throw new Error('Nothing to do: pass a lifecycle change, or title, kind, type, blocked_by, triage, comment, ' +
|
|
108
|
+
'or tick.');
|
|
83
109
|
}
|
|
84
110
|
return annotations;
|
|
85
111
|
}
|
|
@@ -107,8 +133,32 @@ export function editFor(ticket, all, request, now) {
|
|
|
107
133
|
claimedAt: null,
|
|
108
134
|
};
|
|
109
135
|
}
|
|
136
|
+
if (request.reopen !== undefined) {
|
|
137
|
+
const reopen = reopenEdit(ticket, request.reopen.reason);
|
|
138
|
+
const archiveComment = reopen.comment ?? '';
|
|
139
|
+
const comment = request.comment === undefined ? archiveComment : `${archiveComment}\n\n${request.comment}`;
|
|
140
|
+
const { comment: _ignored, ...rest } = annotations;
|
|
141
|
+
return { ...rest, ...reopen, comment };
|
|
142
|
+
}
|
|
143
|
+
if (request.release !== undefined) {
|
|
144
|
+
return { ...annotations, ...releaseEdit(ticket) };
|
|
145
|
+
}
|
|
110
146
|
throw new Error('Unreachable: an action was counted but none matched.');
|
|
111
147
|
}
|
|
148
|
+
function identityFor(ticket, request) {
|
|
149
|
+
const resultingKind = request.kind ?? ticket.kind;
|
|
150
|
+
if (request.type !== undefined && resultingKind !== 'decision') {
|
|
151
|
+
throw new Error(`"${request.title ?? ticket.title}" is a build Ticket, so it has no type — that field records which ` +
|
|
152
|
+
'wayfinder shape a decision Ticket is.');
|
|
153
|
+
}
|
|
154
|
+
const clearType = request.kind === 'build' && ticket.type !== undefined;
|
|
155
|
+
return {
|
|
156
|
+
...(request.title === undefined ? {} : { title: request.title }),
|
|
157
|
+
...(request.kind === undefined ? {} : { kind: request.kind }),
|
|
158
|
+
...(request.type === undefined ? {} : { type: request.type }),
|
|
159
|
+
...(clearType ? { type: null } : {}),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
112
162
|
/**
|
|
113
163
|
* The new Edge list, refused if it closes a cycle. This is the same check
|
|
114
164
|
* `create_tickets` runs and the easier of the two ways to close a loop — a
|
|
@@ -141,13 +191,46 @@ function claimEdit(ticket, by, now) {
|
|
|
141
191
|
if (ticket.claimedBy !== undefined && ticket.claimedBy !== by) {
|
|
142
192
|
throw new Error(`${ticket.handle} is already claimed by ${ticket.claimedBy}` +
|
|
143
193
|
`${ticket.claimedAt === undefined ? '' : ` since ${ticket.claimedAt}`}. ` +
|
|
144
|
-
'Claims are never auto-released; take it up with the holder.');
|
|
194
|
+
'Claims are never auto-released; use release or take it up with the holder.');
|
|
145
195
|
}
|
|
146
196
|
if (ticket.status === 'resolved' || ticket.status === 'dropped') {
|
|
147
197
|
throw new Error(`${ticket.handle} is already ${ticket.status}, so there is nothing to claim.`);
|
|
148
198
|
}
|
|
149
199
|
return { status: 'claimed', claimedBy: by, claimedAt: now };
|
|
150
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Reopening archives what closed the Ticket in a server-authored comment, then
|
|
203
|
+
* clears the fields that made it closed so the Frontier can take it again.
|
|
204
|
+
*/
|
|
205
|
+
function reopenEdit(ticket, reason) {
|
|
206
|
+
if (ticket.status !== 'resolved' && ticket.status !== 'dropped') {
|
|
207
|
+
throw new Error(`${ticket.handle} is ${ticket.status}, so it cannot be reopened — only resolved or ` +
|
|
208
|
+
'dropped Tickets can.');
|
|
209
|
+
}
|
|
210
|
+
const archive = [`Reopened: ${reason}`];
|
|
211
|
+
if (ticket.status === 'resolved' && ticket.answerGist !== undefined) {
|
|
212
|
+
archive.push(`Previous answer_gist: ${ticket.answerGist}`);
|
|
213
|
+
}
|
|
214
|
+
if (ticket.status === 'dropped' && ticket.droppedReason !== undefined) {
|
|
215
|
+
archive.push(`Previous dropped_reason: ${ticket.droppedReason}`);
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
status: 'open',
|
|
219
|
+
answerGist: null,
|
|
220
|
+
droppedReason: null,
|
|
221
|
+
claimedBy: null,
|
|
222
|
+
claimedAt: null,
|
|
223
|
+
comment: archive.join('\n'),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/** Release clears a claim without touching what closed the Ticket, if anything did. */
|
|
227
|
+
function releaseEdit(ticket) {
|
|
228
|
+
if (ticket.status !== 'claimed') {
|
|
229
|
+
throw new Error(`${ticket.handle} is ${ticket.status}, so its claim cannot be released — only claimed ` +
|
|
230
|
+
'Tickets can.');
|
|
231
|
+
}
|
|
232
|
+
return { status: 'open', claimedBy: null, claimedAt: null };
|
|
233
|
+
}
|
|
151
234
|
export function renderUpdate(ticket, warnings = []) {
|
|
152
235
|
const fields = [
|
|
153
236
|
`status=${ticket.status}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-ticket.js","sourceRoot":"","sources":["../../src/tools/update-ticket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;IACxF,KAAK,EAAE,CAAC;SACL,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;SAC/D,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;IACvE,OAAO,EAAE,CAAC;SACP,MAAM,CAAC;QACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACtF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;KAC3F,CAAC;SACD,QAAQ,EAAE;SACV,QAAQ,CAAC,0CAA0C,CAAC;IACvD,IAAI,EAAE,CAAC;SACJ,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC,EAAE,CAAC;SACnF,QAAQ,EAAE;SACV,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,MAAM,EAAE,CAAC;SACN,
|
|
1
|
+
{"version":3,"file":"update-ticket.js","sourceRoot":"","sources":["../../src/tools/update-ticket.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Issue tracker — FrontierMCP and file fallback
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`CONTEXT.md` when present — Effort, Board, Header doc, Map,
|
|
3
|
+
Use **FrontierMCP** as the issue tracker. Its canonical storage is markdown under `.scratch/`.
|
|
4
|
+
Vocabulary is defined in the project's `CONTEXT.md` when present — Effort, Board, Header doc, Map,
|
|
5
|
+
Spec, Ticket, Edge, Frontier.
|
|
5
6
|
|
|
6
7
|
When **FrontierMCP** (server name `frontier`) is loaded in your session, use the tools below. They
|
|
7
8
|
own the schema, compute the graph, and answer orientation questions for a fraction of the token cost
|
|
@@ -47,7 +48,7 @@ Eight tools permanently. Optional arguments extend an existing tool; there is no
|
|
|
47
48
|
| `get_board` | See the whole Effort cheaply — Destination, one summary line per Ticket, Frontier marked. Never returns bodies. |
|
|
48
49
|
| `get_tickets` | Fetch full bodies for specific ids after the Board tells you which Tickets matter. |
|
|
49
50
|
| `create_tickets` | Publish a breakdown in one call. Declare Edges with temporary keys; the server assigns ids and numbers. |
|
|
50
|
-
| `update_ticket` | Claim, resolve, drop, set triage, replace Edges, comment, or tick acceptance criteria. One Ticket per call. |
|
|
51
|
+
| `update_ticket` | Claim, resolve, drop, reopen, release, set title/kind/type, set triage, replace Edges, comment, or tick acceptance criteria. One Ticket per call. |
|
|
51
52
|
| `edit_map` | Edit Map sections — Destination, Notes, fog, Out of scope. Decisions-so-far regenerates from resolved Tickets. |
|
|
52
53
|
| `spec` | Read or write a Spec as a whole document. |
|
|
53
54
|
| `migrate_effort` | Normalize Legacy Tickets in an Effort. Preview writes nothing; filename rename is opt-in. |
|
|
@@ -58,7 +59,7 @@ Eight tools permanently. Optional arguments extend an existing tool; there is no
|
|
|
58
59
|
2. `get_board` on that Effort — read the Frontier (`>` marker).
|
|
59
60
|
3. `get_tickets` on the ids you will work — read bodies only for those Tickets.
|
|
60
61
|
4. `update_ticket` with `claim` before starting work.
|
|
61
|
-
5. `update_ticket` with `resolve` or `drop` when done; tick criteria and comment as you go.
|
|
62
|
+
5. `update_ticket` with `resolve` or `drop` when done; `reopen` when a closed Ticket needs another pass; `release` when a claim should be dropped without closing; tick criteria and comment as you go.
|
|
62
63
|
6. `create_tickets` when a skill publishes a new breakdown; `edit_map` / `spec` for header docs.
|
|
63
64
|
|
|
64
65
|
### Skill mapping
|
|
@@ -71,6 +72,8 @@ Eight tools permanently. Optional arguments extend an existing tool; there is no
|
|
|
71
72
|
| claim before work | `update_ticket` with `claim` |
|
|
72
73
|
| resolve with an answer | `update_ticket` with `resolve` |
|
|
73
74
|
| rule out of scope | `update_ticket` with `drop`, then `edit_map` `rule_out` if needed |
|
|
75
|
+
| reopen closed work | `update_ticket` with `reopen` |
|
|
76
|
+
| release a stale claim | `update_ticket` with `{ release: true }` |
|
|
74
77
|
| edit the Map | `edit_map` |
|
|
75
78
|
| write or read the Spec | `spec` |
|
|
76
79
|
| normalize legacy files | `migrate_effort` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontier-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "An MCP server exposing the markdown issue tracker under a repo's .scratch/ as a queryable graph",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
|
-
"docs/agents/issue-tracker.md"
|
|
15
|
+
"docs/agents/issue-tracker.md",
|
|
16
|
+
"scripts/frontier-setup.cjs"
|
|
16
17
|
],
|
|
17
18
|
"type": "module",
|
|
18
19
|
"main": "./dist/index.js",
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
"vitest": "^4.1.10"
|
|
40
41
|
},
|
|
41
42
|
"engines": {
|
|
42
|
-
"node": "
|
|
43
|
+
"node": "^20.20.2 || ^22.17.1 || ^24.15.0"
|
|
43
44
|
},
|
|
44
45
|
"scripts": {
|
|
45
46
|
"build": "tsc",
|
|
@@ -51,6 +52,9 @@
|
|
|
51
52
|
"format:check": "oxfmt --check",
|
|
52
53
|
"check": "pnpm run typecheck && pnpm run lint && pnpm run format:check",
|
|
53
54
|
"test": "vitest run",
|
|
55
|
+
"test:runtime": "pnpm run build && node scripts/package-runtime-check.mjs",
|
|
56
|
+
"test:runtime:package": "node scripts/package-runtime-check.mjs",
|
|
57
|
+
"test:setup": "node scripts/frontier-setup-check.cjs",
|
|
54
58
|
"test:watch": "vitest",
|
|
55
59
|
"start": "node src/bin.ts",
|
|
56
60
|
"release:dry": "release-it --dry-run --ci"
|