frontier-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.
- package/README.md +104 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/domain.d.ts +230 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +23 -0
- package/dist/domain.js.map +1 -0
- package/dist/edges.d.ts +35 -0
- package/dist/edges.d.ts.map +1 -0
- package/dist/edges.js +61 -0
- package/dist/edges.js.map +1 -0
- package/dist/frontier.d.ts +12 -0
- package/dist/frontier.d.ts.map +1 -0
- package/dist/frontier.js +34 -0
- package/dist/frontier.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +29 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +210 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/driver.d.ts +131 -0
- package/dist/storage/driver.d.ts.map +1 -0
- package/dist/storage/driver.js +43 -0
- package/dist/storage/driver.js.map +1 -0
- package/dist/storage/markdown/create.d.ts +52 -0
- package/dist/storage/markdown/create.d.ts.map +1 -0
- package/dist/storage/markdown/create.js +298 -0
- package/dist/storage/markdown/create.js.map +1 -0
- package/dist/storage/markdown/driver.d.ts +7 -0
- package/dist/storage/markdown/driver.d.ts.map +1 -0
- package/dist/storage/markdown/driver.js +492 -0
- package/dist/storage/markdown/driver.js.map +1 -0
- package/dist/storage/markdown/frontmatter.d.ts +17 -0
- package/dist/storage/markdown/frontmatter.d.ts.map +1 -0
- package/dist/storage/markdown/frontmatter.js +36 -0
- package/dist/storage/markdown/frontmatter.js.map +1 -0
- package/dist/storage/markdown/header-doc.d.ts +56 -0
- package/dist/storage/markdown/header-doc.d.ts.map +1 -0
- package/dist/storage/markdown/header-doc.js +287 -0
- package/dist/storage/markdown/header-doc.js.map +1 -0
- package/dist/storage/markdown/legacy.d.ts +16 -0
- package/dist/storage/markdown/legacy.d.ts.map +1 -0
- package/dist/storage/markdown/legacy.js +152 -0
- package/dist/storage/markdown/legacy.js.map +1 -0
- package/dist/storage/markdown/migrate.d.ts +27 -0
- package/dist/storage/markdown/migrate.d.ts.map +1 -0
- package/dist/storage/markdown/migrate.js +158 -0
- package/dist/storage/markdown/migrate.js.map +1 -0
- package/dist/storage/markdown/serialize.d.ts +37 -0
- package/dist/storage/markdown/serialize.d.ts.map +1 -0
- package/dist/storage/markdown/serialize.js +321 -0
- package/dist/storage/markdown/serialize.js.map +1 -0
- package/dist/storage/markdown/ticket.d.ts +12 -0
- package/dist/storage/markdown/ticket.d.ts.map +1 -0
- package/dist/storage/markdown/ticket.js +97 -0
- package/dist/storage/markdown/ticket.js.map +1 -0
- package/dist/storage/markdown/write.d.ts +42 -0
- package/dist/storage/markdown/write.d.ts.map +1 -0
- package/dist/storage/markdown/write.js +134 -0
- package/dist/storage/markdown/write.js.map +1 -0
- package/dist/tools/create-tickets.d.ts +63 -0
- package/dist/tools/create-tickets.d.ts.map +1 -0
- package/dist/tools/create-tickets.js +161 -0
- package/dist/tools/create-tickets.js.map +1 -0
- package/dist/tools/edit-map.d.ts +29 -0
- package/dist/tools/edit-map.d.ts.map +1 -0
- package/dist/tools/edit-map.js +81 -0
- package/dist/tools/edit-map.js.map +1 -0
- package/dist/tools/get-board.d.ts +29 -0
- package/dist/tools/get-board.d.ts.map +1 -0
- package/dist/tools/get-board.js +190 -0
- package/dist/tools/get-board.js.map +1 -0
- package/dist/tools/get-tickets.d.ts +14 -0
- package/dist/tools/get-tickets.d.ts.map +1 -0
- package/dist/tools/get-tickets.js +56 -0
- package/dist/tools/get-tickets.js.map +1 -0
- package/dist/tools/list-efforts.d.ts +16 -0
- package/dist/tools/list-efforts.d.ts.map +1 -0
- package/dist/tools/list-efforts.js +38 -0
- package/dist/tools/list-efforts.js.map +1 -0
- package/dist/tools/migrate-effort.d.ts +11 -0
- package/dist/tools/migrate-effort.d.ts.map +1 -0
- package/dist/tools/migrate-effort.js +54 -0
- package/dist/tools/migrate-effort.js.map +1 -0
- package/dist/tools/spec.d.ts +12 -0
- package/dist/tools/spec.d.ts.map +1 -0
- package/dist/tools/spec.js +27 -0
- package/dist/tools/spec.js.map +1 -0
- package/dist/tools/update-ticket.d.ts +62 -0
- package/dist/tools/update-ticket.d.ts.map +1 -0
- package/dist/tools/update-ticket.js +164 -0
- package/dist/tools/update-ticket.js.map +1 -0
- package/dist/tracker-doc.d.ts +10 -0
- package/dist/tracker-doc.d.ts.map +1 -0
- package/dist/tracker-doc.js +16 -0
- package/dist/tracker-doc.js.map +1 -0
- package/dist/workspace-index.d.ts +39 -0
- package/dist/workspace-index.d.ts.map +1 -0
- package/dist/workspace-index.js +83 -0
- package/dist/workspace-index.js.map +1 -0
- package/dist/workspace-watcher.d.ts +24 -0
- package/dist/workspace-watcher.d.ts.map +1 -0
- package/dist/workspace-watcher.js +87 -0
- package/dist/workspace-watcher.js.map +1 -0
- package/dist/workspace.d.ts +23 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +70 -0
- package/dist/workspace.js.map +1 -0
- package/docs/agents/issue-tracker.md +141 -0
- package/package.json +56 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { mkdir, rename, rmdir, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { MINTED_ID } from '../../domain.js';
|
|
4
|
+
import { resolveDraftEdges } from '../../edges.js';
|
|
5
|
+
import { serializeNew } from './serialize.js';
|
|
6
|
+
import { stage, unstage } from './write.js';
|
|
7
|
+
/**
|
|
8
|
+
* How many times the batch will re-scan and start over when a parallel session
|
|
9
|
+
* lands an id between our scan and our guard. Each retry needs a real collision,
|
|
10
|
+
* so more than a couple means something other than contention.
|
|
11
|
+
*/
|
|
12
|
+
const MAX_ATTEMPTS = 8;
|
|
13
|
+
/**
|
|
14
|
+
* A ceiling on how far a single batch will walk looking for free ids. Reached
|
|
15
|
+
* only when a workspace has collected a guard per candidate from crashed
|
|
16
|
+
* sessions, which is a broken state rather than a busy one.
|
|
17
|
+
*/
|
|
18
|
+
const CANDIDATE_HEADROOM = 1000;
|
|
19
|
+
/**
|
|
20
|
+
* Create every Ticket in the batch, or none, and return the filenames written in
|
|
21
|
+
* the order asked for.
|
|
22
|
+
*
|
|
23
|
+
* Ids are `max + 1` over the whole workspace — derived, so there is no counter
|
|
24
|
+
* file to drift — and made safe against a parallel session by an exclusive
|
|
25
|
+
* create: `open(..., 'wx')` on a guard named for the candidate id, bumping to the
|
|
26
|
+
* next candidate on collision. The filesystem provides the mutual exclusion.
|
|
27
|
+
*
|
|
28
|
+
* The guard alone is not compare-and-set. A session that scanned before ours and
|
|
29
|
+
* finished writing after would hand us an id it has already used, so the batch
|
|
30
|
+
* re-scans *while holding every guard* and starts over if any candidate has
|
|
31
|
+
* turned up on disk. That is what makes the invariant hold: a file carrying id X
|
|
32
|
+
* is only ever written while X's guard is held, and the guard is only kept when a
|
|
33
|
+
* scan taken after acquiring it shows X unused — so two sessions can never both
|
|
34
|
+
* write X. See ADR 0005.
|
|
35
|
+
*/
|
|
36
|
+
export async function createTicketFiles(request) {
|
|
37
|
+
const { scratch, effort, dir, issues, drafts, rescan, validate, createEffort } = request;
|
|
38
|
+
const { reservations, tickets } = await reserve(scratch, drafts.length, rescan);
|
|
39
|
+
try {
|
|
40
|
+
const ids = reservations.map(entry => entry.id);
|
|
41
|
+
// The last rule that can only be checked now: the ids are real, and nothing
|
|
42
|
+
// has been written or even created, so a refusal leaves no trace at all.
|
|
43
|
+
validate(ids, tickets);
|
|
44
|
+
const files = filesFor(effort, drafts, ids, tickets);
|
|
45
|
+
// After validation, so a refused batch never leaves an empty Effort behind —
|
|
46
|
+
// a bare issues/ directory is enough to make one show up in list_efforts.
|
|
47
|
+
await mkdir(issues, { recursive: true });
|
|
48
|
+
try {
|
|
49
|
+
await writeAll(issues, files);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (createEffort)
|
|
53
|
+
await discardEffort(dir, issues);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
return files.map(file => file.filename);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
// Released only once every file is on disk. A guard held across the write is
|
|
60
|
+
// the whole guarantee; releasing early would reopen the window it closes.
|
|
61
|
+
await release(reservations);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Hold exclusive id guards for `count` fresh ids, run `use`, then release.
|
|
66
|
+
* Migration mints through this so a parallel create_tickets cannot collide.
|
|
67
|
+
*/
|
|
68
|
+
export async function withIdReservations(scratch, count, rescan, use) {
|
|
69
|
+
if (count === 0)
|
|
70
|
+
return use([]);
|
|
71
|
+
const { reservations } = await reserve(scratch, count, rescan);
|
|
72
|
+
try {
|
|
73
|
+
return await use(reservations.map(entry => entry.id));
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await release(reservations);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The next `count` minted ids from a scan, without taking guards. Preview uses
|
|
81
|
+
* this so a dry run never leaves `.frontier-id-*.guard` files behind.
|
|
82
|
+
*/
|
|
83
|
+
export function peekMintedIds(used, count) {
|
|
84
|
+
const ids = [];
|
|
85
|
+
let candidate = highestMinted(used) + 1;
|
|
86
|
+
while (ids.length < count) {
|
|
87
|
+
const id = `T${String(candidate)}`;
|
|
88
|
+
if (!used.has(id))
|
|
89
|
+
ids.push(id);
|
|
90
|
+
candidate += 1;
|
|
91
|
+
}
|
|
92
|
+
return ids;
|
|
93
|
+
}
|
|
94
|
+
/** The cosmetic filename convention: `<NN>-T<n>-<slug>.md`. */
|
|
95
|
+
export function ticketFilename(order, id, title) {
|
|
96
|
+
return `${pad(order)}-${id}-${slugify(title)}.md`;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Remove an Effort this call made and then failed to fill. `rmdir` rather than a
|
|
100
|
+
* recursive delete: it fails with ENOTEMPTY on a directory holding anything,
|
|
101
|
+
* which is exactly right if a concurrent session has already put something
|
|
102
|
+
* there. Never a recursive `rm` — this runs on a failure path, where being wrong
|
|
103
|
+
* about which directory it is would destroy somebody's work.
|
|
104
|
+
*/
|
|
105
|
+
async function discardEffort(dir, issues) {
|
|
106
|
+
await rmdir(issues).catch(() => { });
|
|
107
|
+
await rmdir(dir).catch(() => { });
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Turn the drafts into files. Temporary keys resolve here, against the ids the
|
|
111
|
+
* batch just reserved — the same resolution the cycle check validated, so the
|
|
112
|
+
* graph that was approved is the graph that gets written.
|
|
113
|
+
*/
|
|
114
|
+
function filesFor(effort, drafts, ids, tickets) {
|
|
115
|
+
const resolve = resolveDraftEdges(drafts, ids);
|
|
116
|
+
const firstOrder = nextOrder(tickets, effort);
|
|
117
|
+
return drafts.map((draft, index) => {
|
|
118
|
+
const id = ids[index];
|
|
119
|
+
if (id === undefined)
|
|
120
|
+
throw new Error('Reserved fewer ids than there are Tickets to create.');
|
|
121
|
+
const contents = serializeNew({
|
|
122
|
+
id,
|
|
123
|
+
title: draft.title,
|
|
124
|
+
kind: draft.kind,
|
|
125
|
+
type: draft.type,
|
|
126
|
+
status: 'open',
|
|
127
|
+
triage: draft.triage,
|
|
128
|
+
blockedBy: draft.blockedBy.map(resolve),
|
|
129
|
+
}, draft.body);
|
|
130
|
+
return { filename: ticketFilename(firstOrder + index, id, draft.title), contents };
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Stage every file beside its target, then rename them all into place. Both
|
|
135
|
+
* phases settle in full before the next begins, because a `Promise.all` that
|
|
136
|
+
* rejects on the first failure leaves its siblings running — and a rename
|
|
137
|
+
* landing after the cleanup ran is the orphan this is trying to prevent.
|
|
138
|
+
*
|
|
139
|
+
* Splitting the phases is what makes "all or none" true of the batch rather than
|
|
140
|
+
* only of each file. Everything that can fail — a full disk, a bad path — fails
|
|
141
|
+
* in the staging phase, where nothing is visible yet. By the time the renames
|
|
142
|
+
* start, every file exists in the directory it is going into, and a rename
|
|
143
|
+
* within one directory is atomic and essentially cannot fail.
|
|
144
|
+
*/
|
|
145
|
+
async function writeAll(issues, files) {
|
|
146
|
+
const staged = await Promise.allSettled(files.map(async (file) => ({
|
|
147
|
+
temporary: await stage(join(issues, file.filename), file.contents),
|
|
148
|
+
target: join(issues, file.filename),
|
|
149
|
+
})));
|
|
150
|
+
const ready = staged.filter(entry => entry.status === 'fulfilled').map(entry => entry.value);
|
|
151
|
+
const failed = staged.find(entry => entry.status === 'rejected');
|
|
152
|
+
if (failed !== undefined) {
|
|
153
|
+
await Promise.allSettled(ready.map(entry => unstage(entry.temporary)));
|
|
154
|
+
throw failed.reason;
|
|
155
|
+
}
|
|
156
|
+
const renamed = await Promise.allSettled(ready.map(async (entry) => {
|
|
157
|
+
// Two batches racing on one Effort can pick the same sort order, which is
|
|
158
|
+
// cosmetic — the id beside it still differs, so the names cannot actually
|
|
159
|
+
// collide. This is the assertion of that rather than a case with a path to
|
|
160
|
+
// it: a target that exists would be a Ticket this write was about to
|
|
161
|
+
// destroy.
|
|
162
|
+
await rename(entry.temporary, entry.target);
|
|
163
|
+
return entry.target;
|
|
164
|
+
}));
|
|
165
|
+
const landed = renamed.filter(entry => entry.status === 'fulfilled').map(entry => entry.value);
|
|
166
|
+
const lost = renamed.find(entry => entry.status === 'rejected');
|
|
167
|
+
if (lost !== undefined) {
|
|
168
|
+
await Promise.allSettled([
|
|
169
|
+
...landed.map(path => unlink(path).catch(() => { })),
|
|
170
|
+
...ready.map(entry => unstage(entry.temporary)),
|
|
171
|
+
]);
|
|
172
|
+
throw lost.reason;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function reserve(scratch, count, rescan, attempt = 1) {
|
|
176
|
+
const used = idsOf(await rescan());
|
|
177
|
+
const reservations = await claim(scratch, used, count, highestMinted(used) + 1, []);
|
|
178
|
+
let settled;
|
|
179
|
+
try {
|
|
180
|
+
settled = await rescan();
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
await release(reservations);
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
const taken = idsOf(settled);
|
|
187
|
+
const redundant = reservations.filter(entry => taken.has(entry.id));
|
|
188
|
+
if (redundant.length === 0)
|
|
189
|
+
return { reservations, tickets: settled };
|
|
190
|
+
await release(reservations);
|
|
191
|
+
if (attempt >= MAX_ATTEMPTS) {
|
|
192
|
+
throw new Error(`Could not reserve ${String(count)} Ticket ids after ${String(MAX_ATTEMPTS)} attempts — ` +
|
|
193
|
+
'another session is creating Tickets continuously. Retry in a moment.');
|
|
194
|
+
}
|
|
195
|
+
return reserve(scratch, count, rescan, attempt + 1);
|
|
196
|
+
}
|
|
197
|
+
function release(reservations) {
|
|
198
|
+
return Promise.allSettled(reservations.map(entry => unlink(entry.guard).catch(() => { })));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Walk candidates, taking a guard on each. Recursive rather than a loop because
|
|
202
|
+
* each attempt depends on the one before it, and a bumped candidate is the
|
|
203
|
+
* normal case rather than an error.
|
|
204
|
+
*/
|
|
205
|
+
async function claim(scratch, used, count, candidate, taken) {
|
|
206
|
+
if (taken.length === count)
|
|
207
|
+
return taken;
|
|
208
|
+
if (candidate > highestMinted(used) + CANDIDATE_HEADROOM + count) {
|
|
209
|
+
await release(taken);
|
|
210
|
+
throw new Error(`No free Ticket id within ${String(CANDIDATE_HEADROOM)} of the highest in use. ` +
|
|
211
|
+
'Sweep the abandoned .frontier-id-*.guard files under .scratch/.');
|
|
212
|
+
}
|
|
213
|
+
const id = `T${String(candidate)}`;
|
|
214
|
+
if (used.has(id))
|
|
215
|
+
return claim(scratch, used, count, candidate + 1, taken);
|
|
216
|
+
const guard = guardFor(scratch, id);
|
|
217
|
+
// A guard we cannot take belongs to a session that is still allocating. Bump
|
|
218
|
+
// rather than wait: an id may be skipped, never reused.
|
|
219
|
+
if (!(await hold(guard)))
|
|
220
|
+
return claim(scratch, used, count, candidate + 1, taken);
|
|
221
|
+
return claim(scratch, used, count, candidate + 1, [...taken, { id, guard }]);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Take a guard, or report that somebody else has it.
|
|
225
|
+
*
|
|
226
|
+
* A guard is **never** broken, only bumped past, and that is the whole of the
|
|
227
|
+
* concurrency story here. Every scheme for reclaiming one — an age threshold, a
|
|
228
|
+
* liveness check on the pid inside it — has the same shape: read the guard,
|
|
229
|
+
* decide it is abandoned, then remove it. The decision goes stale between those
|
|
230
|
+
* two steps, and a session that removes a guard another session has just taken
|
|
231
|
+
* hands both of them the same id. That is the exact defect this file exists to
|
|
232
|
+
* prevent, so it is not reintroduced to tidy up after crashes.
|
|
233
|
+
*
|
|
234
|
+
* The cost is a guard left by a crashed session, which makes one id number
|
|
235
|
+
* unusable. Ids are promised never to be *reused*, never to run without gaps, so
|
|
236
|
+
* a skipped number costs nothing; the file is hidden, one line, and names the
|
|
237
|
+
* process that left it. {@link CANDIDATE_HEADROOM} bounds how many can pile up
|
|
238
|
+
* before allocation says so and points at them.
|
|
239
|
+
*/
|
|
240
|
+
async function hold(guard) {
|
|
241
|
+
try {
|
|
242
|
+
await writeFile(guard, `${String(process.pid)}\n`, { flag: 'wx' });
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
if (error?.code !== 'EEXIST')
|
|
247
|
+
throw error;
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Beside the Efforts rather than inside one, because the counter is repo-global:
|
|
253
|
+
* two sessions creating into different Efforts must still collide here. Hidden
|
|
254
|
+
* and not `.md`, so no scan mistakes it for a Ticket, and `.scratch/` yields it
|
|
255
|
+
* no Effort because it is not a directory.
|
|
256
|
+
*/
|
|
257
|
+
function guardFor(scratch, id) {
|
|
258
|
+
return join(scratch, `.frontier-id-${id}.guard`);
|
|
259
|
+
}
|
|
260
|
+
function idsOf(tickets) {
|
|
261
|
+
return new Set(tickets.map(entry => entry.id).filter(id => id !== undefined));
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* The counter, derived. Ids preserved verbatim through migration need not look
|
|
265
|
+
* like `T<n>` at all; those still occupy their name but contribute no number.
|
|
266
|
+
*/
|
|
267
|
+
function highestMinted(used) {
|
|
268
|
+
let highest = 0;
|
|
269
|
+
for (const id of used) {
|
|
270
|
+
const digits = MINTED_ID.exec(id)?.[1];
|
|
271
|
+
if (digits !== undefined)
|
|
272
|
+
highest = Math.max(highest, Number(digits));
|
|
273
|
+
}
|
|
274
|
+
return highest;
|
|
275
|
+
}
|
|
276
|
+
/** `NN` is sort order within the Effort and nothing else, so it simply continues. */
|
|
277
|
+
function nextOrder(tickets, effort) {
|
|
278
|
+
const orders = tickets.filter(entry => entry.effort === effort).map(entry => entry.order);
|
|
279
|
+
return orders.length === 0 ? 1 : Math.max(...orders) + 1;
|
|
280
|
+
}
|
|
281
|
+
function pad(order) {
|
|
282
|
+
return String(order).padStart(2, '0');
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* The cosmetic half of a filename. It exists so a directory listing reads, and
|
|
286
|
+
* carries no identity — the id beside it does, and the frontmatter is the
|
|
287
|
+
* authority over both.
|
|
288
|
+
*/
|
|
289
|
+
function slugify(title) {
|
|
290
|
+
const slug = title
|
|
291
|
+
.toLowerCase()
|
|
292
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
293
|
+
.replace(/^-+|-+$/g, '')
|
|
294
|
+
.slice(0, 48)
|
|
295
|
+
.replace(/-+$/, '');
|
|
296
|
+
return slug === '' ? 'ticket' : slug;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/storage/markdown/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StorageDriver } from '../driver.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The markdown driver — the only driver in v1. Bound to `root`, the resolved
|
|
4
|
+
* workspace, so that no path crosses the {@link StorageDriver} interface.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createMarkdownDriver(root: string): StorageDriver;
|
|
7
|
+
//# sourceMappingURL=driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../../src/storage/markdown/driver.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,cAAc,CAAC;AAsCtB;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAsFhE"}
|