frontier-mcp 0.6.0 → 1.0.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.
- package/README.md +33 -0
- package/dist/domain.d.ts +62 -29
- package/dist/domain.d.ts.map +1 -1
- package/dist/domain.js +9 -0
- package/dist/domain.js.map +1 -1
- package/dist/frontier.js +1 -1
- package/dist/frontier.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +14 -8
- package/dist/server.js.map +1 -1
- package/dist/storage/driver.d.ts +44 -6
- package/dist/storage/driver.d.ts.map +1 -1
- package/dist/storage/driver.js +65 -5
- package/dist/storage/driver.js.map +1 -1
- package/dist/storage/markdown/create.d.ts +0 -2
- package/dist/storage/markdown/create.d.ts.map +1 -1
- package/dist/storage/markdown/create.js +0 -10
- 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 +55 -25
- package/dist/storage/markdown/driver.js.map +1 -1
- package/dist/storage/markdown/frontmatter.js +1 -1
- package/dist/storage/markdown/header-doc.d.ts.map +1 -1
- package/dist/storage/markdown/header-doc.js +13 -11
- package/dist/storage/markdown/header-doc.js.map +1 -1
- package/dist/storage/markdown/legacy.d.ts +8 -4
- package/dist/storage/markdown/legacy.d.ts.map +1 -1
- package/dist/storage/markdown/legacy.js +20 -15
- package/dist/storage/markdown/legacy.js.map +1 -1
- package/dist/storage/markdown/migrate.d.ts +11 -3
- package/dist/storage/markdown/migrate.d.ts.map +1 -1
- package/dist/storage/markdown/migrate.js +69 -80
- package/dist/storage/markdown/migrate.js.map +1 -1
- package/dist/storage/markdown/schema.d.ts +9 -0
- package/dist/storage/markdown/schema.d.ts.map +1 -0
- package/dist/storage/markdown/schema.js +21 -0
- package/dist/storage/markdown/schema.js.map +1 -0
- package/dist/storage/markdown/serialize.d.ts +1 -1
- package/dist/storage/markdown/serialize.d.ts.map +1 -1
- package/dist/storage/markdown/serialize.js +110 -24
- package/dist/storage/markdown/serialize.js.map +1 -1
- package/dist/storage/markdown/ticket.d.ts +29 -6
- package/dist/storage/markdown/ticket.d.ts.map +1 -1
- package/dist/storage/markdown/ticket.js +100 -33
- package/dist/storage/markdown/ticket.js.map +1 -1
- package/dist/storage/markdown/watcher.d.ts +1 -1
- package/dist/storage/markdown/watcher.d.ts.map +1 -1
- package/dist/storage/markdown/watcher.js +91 -11
- package/dist/storage/markdown/watcher.js.map +1 -1
- package/dist/tools/create-tickets.js +1 -1
- package/dist/tools/create-tickets.js.map +1 -1
- package/dist/tools/edit-map.d.ts.map +1 -1
- package/dist/tools/edit-map.js +6 -2
- package/dist/tools/edit-map.js.map +1 -1
- package/dist/tools/get-board.d.ts.map +1 -1
- package/dist/tools/get-board.js +34 -7
- package/dist/tools/get-board.js.map +1 -1
- package/dist/tools/get-tickets.d.ts.map +1 -1
- package/dist/tools/get-tickets.js +16 -9
- package/dist/tools/get-tickets.js.map +1 -1
- package/dist/tools/list-efforts.d.ts +7 -0
- package/dist/tools/list-efforts.d.ts.map +1 -1
- package/dist/tools/list-efforts.js +15 -0
- package/dist/tools/list-efforts.js.map +1 -1
- package/dist/tools/migrate-effort.d.ts +6 -1
- package/dist/tools/migrate-effort.d.ts.map +1 -1
- package/dist/tools/migrate-effort.js +59 -20
- package/dist/tools/migrate-effort.js.map +1 -1
- package/dist/tools/update-ticket.d.ts +2 -0
- package/dist/tools/update-ticket.d.ts.map +1 -1
- package/dist/tools/update-ticket.js +11 -4
- package/dist/tools/update-ticket.js.map +1 -1
- package/dist/workspace.d.ts +11 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +17 -5
- package/dist/workspace.js.map +1 -1
- package/docs/agents/issue-tracker.md +15 -9
- package/package.json +11 -11
- package/scripts/frontier-setup.cjs +451 -18
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The best-effort parser for Ticket files
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The best-effort parser for Ticket files with no usable frontmatter fence:
|
|
3
|
+
* none at all, or one whose YAML does not parse, which is read as prose whole.
|
|
4
|
+
* Every field it produces is an inference, which is why such a Ticket is
|
|
5
|
+
* flagged Foreign: an agent needs to know which values to distrust.
|
|
6
|
+
*
|
|
7
|
+
* The file is named for the one unstructured prose shape it parses, not for
|
|
8
|
+
* Foreign. A Foreign Ticket can also carry a fence that parses but does not
|
|
9
|
+
* conform, and that one never reaches this parser, so `foreign.ts` would claim
|
|
10
|
+
* a generality this module does not have.
|
|
5
11
|
*
|
|
6
12
|
* The shapes here are the ones the real repos actually contain, not the ones a
|
|
7
13
|
* schema would have liked. Reads never write, so a file parsed badly is only
|
|
@@ -29,8 +35,8 @@ const STRIKETHROUGH = /~~[\s\S]*?~~/g;
|
|
|
29
35
|
* label like `[../T99/issues/01.md]` would otherwise mint an Edge to T99.
|
|
30
36
|
*/
|
|
31
37
|
const MARKDOWN_LINK = /\[[^\]]*\]\([^)]*\)/g;
|
|
32
|
-
/** `T31`, and `T38.1` — a sub-slice of T38, which
|
|
33
|
-
const TICKET_REF = /\bT(\d+)(
|
|
38
|
+
/** `T31`, and `T38.1` or `T38.1.2` — a sub-slice of T38, which may or may not be a Ticket. */
|
|
39
|
+
const TICKET_REF = /\bT(\d+)((?:\.\d+)+)?\b/g;
|
|
34
40
|
/**
|
|
35
41
|
* A bare `01` in `Blocked by: 01, 02` — this Effort's sort orders, written
|
|
36
42
|
* before ids existed. Anything touching a `.` is excluded so a version string
|
|
@@ -69,10 +75,10 @@ const TRIAGE_WORDS = new Set([
|
|
|
69
75
|
'ready-for-human',
|
|
70
76
|
'wontfix',
|
|
71
77
|
]);
|
|
72
|
-
export function
|
|
78
|
+
export function parseProseBody(contents) {
|
|
73
79
|
const { id, title } = readHeading(contents);
|
|
74
80
|
const { status, triage, unrecognized } = readStatus(STATUS_LINE.exec(contents)?.[1]);
|
|
75
|
-
const { edges,
|
|
81
|
+
const { edges, subSlices } = readEdges(contents);
|
|
76
82
|
const type = TYPE_LINE.exec(contents)?.[1];
|
|
77
83
|
return {
|
|
78
84
|
id,
|
|
@@ -85,7 +91,7 @@ export function parseLegacyBody(contents) {
|
|
|
85
91
|
triage,
|
|
86
92
|
blockedBy: edges,
|
|
87
93
|
unrecognizedStatus: unrecognized,
|
|
88
|
-
|
|
94
|
+
subSlices,
|
|
89
95
|
};
|
|
90
96
|
}
|
|
91
97
|
function readHeading(contents) {
|
|
@@ -129,24 +135,23 @@ function readStatus(raw) {
|
|
|
129
135
|
*/
|
|
130
136
|
function readEdges(contents) {
|
|
131
137
|
const edges = new Set();
|
|
132
|
-
const
|
|
138
|
+
const subSlices = new Set();
|
|
133
139
|
for (const line of contents.matchAll(EDGE_LINE)) {
|
|
134
140
|
const declared = (line[1] ?? '').replace(STRIKETHROUGH, '').replace(MARKDOWN_LINK, '');
|
|
135
141
|
if (/^\s*(?:—|–|-|none)\s*$/i.test(declared))
|
|
136
142
|
continue;
|
|
137
143
|
for (const ref of declared.matchAll(TICKET_REF)) {
|
|
138
|
-
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
// the one the file declared.
|
|
144
|
+
// A plain `T1` beside `T1.4` is its own Edge, so each keeps the form it
|
|
145
|
+
// was written in.
|
|
146
|
+
const id = `T${ref[1] ?? ''}${ref[2] ?? ''}`;
|
|
142
147
|
if (ref[2] !== undefined)
|
|
143
|
-
|
|
148
|
+
subSlices.add(id);
|
|
144
149
|
edges.add(id);
|
|
145
150
|
}
|
|
146
151
|
for (const bare of declared.matchAll(BARE_ORDER))
|
|
147
152
|
edges.add(bare[1] ?? '');
|
|
148
153
|
}
|
|
149
154
|
edges.delete('');
|
|
150
|
-
return { edges: [...edges],
|
|
155
|
+
return { edges: [...edges], subSlices: [...subSlices] };
|
|
151
156
|
}
|
|
152
157
|
//# sourceMappingURL=legacy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../../src/storage/markdown/legacy.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../../src/storage/markdown/legacy.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,18 +9,26 @@ export interface MigrateFilesRequest {
|
|
|
9
9
|
readonly minting: MintingPlan;
|
|
10
10
|
readonly effort: string;
|
|
11
11
|
readonly issues: string;
|
|
12
|
+
/** `issues` relative to the workspace root, for the report. */
|
|
13
|
+
readonly directory: string;
|
|
12
14
|
readonly entries: readonly TicketFileEntry[];
|
|
15
|
+
/** Every Ticket in the workspace as scanned, to tell which Effort a written Edge lands on. */
|
|
13
16
|
readonly allTickets: readonly TicketSummary[];
|
|
14
17
|
readonly preview: boolean;
|
|
15
|
-
readonly rename: boolean;
|
|
16
18
|
/** Preview only: preserved ids already carried elsewhere, with every claimant file. */
|
|
17
19
|
readonly conflicts: ReadonlyMap<string, readonly string[]>;
|
|
18
20
|
readonly rescan: Rescan;
|
|
19
21
|
readonly readContents: (filename: string) => Promise<string>;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
|
-
* Normalize
|
|
23
|
-
*
|
|
24
|
+
* Normalize Foreign Tickets in one Effort and mint ids for those without.
|
|
25
|
+
* Filenames never change: another Effort's prose may link them by path.
|
|
26
|
+
*
|
|
27
|
+
* A real run mints through `withIdReservations`, so the pattern decides the
|
|
28
|
+
* strategy — a `<N>` pattern holds its guards until every file is on disk, a
|
|
29
|
+
* random one draws against a fresh scan (T62). A preview takes no guards and
|
|
30
|
+
* predicts no ids: an unminted Ticket is named by its handle, everywhere it
|
|
31
|
+
* appears, so two previews of unchanged files are identical.
|
|
24
32
|
*
|
|
25
33
|
* Bare sort-order Edges (`Blocked by: 01`) are rewritten to the id the target
|
|
26
34
|
* Ticket carries after this call — preserved or newly minted — so migration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/migrate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/migrate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAsB,KAAK,WAAW,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAIhF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,8FAA8F;IAC9F,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9D;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC/F"}
|
|
@@ -1,72 +1,85 @@
|
|
|
1
|
-
import { rename as renameFile, unlink } from 'node:fs/promises';
|
|
2
1
|
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
2
|
+
import { withIdReservations } from './create.js';
|
|
4
3
|
import { normalizeTicket } from './serialize.js';
|
|
5
|
-
import {
|
|
4
|
+
import { writeAtomically } from './write.js';
|
|
6
5
|
/**
|
|
7
|
-
* Normalize
|
|
8
|
-
*
|
|
6
|
+
* Normalize Foreign Tickets in one Effort and mint ids for those without.
|
|
7
|
+
* Filenames never change: another Effort's prose may link them by path.
|
|
8
|
+
*
|
|
9
|
+
* A real run mints through `withIdReservations`, so the pattern decides the
|
|
10
|
+
* strategy — a `<N>` pattern holds its guards until every file is on disk, a
|
|
11
|
+
* random one draws against a fresh scan (T62). A preview takes no guards and
|
|
12
|
+
* predicts no ids: an unminted Ticket is named by its handle, everywhere it
|
|
13
|
+
* appears, so two previews of unchanged files are identical.
|
|
9
14
|
*
|
|
10
15
|
* Bare sort-order Edges (`Blocked by: 01`) are rewritten to the id the target
|
|
11
16
|
* Ticket carries after this call — preserved or newly minted — so migration
|
|
12
17
|
* does not leave a Board full of unresolvable `01` references.
|
|
13
18
|
*/
|
|
14
19
|
export async function migrateEffortFiles(request) {
|
|
15
|
-
const { effort, entries, preview,
|
|
16
|
-
const candidates = entries.filter(entry => entry.ticket.
|
|
20
|
+
const { effort, entries, preview, directory } = request;
|
|
21
|
+
const candidates = entries.filter(entry => entry.ticket.foreign || entry.ticket.id === undefined);
|
|
17
22
|
if (candidates.length === 0) {
|
|
18
|
-
return { effort, preview,
|
|
23
|
+
return { effort, preview, directory, changes: [], crossEffortEdges: [], keptSubSlices: [] };
|
|
19
24
|
}
|
|
20
25
|
const needMint = candidates.filter(entry => entry.ticket.id === undefined).length;
|
|
21
|
-
const used = idsOf(request.allTickets);
|
|
22
26
|
if (preview) {
|
|
23
|
-
const plan = planChanges(candidates,
|
|
24
|
-
return {
|
|
27
|
+
const plan = planChanges(candidates, undefined, entries, request.conflicts);
|
|
28
|
+
return {
|
|
29
|
+
effort,
|
|
30
|
+
preview: true,
|
|
31
|
+
directory,
|
|
32
|
+
changes: plan.map(file => file.change),
|
|
33
|
+
...edgeNotes(plan, request),
|
|
34
|
+
};
|
|
25
35
|
}
|
|
26
36
|
return withIdReservations(request.minting, request.storage, needMint, request.rescan, async (minted) => {
|
|
27
|
-
const plan = planChanges(candidates, minted, entries
|
|
37
|
+
const plan = planChanges(candidates, minted, entries);
|
|
28
38
|
await applyPlan(request, plan);
|
|
29
39
|
return {
|
|
30
40
|
effort,
|
|
31
41
|
preview: false,
|
|
32
|
-
|
|
42
|
+
directory,
|
|
33
43
|
changes: plan.map(file => file.change),
|
|
44
|
+
...edgeNotes(plan, request),
|
|
34
45
|
};
|
|
35
46
|
});
|
|
36
47
|
}
|
|
37
|
-
|
|
48
|
+
/** `minted` undefined is a preview: unminted Tickets are named by handle. */
|
|
49
|
+
function planChanges(candidates, minted, entries, conflicts = new Map()) {
|
|
38
50
|
let mintAt = 0;
|
|
39
|
-
const
|
|
51
|
+
const nameByOrder = new Map();
|
|
40
52
|
// Every Ticket in the Effort contributes to Edge remapping — a blocker that
|
|
41
53
|
// already had an id must still be findable by its sort order.
|
|
42
54
|
for (const entry of entries) {
|
|
43
55
|
if (entry.ticket.id !== undefined)
|
|
44
|
-
|
|
56
|
+
nameByOrder.set(entry.ticket.order, entry.ticket.id);
|
|
45
57
|
}
|
|
46
58
|
const assigned = new Map();
|
|
47
59
|
for (const entry of candidates) {
|
|
48
60
|
if (entry.ticket.id !== undefined) {
|
|
49
61
|
assigned.set(entry.ticket.handle, entry.ticket.id);
|
|
50
|
-
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (minted === undefined) {
|
|
65
|
+
assigned.set(entry.ticket.handle, undefined);
|
|
66
|
+
nameByOrder.set(entry.ticket.order, entry.ticket.handle);
|
|
51
67
|
continue;
|
|
52
68
|
}
|
|
53
69
|
const id = minted[mintAt++];
|
|
54
70
|
if (id === undefined)
|
|
55
71
|
throw new Error('Reserved fewer ids than Tickets needing one.');
|
|
56
72
|
assigned.set(entry.ticket.handle, id);
|
|
57
|
-
|
|
73
|
+
nameByOrder.set(entry.ticket.order, id);
|
|
58
74
|
}
|
|
59
75
|
return candidates.map(entry => {
|
|
60
76
|
const id = assigned.get(entry.ticket.handle);
|
|
61
|
-
|
|
62
|
-
throw new Error(`No id planned for ${entry.ticket.handle}.`);
|
|
63
|
-
const to = rename ? ticketFilename(entry.ticket.order, id, entry.ticket.title) : entry.filename;
|
|
64
|
-
const blockedBy = remapEdges(entry.ticket.blockedBy, idByOrder);
|
|
77
|
+
const blockedBy = remapEdges(entry.ticket.blockedBy, nameByOrder);
|
|
65
78
|
return {
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
filename: entry.filename,
|
|
80
|
+
keptSubSlices: entry.ticket.keptSubSlices,
|
|
68
81
|
defaults: {
|
|
69
|
-
id,
|
|
82
|
+
id: id ?? entry.ticket.handle,
|
|
70
83
|
title: entry.ticket.title,
|
|
71
84
|
kind: entry.ticket.kind,
|
|
72
85
|
type: entry.ticket.type,
|
|
@@ -79,68 +92,25 @@ function planChanges(candidates, minted, entries, rename, conflicts = new Map())
|
|
|
79
92
|
id,
|
|
80
93
|
title: entry.ticket.title,
|
|
81
94
|
minted: entry.ticket.id === undefined,
|
|
82
|
-
normalized: entry.ticket.
|
|
83
|
-
|
|
84
|
-
toName: to === entry.filename ? undefined : to,
|
|
95
|
+
normalized: entry.ticket.foreign,
|
|
96
|
+
filename: entry.filename,
|
|
85
97
|
blockedBy,
|
|
86
|
-
duplicateFiles: entry.ticket.id === undefined ? undefined : conflicts.get(id),
|
|
98
|
+
duplicateFiles: entry.ticket.id === undefined ? undefined : conflicts.get(entry.ticket.id),
|
|
87
99
|
},
|
|
88
100
|
};
|
|
89
101
|
});
|
|
90
102
|
}
|
|
91
103
|
async function applyPlan(request, plan) {
|
|
92
|
-
const targets = new Set(plan.map(file => file.to));
|
|
93
|
-
const sources = new Set(plan.map(file => file.from));
|
|
94
|
-
for (const file of plan) {
|
|
95
|
-
if (file.to !== file.from && !sources.has(file.to)) {
|
|
96
|
-
// A name that already exists and is not being vacated would destroy a Ticket.
|
|
97
|
-
const clash = request.entries.some(entry => entry.filename === file.to);
|
|
98
|
-
if (clash) {
|
|
99
|
-
throw new Error(`Cannot rename to ${file.to}: that name is already taken in ${request.effort}.`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Detect two Tickets collapsing onto one target name.
|
|
104
|
-
if (targets.size !== plan.length) {
|
|
105
|
-
throw new Error(`Rename would collide on a filename inside Effort '${request.effort}'.`);
|
|
106
|
-
}
|
|
107
104
|
const prepared = await Promise.all(plan.map(async (file) => ({
|
|
108
|
-
|
|
109
|
-
contents: normalizeTicket(await request.readContents(file.
|
|
110
|
-
})));
|
|
111
|
-
// Same-name updates are per-file atomic. Renames stage every new file first,
|
|
112
|
-
// land them, then remove the vacated names — so a failure mid-batch never
|
|
113
|
-
// deletes a source whose replacement did not land.
|
|
114
|
-
const inPlace = prepared.filter(file => file.from === file.to);
|
|
115
|
-
const moved = prepared.filter(file => file.from !== file.to);
|
|
116
|
-
await Promise.all(inPlace.map(file => writeAtomically(join(request.issues, file.to), file.contents)));
|
|
117
|
-
if (moved.length === 0)
|
|
118
|
-
return;
|
|
119
|
-
const staged = await Promise.allSettled(moved.map(async (file) => ({
|
|
120
|
-
temporary: await stage(join(request.issues, file.to), file.contents),
|
|
121
|
-
target: join(request.issues, file.to),
|
|
122
|
-
from: join(request.issues, file.from),
|
|
105
|
+
filename: file.filename,
|
|
106
|
+
contents: normalizeTicket(await request.readContents(file.filename), file.defaults),
|
|
123
107
|
})));
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
108
|
+
// Settled, not raced: the caller releases its `<N>` guards when this returns
|
|
109
|
+
// or throws, and they must stay held until every write has finished (T62).
|
|
110
|
+
const written = await Promise.allSettled(prepared.map(file => writeAtomically(join(request.issues, file.filename), file.contents)));
|
|
111
|
+
const failed = written.find(result => result.status === 'rejected');
|
|
112
|
+
if (failed !== undefined)
|
|
128
113
|
throw failed.reason;
|
|
129
|
-
}
|
|
130
|
-
const landed = await Promise.allSettled(ready.map(async (entry) => {
|
|
131
|
-
await renameFile(entry.temporary, entry.target);
|
|
132
|
-
return entry;
|
|
133
|
-
}));
|
|
134
|
-
const written = landed.filter(entry => entry.status === 'fulfilled').map(entry => entry.value);
|
|
135
|
-
const lost = landed.find(entry => entry.status === 'rejected');
|
|
136
|
-
if (lost !== undefined) {
|
|
137
|
-
await Promise.allSettled([
|
|
138
|
-
...written.map(entry => unlink(entry.target).catch(() => { })),
|
|
139
|
-
...ready.map(entry => unstage(entry.temporary)),
|
|
140
|
-
]);
|
|
141
|
-
throw lost.reason;
|
|
142
|
-
}
|
|
143
|
-
await Promise.all(written.map(entry => unlink(entry.from)));
|
|
144
114
|
}
|
|
145
115
|
/**
|
|
146
116
|
* A bare sort-order Edge becomes the id of the Ticket at that order. Real ids
|
|
@@ -153,7 +123,26 @@ function remapEdges(edges, idByOrder) {
|
|
|
153
123
|
return idByOrder.get(Number(edge)) ?? edge;
|
|
154
124
|
});
|
|
155
125
|
}
|
|
156
|
-
|
|
157
|
-
|
|
126
|
+
/** Grouped, never per Ticket: what a reader must check by hand after this call. */
|
|
127
|
+
function edgeNotes(plan, request) {
|
|
128
|
+
const effortOf = new Map();
|
|
129
|
+
for (const ticket of request.allTickets) {
|
|
130
|
+
if (ticket.id !== undefined && ticket.effort !== request.effort) {
|
|
131
|
+
effortOf.set(ticket.id, ticket.effort);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const local = new Set(plan.map(file => file.change.id));
|
|
135
|
+
const cross = new Set();
|
|
136
|
+
for (const file of plan) {
|
|
137
|
+
for (const edge of file.change.blockedBy) {
|
|
138
|
+
const foreign = effortOf.get(edge);
|
|
139
|
+
if (foreign !== undefined && !local.has(edge))
|
|
140
|
+
cross.add(`${edge}@${foreign}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// What the scan kept, not a pattern over what is written: a `T7.2` copied
|
|
144
|
+
// from a fence was never a prose sub-slice.
|
|
145
|
+
const kept = new Set(plan.flatMap(file => file.keptSubSlices));
|
|
146
|
+
return { crossEffortEdges: [...cross].toSorted(), keptSubSlices: [...kept].toSorted() };
|
|
158
147
|
}
|
|
159
148
|
//# sourceMappingURL=migrate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/storage/markdown/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/storage/markdown/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frontmatter keys a schema Ticket may carry, in the order a block this
|
|
3
|
+
* driver *creates* is written. The one list: parse reads it to tell imported
|
|
4
|
+
* keys from unimported ones, serialize writes in its order, and `drop_keys`
|
|
5
|
+
* refuses anything in it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FIELD_ORDER: readonly ['id', 'title', 'kind', 'type', 'status', 'triage', 'blocked_by', 'claimed_by', 'claimed_at', 'answer_gist', 'dropped_reason'];
|
|
8
|
+
export declare const SCHEMA_KEYS: ReadonlySet<string>;
|
|
9
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,WAAW,YACtB,IAAI,EACJ,OAAO,EACP,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,CACR,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAAwB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frontmatter keys a schema Ticket may carry, in the order a block this
|
|
3
|
+
* driver *creates* is written. The one list: parse reads it to tell imported
|
|
4
|
+
* keys from unimported ones, serialize writes in its order, and `drop_keys`
|
|
5
|
+
* refuses anything in it.
|
|
6
|
+
*/
|
|
7
|
+
export const FIELD_ORDER = [
|
|
8
|
+
'id',
|
|
9
|
+
'title',
|
|
10
|
+
'kind',
|
|
11
|
+
'type',
|
|
12
|
+
'status',
|
|
13
|
+
'triage',
|
|
14
|
+
'blocked_by',
|
|
15
|
+
'claimed_by',
|
|
16
|
+
'claimed_at',
|
|
17
|
+
'answer_gist',
|
|
18
|
+
'dropped_reason',
|
|
19
|
+
];
|
|
20
|
+
export const SCHEMA_KEYS = new Set(FIELD_ORDER);
|
|
21
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/markdown/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI;IACJ,OAAO;IACP,MAAM;IACN,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,gBAAgB;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -9,7 +9,7 @@ export interface Defaults {
|
|
|
9
9
|
readonly blockedBy: readonly string[];
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Normalize a Ticket file to schema frontmatter. A
|
|
12
|
+
* Normalize a Ticket file to schema frontmatter. A Foreign file with no fence
|
|
13
13
|
* gets a full block from {@link defaults}; a file that already has frontmatter
|
|
14
14
|
* keeps key order and only gains a missing id plus an updated Edge list (so a
|
|
15
15
|
* bare sort-order Edge can become the id migration just minted). Body prose is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/serialize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/serialize.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAgBlD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAiB5E;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA6BxF;AAwSD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK/E"}
|