@trail-pm/cli 0.1.6 → 0.2.2
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 +6 -13
- package/dist/{chunk-TDIYLUKH.js → chunk-YSTYANXJ.js} +220 -42
- package/dist/chunk-YSTYANXJ.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/lib.d.ts +378 -0
- package/dist/lib.js +669 -0
- package/dist/lib.js.map +1 -0
- package/dist/{run-mcp-server-HD7I5M7Z.js → run-mcp-server-NKYRI73A.js} +2 -2
- package/package.json +11 -1
- package/dist/chunk-TDIYLUKH.js.map +0 -1
- /package/dist/{run-mcp-server-HD7I5M7Z.js.map → run-mcp-server-NKYRI73A.js.map} +0 -0
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Walks upward from `startDir` looking for a Trail project root: a directory
|
|
5
|
+
* that contains `.trail/config.json`.
|
|
6
|
+
*
|
|
7
|
+
* @returns The **project root** directory (the parent of the `.trail` folder),
|
|
8
|
+
* or `null` if none is found within the walk limit. This is not the path to
|
|
9
|
+
* `.trail` itself — use {@link trailPaths} for `.trail`-relative paths.
|
|
10
|
+
*/
|
|
11
|
+
declare function findTrailRoot(startDir: string): string | null;
|
|
12
|
+
interface TrailPaths {
|
|
13
|
+
root: string;
|
|
14
|
+
trailDir: string;
|
|
15
|
+
tasksDir: string;
|
|
16
|
+
configPath: string;
|
|
17
|
+
snapshotPath: string;
|
|
18
|
+
gitignorePath: string;
|
|
19
|
+
}
|
|
20
|
+
/** Resolved paths under a Trail project root (the directory that contains `.trail`). */
|
|
21
|
+
declare function trailPaths(root: string): TrailPaths;
|
|
22
|
+
|
|
23
|
+
type TrailError = {
|
|
24
|
+
code: "AUTH_REQUIRED";
|
|
25
|
+
message: string;
|
|
26
|
+
hint?: string;
|
|
27
|
+
} | {
|
|
28
|
+
code: "AUTH_FAILED";
|
|
29
|
+
message: string;
|
|
30
|
+
} | {
|
|
31
|
+
code: "NOT_A_TRAIL_REPO";
|
|
32
|
+
message: string;
|
|
33
|
+
path?: string;
|
|
34
|
+
} | {
|
|
35
|
+
code: "VALIDATION_FAILED";
|
|
36
|
+
message: string;
|
|
37
|
+
details?: string;
|
|
38
|
+
issues?: string[];
|
|
39
|
+
} | {
|
|
40
|
+
code: "GITHUB_API";
|
|
41
|
+
message: string;
|
|
42
|
+
status?: number;
|
|
43
|
+
body?: string;
|
|
44
|
+
} | {
|
|
45
|
+
code: "SYNC_CONFLICT";
|
|
46
|
+
message: string;
|
|
47
|
+
paths?: string[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
declare const TaskSchema: z.ZodObject<{
|
|
51
|
+
id: z.ZodString;
|
|
52
|
+
title: z.ZodString;
|
|
53
|
+
description: z.ZodOptional<z.ZodString>;
|
|
54
|
+
status: z.ZodEnum<["draft", "todo", "in_progress", "in_review", "done", "cancelled"]>;
|
|
55
|
+
priority: z.ZodOptional<z.ZodEnum<["p0", "p1", "p2", "p3"]>>;
|
|
56
|
+
type: z.ZodEnum<["feature", "bug", "chore", "epic"]>;
|
|
57
|
+
assignee: z.ZodOptional<z.ZodString>;
|
|
58
|
+
milestone: z.ZodOptional<z.ZodString>;
|
|
59
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
60
|
+
labels: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
61
|
+
parent: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
62
|
+
depends_on: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
63
|
+
blocks: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
64
|
+
due_date: z.ZodOptional<z.ZodString>;
|
|
65
|
+
start_date: z.ZodOptional<z.ZodString>;
|
|
66
|
+
estimate: z.ZodOptional<z.ZodEnum<["xs", "sm", "md", "lg", "xl"]>>;
|
|
67
|
+
github: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
68
|
+
issue_number: z.ZodNumber;
|
|
69
|
+
synced_at: z.ZodString;
|
|
70
|
+
url: z.ZodString;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
issue_number: number;
|
|
73
|
+
synced_at: string;
|
|
74
|
+
url: string;
|
|
75
|
+
}, {
|
|
76
|
+
issue_number: number;
|
|
77
|
+
synced_at: string;
|
|
78
|
+
url: string;
|
|
79
|
+
}>>>;
|
|
80
|
+
refs: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
81
|
+
type: z.ZodString;
|
|
82
|
+
path: z.ZodString;
|
|
83
|
+
}, "strict", z.ZodTypeAny, {
|
|
84
|
+
path: string;
|
|
85
|
+
type: string;
|
|
86
|
+
}, {
|
|
87
|
+
path: string;
|
|
88
|
+
type: string;
|
|
89
|
+
}>, "many">>;
|
|
90
|
+
ai: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
92
|
+
acceptance_criteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
93
|
+
implementation_context: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
94
|
+
test_strategy: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
95
|
+
constraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
96
|
+
}, "strict", z.ZodTypeAny, {
|
|
97
|
+
summary?: string | undefined;
|
|
98
|
+
acceptance_criteria?: string[] | undefined;
|
|
99
|
+
implementation_context?: string[] | undefined;
|
|
100
|
+
test_strategy?: string[] | undefined;
|
|
101
|
+
constraints?: string[] | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
summary?: string | undefined;
|
|
104
|
+
acceptance_criteria?: string[] | undefined;
|
|
105
|
+
implementation_context?: string[] | undefined;
|
|
106
|
+
test_strategy?: string[] | undefined;
|
|
107
|
+
constraints?: string[] | undefined;
|
|
108
|
+
}>>;
|
|
109
|
+
created_at: z.ZodString;
|
|
110
|
+
updated_at: z.ZodString;
|
|
111
|
+
}, "strict", z.ZodTypeAny, {
|
|
112
|
+
status: "draft" | "todo" | "in_progress" | "in_review" | "done" | "cancelled";
|
|
113
|
+
type: "feature" | "bug" | "chore" | "epic";
|
|
114
|
+
id: string;
|
|
115
|
+
title: string;
|
|
116
|
+
labels: string[];
|
|
117
|
+
depends_on: string[];
|
|
118
|
+
blocks: string[];
|
|
119
|
+
refs: {
|
|
120
|
+
path: string;
|
|
121
|
+
type: string;
|
|
122
|
+
}[];
|
|
123
|
+
created_at: string;
|
|
124
|
+
updated_at: string;
|
|
125
|
+
description?: string | undefined;
|
|
126
|
+
priority?: "p0" | "p1" | "p2" | "p3" | undefined;
|
|
127
|
+
assignee?: string | undefined;
|
|
128
|
+
milestone?: string | undefined;
|
|
129
|
+
branch?: string | undefined;
|
|
130
|
+
parent?: string | null | undefined;
|
|
131
|
+
due_date?: string | undefined;
|
|
132
|
+
start_date?: string | undefined;
|
|
133
|
+
estimate?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
|
|
134
|
+
github?: {
|
|
135
|
+
issue_number: number;
|
|
136
|
+
synced_at: string;
|
|
137
|
+
url: string;
|
|
138
|
+
} | null | undefined;
|
|
139
|
+
ai?: {
|
|
140
|
+
summary?: string | undefined;
|
|
141
|
+
acceptance_criteria?: string[] | undefined;
|
|
142
|
+
implementation_context?: string[] | undefined;
|
|
143
|
+
test_strategy?: string[] | undefined;
|
|
144
|
+
constraints?: string[] | undefined;
|
|
145
|
+
} | undefined;
|
|
146
|
+
}, {
|
|
147
|
+
status: "draft" | "todo" | "in_progress" | "in_review" | "done" | "cancelled";
|
|
148
|
+
type: "feature" | "bug" | "chore" | "epic";
|
|
149
|
+
id: string;
|
|
150
|
+
title: string;
|
|
151
|
+
created_at: string;
|
|
152
|
+
updated_at: string;
|
|
153
|
+
description?: string | undefined;
|
|
154
|
+
priority?: "p0" | "p1" | "p2" | "p3" | undefined;
|
|
155
|
+
assignee?: string | undefined;
|
|
156
|
+
milestone?: string | undefined;
|
|
157
|
+
branch?: string | undefined;
|
|
158
|
+
labels?: string[] | undefined;
|
|
159
|
+
parent?: string | null | undefined;
|
|
160
|
+
depends_on?: string[] | undefined;
|
|
161
|
+
blocks?: string[] | undefined;
|
|
162
|
+
due_date?: string | undefined;
|
|
163
|
+
start_date?: string | undefined;
|
|
164
|
+
estimate?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
|
|
165
|
+
github?: {
|
|
166
|
+
issue_number: number;
|
|
167
|
+
synced_at: string;
|
|
168
|
+
url: string;
|
|
169
|
+
} | null | undefined;
|
|
170
|
+
refs?: {
|
|
171
|
+
path: string;
|
|
172
|
+
type: string;
|
|
173
|
+
}[] | undefined;
|
|
174
|
+
ai?: {
|
|
175
|
+
summary?: string | undefined;
|
|
176
|
+
acceptance_criteria?: string[] | undefined;
|
|
177
|
+
implementation_context?: string[] | undefined;
|
|
178
|
+
test_strategy?: string[] | undefined;
|
|
179
|
+
constraints?: string[] | undefined;
|
|
180
|
+
} | undefined;
|
|
181
|
+
}>;
|
|
182
|
+
type Task = z.infer<typeof TaskSchema>;
|
|
183
|
+
|
|
184
|
+
declare function writeTaskFile(filePath: string, task: Task): void;
|
|
185
|
+
/**
|
|
186
|
+
* Loads all task JSON files from `tasksDir`. Returns an empty array if the directory is missing.
|
|
187
|
+
* Stops on the first file that fails to parse or validate.
|
|
188
|
+
*/
|
|
189
|
+
declare function loadAllTasks(tasksDir: string): Task[];
|
|
190
|
+
/**
|
|
191
|
+
* Resolves the task file for `id`: prefers `${id}.json` when it exists and its `id` matches;
|
|
192
|
+
* otherwise scans `*.json` for a task whose `id` field equals `id`.
|
|
193
|
+
*/
|
|
194
|
+
declare function findTaskFileById(tasksDir: string, id: string): {
|
|
195
|
+
filePath: string;
|
|
196
|
+
task: Task;
|
|
197
|
+
} | null;
|
|
198
|
+
|
|
199
|
+
/** Recompiles `.trail/snapshot.json` from all task files. */
|
|
200
|
+
declare function rebuildSnapshot(paths: TrailPaths, now?: Date): void;
|
|
201
|
+
|
|
202
|
+
/** Stable draft task id prefix + random suffix (e.g. `draft-a1b2c3d4`). */
|
|
203
|
+
declare function generateDraftId(): string;
|
|
204
|
+
|
|
205
|
+
declare const TrailConfigSchema: z.ZodObject<{
|
|
206
|
+
github: z.ZodObject<{
|
|
207
|
+
owner: z.ZodString;
|
|
208
|
+
repo: z.ZodString;
|
|
209
|
+
}, "strict", z.ZodTypeAny, {
|
|
210
|
+
owner: string;
|
|
211
|
+
repo: string;
|
|
212
|
+
}, {
|
|
213
|
+
owner: string;
|
|
214
|
+
repo: string;
|
|
215
|
+
}>;
|
|
216
|
+
sync: z.ZodObject<{
|
|
217
|
+
preset: z.ZodEnum<["collaborative", "solo", "offline"]>;
|
|
218
|
+
auto_sync_on_command: z.ZodBoolean;
|
|
219
|
+
ui_poll_interval_seconds: z.ZodNumber;
|
|
220
|
+
ui_idle_backoff: z.ZodBoolean;
|
|
221
|
+
}, "strict", z.ZodTypeAny, {
|
|
222
|
+
preset: "collaborative" | "solo" | "offline";
|
|
223
|
+
auto_sync_on_command: boolean;
|
|
224
|
+
ui_poll_interval_seconds: number;
|
|
225
|
+
ui_idle_backoff: boolean;
|
|
226
|
+
}, {
|
|
227
|
+
preset: "collaborative" | "solo" | "offline";
|
|
228
|
+
auto_sync_on_command: boolean;
|
|
229
|
+
ui_poll_interval_seconds: number;
|
|
230
|
+
ui_idle_backoff: boolean;
|
|
231
|
+
}>;
|
|
232
|
+
/** Last successful full sync; useful for future `trail status` and similar. */
|
|
233
|
+
last_full_sync_at: z.ZodOptional<z.ZodString>;
|
|
234
|
+
}, "strict", z.ZodTypeAny, {
|
|
235
|
+
github: {
|
|
236
|
+
owner: string;
|
|
237
|
+
repo: string;
|
|
238
|
+
};
|
|
239
|
+
sync: {
|
|
240
|
+
preset: "collaborative" | "solo" | "offline";
|
|
241
|
+
auto_sync_on_command: boolean;
|
|
242
|
+
ui_poll_interval_seconds: number;
|
|
243
|
+
ui_idle_backoff: boolean;
|
|
244
|
+
};
|
|
245
|
+
last_full_sync_at?: string | undefined;
|
|
246
|
+
}, {
|
|
247
|
+
github: {
|
|
248
|
+
owner: string;
|
|
249
|
+
repo: string;
|
|
250
|
+
};
|
|
251
|
+
sync: {
|
|
252
|
+
preset: "collaborative" | "solo" | "offline";
|
|
253
|
+
auto_sync_on_command: boolean;
|
|
254
|
+
ui_poll_interval_seconds: number;
|
|
255
|
+
ui_idle_backoff: boolean;
|
|
256
|
+
};
|
|
257
|
+
last_full_sync_at?: string | undefined;
|
|
258
|
+
}>;
|
|
259
|
+
type TrailConfig = z.infer<typeof TrailConfigSchema>;
|
|
260
|
+
|
|
261
|
+
type ResolveTokenResult = {
|
|
262
|
+
ok: true;
|
|
263
|
+
token: string;
|
|
264
|
+
} | {
|
|
265
|
+
ok: false;
|
|
266
|
+
error: TrailError;
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Resolves a GitHub API token from `GITHUB_TOKEN` (trimmed) or `gh auth token`.
|
|
270
|
+
*/
|
|
271
|
+
declare function resolveGitHubToken(env?: NodeJS.ProcessEnv): ResolveTokenResult;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Minimal fields from GitHub REST issue JSON (list and single resource).
|
|
275
|
+
*/
|
|
276
|
+
interface GitHubIssue {
|
|
277
|
+
number: number;
|
|
278
|
+
title: string;
|
|
279
|
+
body: string | null;
|
|
280
|
+
state: string;
|
|
281
|
+
labels: {
|
|
282
|
+
name: string;
|
|
283
|
+
}[];
|
|
284
|
+
assignee: {
|
|
285
|
+
login: string;
|
|
286
|
+
} | null;
|
|
287
|
+
milestone: {
|
|
288
|
+
title: string;
|
|
289
|
+
} | null;
|
|
290
|
+
html_url: string;
|
|
291
|
+
updated_at: string;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
declare class GitHubClient {
|
|
295
|
+
private readonly token;
|
|
296
|
+
private readonly baseUrl;
|
|
297
|
+
constructor(token: string, baseUrl?: string);
|
|
298
|
+
private request;
|
|
299
|
+
private parseJson;
|
|
300
|
+
listIssues(owner: string, repo: string, params: {
|
|
301
|
+
state: "open" | "all" | "closed";
|
|
302
|
+
per_page: number;
|
|
303
|
+
page: number;
|
|
304
|
+
}): Promise<GitHubIssue[]>;
|
|
305
|
+
getIssue(owner: string, repo: string, issueNumber: number): Promise<GitHubIssue>;
|
|
306
|
+
updateIssue(owner: string, repo: string, issueNumber: number, patch: Record<string, unknown>): Promise<GitHubIssue>;
|
|
307
|
+
createIssueComment(owner: string, repo: string, issueNumber: number, body: string): Promise<{
|
|
308
|
+
id: number;
|
|
309
|
+
}>;
|
|
310
|
+
/** Create a new issue. Returns the created issue (same shape as list/get). */
|
|
311
|
+
createIssue(owner: string, repo: string, input: {
|
|
312
|
+
title: string;
|
|
313
|
+
body?: string;
|
|
314
|
+
labels?: string[];
|
|
315
|
+
}): Promise<GitHubIssue>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Maps a GitHub issue to a Trail task. GitHub wins for title, body, labels, assignee, milestone;
|
|
320
|
+
* local-only fields are preserved from `existing` when present.
|
|
321
|
+
*/
|
|
322
|
+
declare function issueToTask(issue: GitHubIssue, existing: Task | null, now: Date): Task;
|
|
323
|
+
/**
|
|
324
|
+
* Maps a Trail task to fields for `GitHubClient.updateIssue`.
|
|
325
|
+
*/
|
|
326
|
+
declare function taskToIssueUpdate(task: Task): {
|
|
327
|
+
title?: string;
|
|
328
|
+
body?: string;
|
|
329
|
+
state?: "open" | "closed";
|
|
330
|
+
labels?: string[];
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
type SyncProgress = {
|
|
334
|
+
phase: "pull";
|
|
335
|
+
page: number;
|
|
336
|
+
issuesInPage: number;
|
|
337
|
+
issuesSoFar: number;
|
|
338
|
+
} | {
|
|
339
|
+
phase: "push";
|
|
340
|
+
index: number;
|
|
341
|
+
total: number;
|
|
342
|
+
taskId: string;
|
|
343
|
+
};
|
|
344
|
+
declare function pullSync(options: {
|
|
345
|
+
client: GitHubClient;
|
|
346
|
+
owner: string;
|
|
347
|
+
repo: string;
|
|
348
|
+
tasksDir: string;
|
|
349
|
+
now?: Date;
|
|
350
|
+
onProgress?: (p: SyncProgress) => void;
|
|
351
|
+
}): Promise<void>;
|
|
352
|
+
declare function fullSync(options: {
|
|
353
|
+
client: GitHubClient;
|
|
354
|
+
owner: string;
|
|
355
|
+
repo: string;
|
|
356
|
+
tasksDir: string;
|
|
357
|
+
snapshotPath: string;
|
|
358
|
+
now?: Date;
|
|
359
|
+
onProgress?: (p: SyncProgress) => void;
|
|
360
|
+
}): Promise<void>;
|
|
361
|
+
|
|
362
|
+
declare function writeLastFullSyncAt(paths: TrailPaths, iso: string): void;
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Creates a GitHub issue from a draft task, deletes the draft file, and writes
|
|
366
|
+
* `{issueNumber}.json`. Mirrors `trail promote` without CLI validation.
|
|
367
|
+
*/
|
|
368
|
+
declare function linkDraftToNewGitHubIssue(options: {
|
|
369
|
+
client: GitHubClient;
|
|
370
|
+
owner: string;
|
|
371
|
+
repo: string;
|
|
372
|
+
draft: Task;
|
|
373
|
+
draftFilePath: string;
|
|
374
|
+
tasksDir: string;
|
|
375
|
+
now: Date;
|
|
376
|
+
}): Promise<Task>;
|
|
377
|
+
|
|
378
|
+
export { GitHubClient, type SyncProgress, type Task, TaskSchema, type TrailConfig, TrailConfigSchema, type TrailPaths, findTaskFileById, findTrailRoot, fullSync, generateDraftId, issueToTask, linkDraftToNewGitHubIssue, loadAllTasks, pullSync, rebuildSnapshot, resolveGitHubToken, taskToIssueUpdate, trailPaths, writeLastFullSyncAt, writeTaskFile };
|