@markmdev/pebble 0.1.20 → 0.1.21
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/dist/cli/index.js
CHANGED
|
@@ -566,10 +566,12 @@ function getBlocking(issueId) {
|
|
|
566
566
|
(issue) => issue.blockedBy.includes(issueId)
|
|
567
567
|
);
|
|
568
568
|
}
|
|
569
|
-
function getChildren(epicId) {
|
|
569
|
+
function getChildren(epicId, includeDeleted = false) {
|
|
570
570
|
const events = readEvents();
|
|
571
571
|
const state = computeState(events);
|
|
572
|
-
return Array.from(state.values()).filter(
|
|
572
|
+
return Array.from(state.values()).filter(
|
|
573
|
+
(issue) => issue.parent === epicId && (includeDeleted || !issue.deleted)
|
|
574
|
+
);
|
|
573
575
|
}
|
|
574
576
|
function getVerifications(issueId) {
|
|
575
577
|
const events = readEvents();
|
|
@@ -1148,6 +1150,15 @@ function createCommand(program2) {
|
|
|
1148
1150
|
}
|
|
1149
1151
|
};
|
|
1150
1152
|
appendEvent(event, pebbleDir);
|
|
1153
|
+
if (parentId) {
|
|
1154
|
+
const parentUpdateEvent = {
|
|
1155
|
+
type: "update",
|
|
1156
|
+
issueId: parentId,
|
|
1157
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1158
|
+
data: {}
|
|
1159
|
+
};
|
|
1160
|
+
appendEvent(parentUpdateEvent, pebbleDir);
|
|
1161
|
+
}
|
|
1151
1162
|
if (blockedByIds.length > 0) {
|
|
1152
1163
|
const depEvent = {
|
|
1153
1164
|
type: "update",
|
|
@@ -1322,8 +1333,8 @@ function closeCommand(program2) {
|
|
|
1322
1333
|
results.push({ id: resolvedId, success: false, error: `Issue is already closed: ${resolvedId}` });
|
|
1323
1334
|
continue;
|
|
1324
1335
|
}
|
|
1325
|
-
if (
|
|
1326
|
-
results.push({ id: resolvedId, success: false, error: `Cannot close
|
|
1336
|
+
if (hasOpenChildren(resolvedId)) {
|
|
1337
|
+
results.push({ id: resolvedId, success: false, error: `Cannot close issue with open children: ${resolvedId}` });
|
|
1327
1338
|
continue;
|
|
1328
1339
|
}
|
|
1329
1340
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2805,6 +2816,15 @@ data: ${message}
|
|
|
2805
2816
|
}
|
|
2806
2817
|
};
|
|
2807
2818
|
appendEvent(event, pebbleDir);
|
|
2819
|
+
if (parent) {
|
|
2820
|
+
const parentUpdateEvent = {
|
|
2821
|
+
type: "update",
|
|
2822
|
+
issueId: parent,
|
|
2823
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2824
|
+
data: {}
|
|
2825
|
+
};
|
|
2826
|
+
appendEvent(parentUpdateEvent, pebbleDir);
|
|
2827
|
+
}
|
|
2808
2828
|
const issue = getIssue(issueId);
|
|
2809
2829
|
const result = parentReopened ? { ...issue, _parentReopened: parentReopened } : issue;
|
|
2810
2830
|
res.status(201).json(result);
|
|
@@ -2833,8 +2853,8 @@ data: ${message}
|
|
|
2833
2853
|
results.push({ id: issueId, success: true });
|
|
2834
2854
|
continue;
|
|
2835
2855
|
}
|
|
2836
|
-
if (
|
|
2837
|
-
results.push({ id: issueId, success: false, error: "Cannot close
|
|
2856
|
+
if (hasOpenChildren(issueId)) {
|
|
2857
|
+
results.push({ id: issueId, success: false, error: "Cannot close issue with open children" });
|
|
2838
2858
|
continue;
|
|
2839
2859
|
}
|
|
2840
2860
|
const pendingVerifications = getVerifications(issueId).filter((v) => v.status !== "closed");
|
|
@@ -3084,8 +3104,8 @@ data: ${message}
|
|
|
3084
3104
|
res.status(400).json({ error: "Issue is already closed" });
|
|
3085
3105
|
return;
|
|
3086
3106
|
}
|
|
3087
|
-
if (!isMultiWorktree() &&
|
|
3088
|
-
res.status(400).json({ error: "Cannot close
|
|
3107
|
+
if (!isMultiWorktree() && hasOpenChildren(issueId)) {
|
|
3108
|
+
res.status(400).json({ error: "Cannot close issue with open children" });
|
|
3089
3109
|
return;
|
|
3090
3110
|
}
|
|
3091
3111
|
const { reason } = req.body;
|
|
@@ -3898,6 +3918,21 @@ function formatInProgressPretty(issues) {
|
|
|
3898
3918
|
}
|
|
3899
3919
|
return lines.join("\n");
|
|
3900
3920
|
}
|
|
3921
|
+
function formatClosedIssuesPretty(issues) {
|
|
3922
|
+
if (issues.length === 0) return "";
|
|
3923
|
+
const lines = [];
|
|
3924
|
+
lines.push(`## Recently Closed (${issues.length})`);
|
|
3925
|
+
lines.push("");
|
|
3926
|
+
for (const issue of issues) {
|
|
3927
|
+
lines.push(`\u2713 ${issue.id}: ${issue.title} [${issue.type}]`);
|
|
3928
|
+
lines.push(` Closed: ${formatRelativeTime(issue.closedAt)}${issue.lastSource ? ` | Source: ${issue.lastSource}` : ""}`);
|
|
3929
|
+
if (issue.parent) {
|
|
3930
|
+
lines.push(` Parent: ${issue.parent.title}`);
|
|
3931
|
+
}
|
|
3932
|
+
lines.push("");
|
|
3933
|
+
}
|
|
3934
|
+
return lines.join("\n");
|
|
3935
|
+
}
|
|
3901
3936
|
function formatSummaryPretty(summaries, sectionHeader) {
|
|
3902
3937
|
if (summaries.length === 0) {
|
|
3903
3938
|
return "No epics found.";
|
|
@@ -4012,6 +4047,27 @@ function summaryCommand(program2) {
|
|
|
4012
4047
|
const limitedClosed = limit > 0 ? closedEpics.slice(0, limit) : closedEpics;
|
|
4013
4048
|
const openSummaries = limitedOpen.map(buildSummary);
|
|
4014
4049
|
const closedSummaries = limitedClosed.map(buildSummary);
|
|
4050
|
+
let closedIssues = getIssues({ status: "closed" });
|
|
4051
|
+
closedIssues.sort(
|
|
4052
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
4053
|
+
);
|
|
4054
|
+
closedIssues = closedIssues.slice(0, 20);
|
|
4055
|
+
const recentlyClosedSummaries = closedIssues.map((issue) => {
|
|
4056
|
+
const summary = {
|
|
4057
|
+
id: issue.id,
|
|
4058
|
+
title: issue.title,
|
|
4059
|
+
type: issue.type,
|
|
4060
|
+
closedAt: issue.updatedAt,
|
|
4061
|
+
lastSource: issue.lastSource
|
|
4062
|
+
};
|
|
4063
|
+
if (issue.parent) {
|
|
4064
|
+
const parentIssue = getIssue(issue.parent, true);
|
|
4065
|
+
if (parentIssue) {
|
|
4066
|
+
summary.parent = { id: parentIssue.id, title: parentIssue.title };
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
return summary;
|
|
4070
|
+
});
|
|
4015
4071
|
if (pretty) {
|
|
4016
4072
|
const output = [];
|
|
4017
4073
|
const inProgressOutput = formatInProgressPretty(inProgressSummaries);
|
|
@@ -4026,12 +4082,16 @@ function summaryCommand(program2) {
|
|
|
4026
4082
|
if (output.length > 0) output.push("");
|
|
4027
4083
|
output.push(formatSummaryPretty(closedSummaries, "Recently Closed Epics (last 72h)"));
|
|
4028
4084
|
}
|
|
4085
|
+
if (recentlyClosedSummaries.length > 0) {
|
|
4086
|
+
if (output.length > 0) output.push("");
|
|
4087
|
+
output.push(formatClosedIssuesPretty(recentlyClosedSummaries));
|
|
4088
|
+
}
|
|
4029
4089
|
if (output.length === 0) {
|
|
4030
4090
|
output.push("No issues in progress and no epics found.");
|
|
4031
4091
|
}
|
|
4032
4092
|
console.log(output.join("\n"));
|
|
4033
4093
|
} else {
|
|
4034
|
-
console.log(formatJson({ inProgress: inProgressSummaries, open: openSummaries, closed: closedSummaries }));
|
|
4094
|
+
console.log(formatJson({ inProgress: inProgressSummaries, open: openSummaries, closed: closedSummaries, recentlyClosed: recentlyClosedSummaries }));
|
|
4035
4095
|
}
|
|
4036
4096
|
} catch (error) {
|
|
4037
4097
|
outputError(error, pretty);
|