planfs-core 1.2.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 +125 -0
- package/dist/ai.d.ts +98 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +265 -0
- package/dist/ai.js.map +1 -0
- package/dist/backlog.d.ts +40 -0
- package/dist/backlog.d.ts.map +1 -0
- package/dist/backlog.js +206 -0
- package/dist/backlog.js.map +1 -0
- package/dist/bulk.d.ts +29 -0
- package/dist/bulk.d.ts.map +1 -0
- package/dist/bulk.js +206 -0
- package/dist/bulk.js.map +1 -0
- package/dist/files.d.ts +38 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +179 -0
- package/dist/files.js.map +1 -0
- package/dist/git.d.ts +74 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +426 -0
- package/dist/git.js.map +1 -0
- package/dist/graph.d.ts +56 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +188 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +26 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +248 -0
- package/dist/loader.js.map +1 -0
- package/dist/milestone.d.ts +23 -0
- package/dist/milestone.d.ts.map +1 -0
- package/dist/milestone.js +60 -0
- package/dist/milestone.js.map +1 -0
- package/dist/next-work.d.ts +34 -0
- package/dist/next-work.d.ts.map +1 -0
- package/dist/next-work.js +239 -0
- package/dist/next-work.js.map +1 -0
- package/dist/parser.d.ts +37 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +132 -0
- package/dist/parser.js.map +1 -0
- package/dist/pull-request.d.ts +38 -0
- package/dist/pull-request.d.ts.map +1 -0
- package/dist/pull-request.js +147 -0
- package/dist/pull-request.js.map +1 -0
- package/dist/references.d.ts +10 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +30 -0
- package/dist/references.js.map +1 -0
- package/dist/repository.d.ts +85 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +495 -0
- package/dist/repository.js.map +1 -0
- package/dist/search.d.ts +25 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +150 -0
- package/dist/search.js.map +1 -0
- package/dist/types.d.ts +119 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/validator.d.ts +24 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +540 -0
- package/dist/validator.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Milestone, Repository, Task } from './types';
|
|
2
|
+
export interface MilestoneRollupTask {
|
|
3
|
+
task: Task;
|
|
4
|
+
blocked: boolean;
|
|
5
|
+
overdue: boolean;
|
|
6
|
+
atRisk: boolean;
|
|
7
|
+
blockingTaskIds: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface MilestoneRollup {
|
|
10
|
+
milestone: Milestone;
|
|
11
|
+
tasks: MilestoneRollupTask[];
|
|
12
|
+
total: number;
|
|
13
|
+
open: number;
|
|
14
|
+
done: number;
|
|
15
|
+
blocked: number;
|
|
16
|
+
overdue: number;
|
|
17
|
+
atRisk: number;
|
|
18
|
+
completionPercentage?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function getMilestoneRollup(repository: Repository, milestoneId: string, options?: {
|
|
21
|
+
now?: Date;
|
|
22
|
+
}): MilestoneRollup | undefined;
|
|
23
|
+
//# sourceMappingURL=milestone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"milestone.d.ts","sourceRoot":"","sources":["../src/milestone.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAC3B,eAAe,GAAG,SAAS,CAsC7B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMilestoneRollup = getMilestoneRollup;
|
|
4
|
+
const next_work_1 = require("./next-work");
|
|
5
|
+
function getMilestoneRollup(repository, milestoneId, options = {}) {
|
|
6
|
+
const milestone = repository.milestones.get(milestoneId);
|
|
7
|
+
if (!milestone) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
const now = options.now ?? new Date();
|
|
11
|
+
const tasks = Array.from(repository.tasks.values())
|
|
12
|
+
.filter(task => task.milestone === milestoneId)
|
|
13
|
+
.sort((a, b) => a.status.localeCompare(b.status) || a.id.localeCompare(b.id))
|
|
14
|
+
.map(task => {
|
|
15
|
+
const readiness = (0, next_work_1.getTaskReadiness)(task, repository);
|
|
16
|
+
const open = task.status !== 'done';
|
|
17
|
+
const dueDate = parseDate(task.dueDate, true);
|
|
18
|
+
const blocked = open && (readiness.status === 'blocked' || readiness.status === 'missing-dependency');
|
|
19
|
+
const overdue = open && dueDate !== undefined && dueDate < now.getTime();
|
|
20
|
+
const atRisk = open && (blocked || isAfter(task.dueDate, milestone.targetDate));
|
|
21
|
+
return {
|
|
22
|
+
task,
|
|
23
|
+
blocked,
|
|
24
|
+
overdue,
|
|
25
|
+
atRisk,
|
|
26
|
+
blockingTaskIds: [...readiness.blockingTaskIds, ...readiness.missingDependencyIds]
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
const done = tasks.filter(item => item.task.status === 'done').length;
|
|
30
|
+
return {
|
|
31
|
+
milestone,
|
|
32
|
+
tasks,
|
|
33
|
+
total: tasks.length,
|
|
34
|
+
open: tasks.length - done,
|
|
35
|
+
done,
|
|
36
|
+
blocked: tasks.filter(item => item.blocked).length,
|
|
37
|
+
overdue: tasks.filter(item => item.overdue).length,
|
|
38
|
+
atRisk: tasks.filter(item => item.atRisk).length,
|
|
39
|
+
completionPercentage: tasks.length > 0 ? Math.round((done / tasks.length) * 100) : undefined
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function parseDate(value, endOfDateOnly = false) {
|
|
43
|
+
if (!value)
|
|
44
|
+
return undefined;
|
|
45
|
+
const parsed = Date.parse(endOfDateOnly && /^\d{4}-\d{2}-\d{2}$/.test(value) ? `${value}T23:59:59.999` : value);
|
|
46
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
47
|
+
}
|
|
48
|
+
function isAfter(value, comparison) {
|
|
49
|
+
if (!value || !comparison)
|
|
50
|
+
return false;
|
|
51
|
+
const valueDate = value.slice(0, 10);
|
|
52
|
+
const comparisonDate = comparison.slice(0, 10);
|
|
53
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(valueDate) && /^\d{4}-\d{2}-\d{2}$/.test(comparisonDate)) {
|
|
54
|
+
return valueDate > comparisonDate;
|
|
55
|
+
}
|
|
56
|
+
const parsed = parseDate(value);
|
|
57
|
+
const parsedComparison = parseDate(comparison);
|
|
58
|
+
return parsed !== undefined && parsedComparison !== undefined && parsed > parsedComparison;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=milestone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"milestone.js","sourceRoot":"","sources":["../src/milestone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next-work readiness and ranking helpers.
|
|
3
|
+
*/
|
|
4
|
+
import { Repository, Task, TaskStatus } from './types';
|
|
5
|
+
export type TaskReadiness = 'ready' | 'blocked' | 'missing-dependency' | 'in-progress' | 'needs-review' | 'done';
|
|
6
|
+
export interface TaskReadinessResult {
|
|
7
|
+
status: TaskReadiness;
|
|
8
|
+
blockingTaskIds: string[];
|
|
9
|
+
missingDependencyIds: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface NextWorkOptions {
|
|
12
|
+
assignee?: string;
|
|
13
|
+
epic?: string;
|
|
14
|
+
milestone?: string;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
status?: TaskStatus | TaskStatus[];
|
|
17
|
+
includeBlocked?: boolean;
|
|
18
|
+
now?: Date;
|
|
19
|
+
limit?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NextWorkCandidate {
|
|
22
|
+
task: Task;
|
|
23
|
+
readiness: TaskReadinessResult;
|
|
24
|
+
reasons: string[];
|
|
25
|
+
downstreamCount: number;
|
|
26
|
+
critical: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function getTaskReadiness(task: Task, repository: Repository): TaskReadinessResult;
|
|
29
|
+
export declare function getNextWorkCandidates(repository: Repository, options?: NextWorkOptions): NextWorkCandidate[];
|
|
30
|
+
export declare function explainNextWork(task: Task, repository: Repository, context?: {
|
|
31
|
+
readiness?: TaskReadinessResult;
|
|
32
|
+
now?: Date;
|
|
33
|
+
}): string[];
|
|
34
|
+
//# sourceMappingURL=next-work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-work.d.ts","sourceRoot":"","sources":["../src/next-work.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAgB,UAAU,EAAE,MAAM,SAAS,CAAC;AAErE,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,SAAS,GACT,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,MAAM,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,aAAa,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,mBAAmB,CAAC;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAUD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,GACrB,mBAAmB,CA8BrB;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,eAAoB,GAC5B,iBAAiB,EAAE,CAiCrB;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAC5D,MAAM,EAAE,CAyCV"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Next-work readiness and ranking helpers.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getTaskReadiness = getTaskReadiness;
|
|
7
|
+
exports.getNextWorkCandidates = getNextWorkCandidates;
|
|
8
|
+
exports.explainNextWork = explainNextWork;
|
|
9
|
+
const graph_1 = require("./graph");
|
|
10
|
+
const references_1 = require("./references");
|
|
11
|
+
const OPEN_STATUSES = ['todo', 'in-progress', 'review'];
|
|
12
|
+
const PRIORITY_RANK = {
|
|
13
|
+
critical: 0,
|
|
14
|
+
high: 1,
|
|
15
|
+
medium: 2,
|
|
16
|
+
low: 3
|
|
17
|
+
};
|
|
18
|
+
function getTaskReadiness(task, repository) {
|
|
19
|
+
const dependencyIds = task.dependsOn ?? [];
|
|
20
|
+
const missingDependencyIds = dependencyIds.filter(dependencyId => !(0, references_1.isTaskReferenceSatisfied)(repository, dependencyId));
|
|
21
|
+
const blockingTaskIds = dependencyIds.filter(dependencyId => (0, references_1.isTaskDependencyBlocking)(repository, dependencyId));
|
|
22
|
+
if (task.status === 'done') {
|
|
23
|
+
return { status: 'done', blockingTaskIds: [], missingDependencyIds };
|
|
24
|
+
}
|
|
25
|
+
if (missingDependencyIds.length > 0) {
|
|
26
|
+
return { status: 'missing-dependency', blockingTaskIds, missingDependencyIds };
|
|
27
|
+
}
|
|
28
|
+
if (blockingTaskIds.length > 0) {
|
|
29
|
+
return { status: 'blocked', blockingTaskIds, missingDependencyIds };
|
|
30
|
+
}
|
|
31
|
+
if (task.status === 'review') {
|
|
32
|
+
return { status: 'needs-review', blockingTaskIds, missingDependencyIds };
|
|
33
|
+
}
|
|
34
|
+
if (task.status === 'in-progress') {
|
|
35
|
+
return { status: 'in-progress', blockingTaskIds, missingDependencyIds };
|
|
36
|
+
}
|
|
37
|
+
return { status: 'ready', blockingTaskIds, missingDependencyIds };
|
|
38
|
+
}
|
|
39
|
+
function getNextWorkCandidates(repository, options = {}) {
|
|
40
|
+
const graph = (0, graph_1.buildTaskGraph)(repository.tasks.values());
|
|
41
|
+
const statuses = toStatusSet(options.status ?? OPEN_STATUSES);
|
|
42
|
+
const now = options.now ?? new Date();
|
|
43
|
+
const candidates = Array.from(repository.tasks.values())
|
|
44
|
+
.filter(task => statuses.has(task.status))
|
|
45
|
+
.filter(task => !task.refinementState || task.refinementState === 'ready')
|
|
46
|
+
.filter(task => matchesScope(task, options))
|
|
47
|
+
.map(task => {
|
|
48
|
+
const readiness = getTaskReadiness(task, repository);
|
|
49
|
+
const graphNode = graph.nodes.get(task.id);
|
|
50
|
+
return {
|
|
51
|
+
task,
|
|
52
|
+
readiness,
|
|
53
|
+
reasons: explainNextWork(task, repository, { readiness, now }),
|
|
54
|
+
downstreamCount: graphNode?.dependents.filter(id => {
|
|
55
|
+
const dependent = repository.tasks.get(id);
|
|
56
|
+
return dependent?.status !== 'done';
|
|
57
|
+
}).length ?? 0,
|
|
58
|
+
critical: graphNode?.critical ?? false
|
|
59
|
+
};
|
|
60
|
+
})
|
|
61
|
+
.filter(candidate => options.includeBlocked
|
|
62
|
+
? candidate.readiness.status !== 'done'
|
|
63
|
+
: isActionable(candidate.readiness.status))
|
|
64
|
+
.sort((a, b) => compareCandidates(a, b, repository, options, now));
|
|
65
|
+
return typeof options.limit === 'number'
|
|
66
|
+
? candidates.slice(0, options.limit)
|
|
67
|
+
: candidates;
|
|
68
|
+
}
|
|
69
|
+
function explainNextWork(task, repository, context = {}) {
|
|
70
|
+
const readiness = context.readiness ?? getTaskReadiness(task, repository);
|
|
71
|
+
const now = context.now ?? new Date();
|
|
72
|
+
const graph = (0, graph_1.buildTaskGraph)(repository.tasks.values());
|
|
73
|
+
const node = graph.nodes.get(task.id);
|
|
74
|
+
const reasons = [readinessReason(readiness)];
|
|
75
|
+
if (task.priority) {
|
|
76
|
+
reasons.push(`${capitalize(task.priority)} task priority`);
|
|
77
|
+
}
|
|
78
|
+
const epic = task.epic ? repository.epics.get(task.epic) : undefined;
|
|
79
|
+
if (epic?.priority) {
|
|
80
|
+
reasons.push(`${capitalize(epic.priority)} epic priority`);
|
|
81
|
+
}
|
|
82
|
+
const dueReason = dateReason('Due', task.dueDate, now);
|
|
83
|
+
if (dueReason) {
|
|
84
|
+
reasons.push(dueReason);
|
|
85
|
+
}
|
|
86
|
+
const targetDate = epic?.targetDate
|
|
87
|
+
?? (task.milestone ? repository.milestones.get(task.milestone)?.targetDate : undefined);
|
|
88
|
+
const targetReason = dateReason('Target', targetDate, now);
|
|
89
|
+
if (targetReason) {
|
|
90
|
+
reasons.push(targetReason);
|
|
91
|
+
}
|
|
92
|
+
if (node?.critical) {
|
|
93
|
+
reasons.push('On critical path');
|
|
94
|
+
}
|
|
95
|
+
const downstreamCount = node?.dependents.filter(id => {
|
|
96
|
+
const dependent = repository.tasks.get(id);
|
|
97
|
+
return dependent?.status !== 'done';
|
|
98
|
+
}).length ?? 0;
|
|
99
|
+
if (downstreamCount > 0) {
|
|
100
|
+
reasons.push(`Unblocks ${downstreamCount} downstream ${downstreamCount === 1 ? 'task' : 'tasks'}`);
|
|
101
|
+
}
|
|
102
|
+
return reasons;
|
|
103
|
+
}
|
|
104
|
+
function compareCandidates(a, b, repository, options, now) {
|
|
105
|
+
return compareReadiness(a.readiness.status, b.readiness.status)
|
|
106
|
+
|| compareAssignee(a.task, b.task, options.assignee)
|
|
107
|
+
|| comparePriority(a.task.priority, b.task.priority)
|
|
108
|
+
|| compareEpicPriority(a.task, b.task, repository)
|
|
109
|
+
|| compareDates(a.task.dueDate, b.task.dueDate, now)
|
|
110
|
+
|| compareBooleans(a.critical, b.critical)
|
|
111
|
+
|| b.downstreamCount - a.downstreamCount
|
|
112
|
+
|| compareTargetDates(a.task, b.task, repository, now)
|
|
113
|
+
|| compareDates(a.task.createdAt, b.task.createdAt, now)
|
|
114
|
+
|| a.task.id.localeCompare(b.task.id);
|
|
115
|
+
}
|
|
116
|
+
function compareReadiness(a, b) {
|
|
117
|
+
const rank = {
|
|
118
|
+
ready: 0,
|
|
119
|
+
'in-progress': 1,
|
|
120
|
+
'needs-review': 2,
|
|
121
|
+
blocked: 3,
|
|
122
|
+
'missing-dependency': 4,
|
|
123
|
+
done: 5
|
|
124
|
+
};
|
|
125
|
+
return rank[a] - rank[b];
|
|
126
|
+
}
|
|
127
|
+
function compareAssignee(a, b, assignee) {
|
|
128
|
+
if (!assignee) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
return Number(b.assignee === assignee) - Number(a.assignee === assignee);
|
|
132
|
+
}
|
|
133
|
+
function comparePriority(a, b) {
|
|
134
|
+
return priorityValue(a) - priorityValue(b);
|
|
135
|
+
}
|
|
136
|
+
function compareEpicPriority(a, b, repository) {
|
|
137
|
+
return priorityValue(a.epic ? repository.epics.get(a.epic)?.priority : undefined)
|
|
138
|
+
- priorityValue(b.epic ? repository.epics.get(b.epic)?.priority : undefined);
|
|
139
|
+
}
|
|
140
|
+
function compareBooleans(a, b) {
|
|
141
|
+
return Number(b) - Number(a);
|
|
142
|
+
}
|
|
143
|
+
function compareTargetDates(a, b, repository, now) {
|
|
144
|
+
return compareDates(targetDateForTask(a, repository), targetDateForTask(b, repository), now);
|
|
145
|
+
}
|
|
146
|
+
function compareDates(a, b, now) {
|
|
147
|
+
const aTime = dateRank(a, now);
|
|
148
|
+
const bTime = dateRank(b, now);
|
|
149
|
+
return aTime - bTime;
|
|
150
|
+
}
|
|
151
|
+
function dateRank(value, now) {
|
|
152
|
+
const time = parseDate(value);
|
|
153
|
+
if (time === undefined) {
|
|
154
|
+
return Number.POSITIVE_INFINITY;
|
|
155
|
+
}
|
|
156
|
+
return time - startOfDay(now).getTime();
|
|
157
|
+
}
|
|
158
|
+
function priorityValue(priority) {
|
|
159
|
+
return priority ? PRIORITY_RANK[priority] : 99;
|
|
160
|
+
}
|
|
161
|
+
function targetDateForTask(task, repository) {
|
|
162
|
+
const epicTargetDate = task.epic
|
|
163
|
+
? repository.epics.get(task.epic)?.targetDate
|
|
164
|
+
: undefined;
|
|
165
|
+
return epicTargetDate
|
|
166
|
+
?? (task.milestone ? repository.milestones.get(task.milestone)?.targetDate : undefined);
|
|
167
|
+
}
|
|
168
|
+
function matchesScope(task, options) {
|
|
169
|
+
if (options.assignee && task.assignee !== options.assignee) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (options.epic && task.epic !== options.epic) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (options.milestone && task.milestone !== options.milestone) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
if (options.tags?.length) {
|
|
179
|
+
const tags = new Set(task.tags ?? []);
|
|
180
|
+
if (!options.tags.every(tag => tags.has(tag))) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
function isActionable(status) {
|
|
187
|
+
return status === 'ready' || status === 'in-progress' || status === 'needs-review';
|
|
188
|
+
}
|
|
189
|
+
function toStatusSet(status) {
|
|
190
|
+
return new Set(Array.isArray(status) ? status : [status]);
|
|
191
|
+
}
|
|
192
|
+
function readinessReason(readiness) {
|
|
193
|
+
switch (readiness.status) {
|
|
194
|
+
case 'ready':
|
|
195
|
+
return 'Ready: dependencies complete';
|
|
196
|
+
case 'in-progress':
|
|
197
|
+
return 'Already in progress';
|
|
198
|
+
case 'needs-review':
|
|
199
|
+
return 'Needs review';
|
|
200
|
+
case 'blocked':
|
|
201
|
+
return `Blocked by ${readiness.blockingTaskIds.join(', ')}`;
|
|
202
|
+
case 'missing-dependency':
|
|
203
|
+
return `Missing dependency ${readiness.missingDependencyIds.join(', ')}`;
|
|
204
|
+
case 'done':
|
|
205
|
+
return 'Done';
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function dateReason(label, value, now) {
|
|
209
|
+
const time = parseDate(value);
|
|
210
|
+
if (time === undefined) {
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
const days = Math.floor((time - startOfDay(now).getTime()) / 86400000);
|
|
214
|
+
if (days < 0) {
|
|
215
|
+
return `${label} overdue`;
|
|
216
|
+
}
|
|
217
|
+
if (days === 0) {
|
|
218
|
+
return `${label} today`;
|
|
219
|
+
}
|
|
220
|
+
return `${label} in ${days} ${days === 1 ? 'day' : 'days'}`;
|
|
221
|
+
}
|
|
222
|
+
function parseDate(value) {
|
|
223
|
+
if (!value) {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
227
|
+
if (dateOnly) {
|
|
228
|
+
return new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3])).getTime();
|
|
229
|
+
}
|
|
230
|
+
const time = Date.parse(value);
|
|
231
|
+
return Number.isNaN(time) ? undefined : time;
|
|
232
|
+
}
|
|
233
|
+
function startOfDay(date) {
|
|
234
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
235
|
+
}
|
|
236
|
+
function capitalize(value) {
|
|
237
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=next-work.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-work.js","sourceRoot":"","sources":["../src/next-work.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML frontmatter parser
|
|
3
|
+
* Extracts and parses YAML frontmatter from markdown files
|
|
4
|
+
*/
|
|
5
|
+
export interface ParsedContent {
|
|
6
|
+
metadata: Record<string, unknown>;
|
|
7
|
+
body: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FrontmatterDiagnostic {
|
|
10
|
+
field: string;
|
|
11
|
+
message: string;
|
|
12
|
+
severity: 'error' | 'warning';
|
|
13
|
+
}
|
|
14
|
+
export interface TolerantParsedContent extends ParsedContent {
|
|
15
|
+
diagnostics: FrontmatterDiagnostic[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse YAML frontmatter from markdown content
|
|
19
|
+
* Expected format:
|
|
20
|
+
* ---
|
|
21
|
+
* key: value
|
|
22
|
+
* ---
|
|
23
|
+
* Body content here
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseFrontmatter(content: string): ParsedContent;
|
|
26
|
+
/**
|
|
27
|
+
* Parse YAML frontmatter without throwing.
|
|
28
|
+
*
|
|
29
|
+
* This is intended for repository loading paths where one malformed file should
|
|
30
|
+
* not hide unrelated planning artifacts from the user.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseFrontmatterTolerant(content: string): TolerantParsedContent;
|
|
33
|
+
/**
|
|
34
|
+
* Normalize metadata keys from kebab-case or snake_case to camelCase
|
|
35
|
+
*/
|
|
36
|
+
export declare function normalizeMetadata(metadata: Record<string, unknown>): Record<string, unknown>;
|
|
37
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAwC/D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAwC/E;AAgCD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* YAML frontmatter parser
|
|
4
|
+
* Extracts and parses YAML frontmatter from markdown files
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.parseFrontmatter = parseFrontmatter;
|
|
8
|
+
exports.parseFrontmatterTolerant = parseFrontmatterTolerant;
|
|
9
|
+
exports.normalizeMetadata = normalizeMetadata;
|
|
10
|
+
const yaml_1 = require("yaml");
|
|
11
|
+
/**
|
|
12
|
+
* Parse YAML frontmatter from markdown content
|
|
13
|
+
* Expected format:
|
|
14
|
+
* ---
|
|
15
|
+
* key: value
|
|
16
|
+
* ---
|
|
17
|
+
* Body content here
|
|
18
|
+
*/
|
|
19
|
+
function parseFrontmatter(content) {
|
|
20
|
+
const lines = content.split('\n');
|
|
21
|
+
// First line should be ---
|
|
22
|
+
if (lines[0]?.trim() !== '---') {
|
|
23
|
+
throw new Error('Content must start with --- frontmatter delimiter');
|
|
24
|
+
}
|
|
25
|
+
// Find closing ---
|
|
26
|
+
let endIndex = -1;
|
|
27
|
+
for (let i = 1; i < lines.length; i++) {
|
|
28
|
+
if (lines[i]?.trim() === '---') {
|
|
29
|
+
endIndex = i;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (endIndex === -1) {
|
|
34
|
+
throw new Error('Frontmatter must be closed with --- delimiter');
|
|
35
|
+
}
|
|
36
|
+
// Extract and parse YAML
|
|
37
|
+
const yamlContent = lines.slice(1, endIndex).join('\n');
|
|
38
|
+
let metadata = {};
|
|
39
|
+
if (yamlContent.trim()) {
|
|
40
|
+
try {
|
|
41
|
+
const parsed = (0, yaml_1.parse)(yamlContent);
|
|
42
|
+
metadata = typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new Error(`Failed to parse YAML frontmatter: ${error instanceof Error ? error.message : String(error)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Extract body
|
|
49
|
+
const body = lines.slice(endIndex + 1).join('\n').trimStart();
|
|
50
|
+
return { metadata, body };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parse YAML frontmatter without throwing.
|
|
54
|
+
*
|
|
55
|
+
* This is intended for repository loading paths where one malformed file should
|
|
56
|
+
* not hide unrelated planning artifacts from the user.
|
|
57
|
+
*/
|
|
58
|
+
function parseFrontmatterTolerant(content) {
|
|
59
|
+
const lines = content.split('\n');
|
|
60
|
+
const diagnostics = [];
|
|
61
|
+
if (lines[0]?.trim() !== '---') {
|
|
62
|
+
return {
|
|
63
|
+
metadata: {},
|
|
64
|
+
body: content.trimStart(),
|
|
65
|
+
diagnostics: [{
|
|
66
|
+
field: 'frontmatter',
|
|
67
|
+
message: 'Missing opening YAML frontmatter delimiter. Repair by adding --- before metadata and a closing --- before the Markdown body.',
|
|
68
|
+
severity: 'error'
|
|
69
|
+
}]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const endIndex = lines.findIndex((line, index) => index > 0 && line.trim() === '---');
|
|
73
|
+
if (endIndex === -1) {
|
|
74
|
+
const yamlContent = lines.slice(1).join('\n');
|
|
75
|
+
const metadata = parseYamlObject(yamlContent, diagnostics);
|
|
76
|
+
diagnostics.push({
|
|
77
|
+
field: 'frontmatter',
|
|
78
|
+
message: 'Missing closing YAML frontmatter delimiter. Repair by adding a line containing only --- before the Markdown body.',
|
|
79
|
+
severity: 'error'
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
metadata,
|
|
83
|
+
body: '',
|
|
84
|
+
diagnostics
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const yamlContent = lines.slice(1, endIndex).join('\n');
|
|
88
|
+
const metadata = parseYamlObject(yamlContent, diagnostics);
|
|
89
|
+
const body = lines.slice(endIndex + 1).join('\n').trimStart();
|
|
90
|
+
return {
|
|
91
|
+
metadata,
|
|
92
|
+
body,
|
|
93
|
+
diagnostics
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function parseYamlObject(yamlContent, diagnostics) {
|
|
97
|
+
if (!yamlContent.trim()) {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const parsed = (0, yaml_1.parse)(yamlContent);
|
|
102
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
103
|
+
return parsed;
|
|
104
|
+
}
|
|
105
|
+
diagnostics.push({
|
|
106
|
+
field: 'frontmatter',
|
|
107
|
+
message: 'YAML frontmatter must be a key/value object. Repair by using fields such as id, title, and status.',
|
|
108
|
+
severity: 'error'
|
|
109
|
+
});
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
diagnostics.push({
|
|
114
|
+
field: 'frontmatter',
|
|
115
|
+
message: `Failed to parse YAML frontmatter. Repair the YAML syntax before relying on metadata. Parser message: ${error instanceof Error ? error.message : String(error)}`,
|
|
116
|
+
severity: 'error'
|
|
117
|
+
});
|
|
118
|
+
return {};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Normalize metadata keys from kebab-case or snake_case to camelCase
|
|
123
|
+
*/
|
|
124
|
+
function normalizeMetadata(metadata) {
|
|
125
|
+
const normalized = {};
|
|
126
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
127
|
+
const camelKey = key.replace(/[-_]([a-z])/g, (_, char) => char.toUpperCase());
|
|
128
|
+
normalized[camelKey] = value;
|
|
129
|
+
}
|
|
130
|
+
return normalized;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA2BH,4CAwCC;AAQD,4DAwCC;AAmCD,8CAWC;AA/JD,+BAA0C;AAiB1C;;;;;;;GAOG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,2BAA2B;IAC3B,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,mBAAmB;IACnB,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;YAC/B,QAAQ,GAAG,CAAC,CAAC;YACb,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,yBAAyB;IACzB,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAE3C,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,YAAS,EAAC,WAAW,CAAC,CAAC;YACtC,QAAQ,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IAE9D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,OAAe;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,WAAW,GAA4B,EAAE,CAAC;IAEhD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;QAC/B,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE;YACzB,WAAW,EAAE,CAAC;oBACZ,KAAK,EAAE,aAAa;oBACpB,OAAO,EAAE,8HAA8H;oBACvI,QAAQ,EAAE,OAAO;iBAClB,CAAC;SACH,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC;IACtF,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAC3D,WAAW,CAAC,IAAI,CAAC;YACf,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,mHAAmH;YAC5H,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,OAAO;YACL,QAAQ;YACR,IAAI,EAAE,EAAE;YACR,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IAC9D,OAAO;QACL,QAAQ;QACR,IAAI;QACJ,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,WAAmB,EACnB,WAAoC;IAEpC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,YAAS,EAAC,WAAW,CAAC,CAAC;QACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,MAAiC,CAAC;QAC3C,CAAC;QAED,WAAW,CAAC,IAAI,CAAC;YACf,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,oGAAoG;YAC7G,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,IAAI,CAAC;YACf,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,wGAAwG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACzK,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,QAAiC;IAEjC,MAAM,UAAU,GAA4B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9E,UAAU,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;IAC/B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull request integration helpers
|
|
3
|
+
*/
|
|
4
|
+
import { BranchPlanningOptions } from './git';
|
|
5
|
+
import { Repository, Task } from './types';
|
|
6
|
+
export type PullRequestProviderId = 'github' | 'gitlab' | 'azure-devops';
|
|
7
|
+
export interface PullRequestProviderBoundary {
|
|
8
|
+
id: PullRequestProviderId;
|
|
9
|
+
name: string;
|
|
10
|
+
status: 'planned' | 'local-summary';
|
|
11
|
+
responsibilities: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface TaskPullRequestRef {
|
|
14
|
+
provider: PullRequestProviderId;
|
|
15
|
+
url: string;
|
|
16
|
+
status: 'linked';
|
|
17
|
+
}
|
|
18
|
+
export interface PullRequestSummaryOptions extends BranchPlanningOptions {
|
|
19
|
+
provider?: PullRequestProviderId;
|
|
20
|
+
}
|
|
21
|
+
export interface PullRequestSummary {
|
|
22
|
+
provider: PullRequestProviderId;
|
|
23
|
+
title: string;
|
|
24
|
+
markdown: string;
|
|
25
|
+
relatedTaskIds: string[];
|
|
26
|
+
branch: string;
|
|
27
|
+
baseRef: string;
|
|
28
|
+
changedPlanfsFiles: number;
|
|
29
|
+
addedTasks: number;
|
|
30
|
+
modifiedTasks: number;
|
|
31
|
+
deletedTasks: number;
|
|
32
|
+
conflicts: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function getPullRequestProviderBoundaries(): PullRequestProviderBoundary[];
|
|
35
|
+
export declare function generatePullRequestSummary(rootPath: string, options?: PullRequestSummaryOptions): Promise<PullRequestSummary>;
|
|
36
|
+
export declare function getTaskPullRequestRefs(task: Task): TaskPullRequestRef[];
|
|
37
|
+
export declare function getTaskPullRequestRefsById(repository: Repository): Map<string, TaskPullRequestRef[]>;
|
|
38
|
+
//# sourceMappingURL=pull-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull-request.d.ts","sourceRoot":"","sources":["../src/pull-request.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA4B,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEzE,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,qBAAqB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,eAAe,CAAC;IACpC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gCAAgC,IAAI,2BAA2B,EAAE,CAiChF;AAED,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,kBAAkB,CAAC,CAyD7B;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,kBAAkB,EAAE,CAUvE;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,UAAU,GACrB,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAWnC"}
|