@bretwardjames/ghp-core 0.7.1 → 0.8.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/dist/index.cjs +77 -7
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +77 -7
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1908,6 +1908,7 @@ var GitHubAPI = class {
|
|
|
1908
1908
|
*/
|
|
1909
1909
|
async getRecentActivity(repo, since, options) {
|
|
1910
1910
|
if (!this.graphqlWithAuth) throw new Error("Not authenticated");
|
|
1911
|
+
const filterUser = options?.user || (options?.mine ? this.username : null);
|
|
1911
1912
|
const projects = await this.getProjects(repo);
|
|
1912
1913
|
if (projects.length === 0) return [];
|
|
1913
1914
|
const allItems = [];
|
|
@@ -1921,9 +1922,9 @@ var GitHubAPI = class {
|
|
|
1921
1922
|
let recentItems = allItems.filter(
|
|
1922
1923
|
(item) => item.updatedAt && new Date(item.updatedAt).getTime() >= sinceMs
|
|
1923
1924
|
);
|
|
1924
|
-
if (
|
|
1925
|
+
if (filterUser) {
|
|
1925
1926
|
recentItems = recentItems.filter(
|
|
1926
|
-
(item) => item.assignees.includes(
|
|
1927
|
+
(item) => item.assignees.includes(filterUser)
|
|
1927
1928
|
);
|
|
1928
1929
|
}
|
|
1929
1930
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1968,10 +1969,11 @@ var GitHubAPI = class {
|
|
|
1968
1969
|
}
|
|
1969
1970
|
}
|
|
1970
1971
|
const activityNumbers = new Set(activities.map((a) => a.issue.number));
|
|
1971
|
-
|
|
1972
|
+
const prSearchUser = filterUser || this.username;
|
|
1973
|
+
if (prSearchUser) {
|
|
1972
1974
|
const reviewActivities = await this.fetchReviewedPRs(
|
|
1973
1975
|
repo,
|
|
1974
|
-
|
|
1976
|
+
prSearchUser,
|
|
1975
1977
|
sinceDate,
|
|
1976
1978
|
sinceMs,
|
|
1977
1979
|
activityNumbers
|
|
@@ -1980,11 +1982,9 @@ var GitHubAPI = class {
|
|
|
1980
1982
|
activityNumbers.add(a.issue.number);
|
|
1981
1983
|
activities.push(a);
|
|
1982
1984
|
}
|
|
1983
|
-
}
|
|
1984
|
-
if (this.username) {
|
|
1985
1985
|
const authoredActivities = await this.fetchAuthoredPRs(
|
|
1986
1986
|
repo,
|
|
1987
|
-
|
|
1987
|
+
prSearchUser,
|
|
1988
1988
|
sinceDate,
|
|
1989
1989
|
sinceMs,
|
|
1990
1990
|
activityNumbers
|
|
@@ -4244,6 +4244,12 @@ function validateUrl(url) {
|
|
|
4244
4244
|
|
|
4245
4245
|
// src/standup.ts
|
|
4246
4246
|
function formatStandupText(activities, options) {
|
|
4247
|
+
if (options.timeline) {
|
|
4248
|
+
return formatTimeline(activities, options);
|
|
4249
|
+
}
|
|
4250
|
+
return formatGrouped(activities, options);
|
|
4251
|
+
}
|
|
4252
|
+
function formatGrouped(activities, options) {
|
|
4247
4253
|
const { since } = options;
|
|
4248
4254
|
const lines = [];
|
|
4249
4255
|
const sinceStr = formatRelativeDate(since);
|
|
@@ -4264,6 +4270,35 @@ function formatStandupText(activities, options) {
|
|
|
4264
4270
|
}
|
|
4265
4271
|
return lines.join("\n").trimEnd();
|
|
4266
4272
|
}
|
|
4273
|
+
function formatTimeline(activities, options) {
|
|
4274
|
+
const { since } = options;
|
|
4275
|
+
const lines = [];
|
|
4276
|
+
const allEvents = [];
|
|
4277
|
+
for (const activity of activities) {
|
|
4278
|
+
for (const event of activity.changes) {
|
|
4279
|
+
allEvents.push({ event, issue: activity.issue });
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
allEvents.sort(
|
|
4283
|
+
(a, b) => new Date(b.event.timestamp).getTime() - new Date(a.event.timestamp).getTime()
|
|
4284
|
+
);
|
|
4285
|
+
const sinceStr = formatRelativeDate(since);
|
|
4286
|
+
const eventCount = allEvents.length;
|
|
4287
|
+
const issueCount = activities.length;
|
|
4288
|
+
lines.push(`Since ${sinceStr} \u2014 ${eventCount} event${eventCount !== 1 ? "s" : ""} across ${issueCount} issue${issueCount !== 1 ? "s" : ""}`);
|
|
4289
|
+
lines.push("");
|
|
4290
|
+
if (allEvents.length === 0) {
|
|
4291
|
+
lines.push("No activity found in this time window.");
|
|
4292
|
+
return lines.join("\n");
|
|
4293
|
+
}
|
|
4294
|
+
for (const { event, issue } of allEvents) {
|
|
4295
|
+
const time = formatShortTimestamp(event.timestamp);
|
|
4296
|
+
const desc = formatEventDescription(event);
|
|
4297
|
+
const issueRef = `#${issue.number} ${truncate(issue.title, 50)}`;
|
|
4298
|
+
lines.push(`${time} ${desc} (${issueRef})`);
|
|
4299
|
+
}
|
|
4300
|
+
return lines.join("\n").trimEnd();
|
|
4301
|
+
}
|
|
4267
4302
|
function parseSince(input) {
|
|
4268
4303
|
const isoDate = new Date(input);
|
|
4269
4304
|
if (!isNaN(isoDate.getTime()) && input.includes("-")) {
|
|
@@ -4320,6 +4355,41 @@ function formatEventLine(event) {
|
|
|
4320
4355
|
return `${arrow} ${event.type} by ${actor} (${timestamp})`;
|
|
4321
4356
|
}
|
|
4322
4357
|
}
|
|
4358
|
+
function formatEventDescription(event) {
|
|
4359
|
+
const actor = event.actor;
|
|
4360
|
+
switch (event.type) {
|
|
4361
|
+
case "comment":
|
|
4362
|
+
return `Comment by ${actor}${event.details ? ": " + event.details : ""}`;
|
|
4363
|
+
case "labeled":
|
|
4364
|
+
return `Labeled "${event.details}" by ${actor}`;
|
|
4365
|
+
case "unlabeled":
|
|
4366
|
+
return `Unlabeled "${event.details}" by ${actor}`;
|
|
4367
|
+
case "assigned":
|
|
4368
|
+
return `Assigned to ${event.details || actor}`;
|
|
4369
|
+
case "unassigned":
|
|
4370
|
+
return `Unassigned ${event.details || ""} by ${actor}`;
|
|
4371
|
+
case "closed":
|
|
4372
|
+
return `Closed by ${actor}`;
|
|
4373
|
+
case "reopened":
|
|
4374
|
+
return `Reopened by ${actor}`;
|
|
4375
|
+
case "referenced":
|
|
4376
|
+
return `${event.details} linked by ${actor}`;
|
|
4377
|
+
case "review_submitted":
|
|
4378
|
+
return `${event.details} by ${actor}`;
|
|
4379
|
+
case "review_requested":
|
|
4380
|
+
return `Review requested from ${event.details || "team"} by ${actor}`;
|
|
4381
|
+
case "pr_created":
|
|
4382
|
+
return `PR created by ${actor}`;
|
|
4383
|
+
case "pr_merged":
|
|
4384
|
+
return `PR merged by ${actor}`;
|
|
4385
|
+
default:
|
|
4386
|
+
return `${event.type} by ${actor}`;
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
function truncate(str, maxLen) {
|
|
4390
|
+
if (str.length <= maxLen) return str;
|
|
4391
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
4392
|
+
}
|
|
4323
4393
|
function formatRelativeDate(date) {
|
|
4324
4394
|
const now = /* @__PURE__ */ new Date();
|
|
4325
4395
|
const diffMs = now.getTime() - date.getTime();
|
package/dist/index.d.cts
CHANGED
|
@@ -691,6 +691,7 @@ declare class GitHubAPI {
|
|
|
691
691
|
*/
|
|
692
692
|
getRecentActivity(repo: RepoInfo, since: Date, options?: {
|
|
693
693
|
mine?: boolean;
|
|
694
|
+
user?: string;
|
|
694
695
|
}): Promise<IssueActivity[]>;
|
|
695
696
|
/**
|
|
696
697
|
* Search for PRs the user reviewed that aren't already in the activity list.
|
|
@@ -2283,6 +2284,8 @@ declare function validateUrl(url: string): string;
|
|
|
2283
2284
|
interface FormatStandupOptions {
|
|
2284
2285
|
since: Date;
|
|
2285
2286
|
colorize?: boolean;
|
|
2287
|
+
/** If true, show a flat chronological timeline instead of grouping by issue */
|
|
2288
|
+
timeline?: boolean;
|
|
2286
2289
|
}
|
|
2287
2290
|
/**
|
|
2288
2291
|
* Format a standup summary as human-readable text.
|
package/dist/index.d.ts
CHANGED
|
@@ -691,6 +691,7 @@ declare class GitHubAPI {
|
|
|
691
691
|
*/
|
|
692
692
|
getRecentActivity(repo: RepoInfo, since: Date, options?: {
|
|
693
693
|
mine?: boolean;
|
|
694
|
+
user?: string;
|
|
694
695
|
}): Promise<IssueActivity[]>;
|
|
695
696
|
/**
|
|
696
697
|
* Search for PRs the user reviewed that aren't already in the activity list.
|
|
@@ -2283,6 +2284,8 @@ declare function validateUrl(url: string): string;
|
|
|
2283
2284
|
interface FormatStandupOptions {
|
|
2284
2285
|
since: Date;
|
|
2285
2286
|
colorize?: boolean;
|
|
2287
|
+
/** If true, show a flat chronological timeline instead of grouping by issue */
|
|
2288
|
+
timeline?: boolean;
|
|
2286
2289
|
}
|
|
2287
2290
|
/**
|
|
2288
2291
|
* Format a standup summary as human-readable text.
|
package/dist/index.js
CHANGED
|
@@ -1739,6 +1739,7 @@ var GitHubAPI = class {
|
|
|
1739
1739
|
*/
|
|
1740
1740
|
async getRecentActivity(repo, since, options) {
|
|
1741
1741
|
if (!this.graphqlWithAuth) throw new Error("Not authenticated");
|
|
1742
|
+
const filterUser = options?.user || (options?.mine ? this.username : null);
|
|
1742
1743
|
const projects = await this.getProjects(repo);
|
|
1743
1744
|
if (projects.length === 0) return [];
|
|
1744
1745
|
const allItems = [];
|
|
@@ -1752,9 +1753,9 @@ var GitHubAPI = class {
|
|
|
1752
1753
|
let recentItems = allItems.filter(
|
|
1753
1754
|
(item) => item.updatedAt && new Date(item.updatedAt).getTime() >= sinceMs
|
|
1754
1755
|
);
|
|
1755
|
-
if (
|
|
1756
|
+
if (filterUser) {
|
|
1756
1757
|
recentItems = recentItems.filter(
|
|
1757
|
-
(item) => item.assignees.includes(
|
|
1758
|
+
(item) => item.assignees.includes(filterUser)
|
|
1758
1759
|
);
|
|
1759
1760
|
}
|
|
1760
1761
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1799,10 +1800,11 @@ var GitHubAPI = class {
|
|
|
1799
1800
|
}
|
|
1800
1801
|
}
|
|
1801
1802
|
const activityNumbers = new Set(activities.map((a) => a.issue.number));
|
|
1802
|
-
|
|
1803
|
+
const prSearchUser = filterUser || this.username;
|
|
1804
|
+
if (prSearchUser) {
|
|
1803
1805
|
const reviewActivities = await this.fetchReviewedPRs(
|
|
1804
1806
|
repo,
|
|
1805
|
-
|
|
1807
|
+
prSearchUser,
|
|
1806
1808
|
sinceDate,
|
|
1807
1809
|
sinceMs,
|
|
1808
1810
|
activityNumbers
|
|
@@ -1811,11 +1813,9 @@ var GitHubAPI = class {
|
|
|
1811
1813
|
activityNumbers.add(a.issue.number);
|
|
1812
1814
|
activities.push(a);
|
|
1813
1815
|
}
|
|
1814
|
-
}
|
|
1815
|
-
if (this.username) {
|
|
1816
1816
|
const authoredActivities = await this.fetchAuthoredPRs(
|
|
1817
1817
|
repo,
|
|
1818
|
-
|
|
1818
|
+
prSearchUser,
|
|
1819
1819
|
sinceDate,
|
|
1820
1820
|
sinceMs,
|
|
1821
1821
|
activityNumbers
|
|
@@ -4075,6 +4075,12 @@ function validateUrl(url) {
|
|
|
4075
4075
|
|
|
4076
4076
|
// src/standup.ts
|
|
4077
4077
|
function formatStandupText(activities, options) {
|
|
4078
|
+
if (options.timeline) {
|
|
4079
|
+
return formatTimeline(activities, options);
|
|
4080
|
+
}
|
|
4081
|
+
return formatGrouped(activities, options);
|
|
4082
|
+
}
|
|
4083
|
+
function formatGrouped(activities, options) {
|
|
4078
4084
|
const { since } = options;
|
|
4079
4085
|
const lines = [];
|
|
4080
4086
|
const sinceStr = formatRelativeDate(since);
|
|
@@ -4095,6 +4101,35 @@ function formatStandupText(activities, options) {
|
|
|
4095
4101
|
}
|
|
4096
4102
|
return lines.join("\n").trimEnd();
|
|
4097
4103
|
}
|
|
4104
|
+
function formatTimeline(activities, options) {
|
|
4105
|
+
const { since } = options;
|
|
4106
|
+
const lines = [];
|
|
4107
|
+
const allEvents = [];
|
|
4108
|
+
for (const activity of activities) {
|
|
4109
|
+
for (const event of activity.changes) {
|
|
4110
|
+
allEvents.push({ event, issue: activity.issue });
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
allEvents.sort(
|
|
4114
|
+
(a, b) => new Date(b.event.timestamp).getTime() - new Date(a.event.timestamp).getTime()
|
|
4115
|
+
);
|
|
4116
|
+
const sinceStr = formatRelativeDate(since);
|
|
4117
|
+
const eventCount = allEvents.length;
|
|
4118
|
+
const issueCount = activities.length;
|
|
4119
|
+
lines.push(`Since ${sinceStr} \u2014 ${eventCount} event${eventCount !== 1 ? "s" : ""} across ${issueCount} issue${issueCount !== 1 ? "s" : ""}`);
|
|
4120
|
+
lines.push("");
|
|
4121
|
+
if (allEvents.length === 0) {
|
|
4122
|
+
lines.push("No activity found in this time window.");
|
|
4123
|
+
return lines.join("\n");
|
|
4124
|
+
}
|
|
4125
|
+
for (const { event, issue } of allEvents) {
|
|
4126
|
+
const time = formatShortTimestamp(event.timestamp);
|
|
4127
|
+
const desc = formatEventDescription(event);
|
|
4128
|
+
const issueRef = `#${issue.number} ${truncate(issue.title, 50)}`;
|
|
4129
|
+
lines.push(`${time} ${desc} (${issueRef})`);
|
|
4130
|
+
}
|
|
4131
|
+
return lines.join("\n").trimEnd();
|
|
4132
|
+
}
|
|
4098
4133
|
function parseSince(input) {
|
|
4099
4134
|
const isoDate = new Date(input);
|
|
4100
4135
|
if (!isNaN(isoDate.getTime()) && input.includes("-")) {
|
|
@@ -4151,6 +4186,41 @@ function formatEventLine(event) {
|
|
|
4151
4186
|
return `${arrow} ${event.type} by ${actor} (${timestamp})`;
|
|
4152
4187
|
}
|
|
4153
4188
|
}
|
|
4189
|
+
function formatEventDescription(event) {
|
|
4190
|
+
const actor = event.actor;
|
|
4191
|
+
switch (event.type) {
|
|
4192
|
+
case "comment":
|
|
4193
|
+
return `Comment by ${actor}${event.details ? ": " + event.details : ""}`;
|
|
4194
|
+
case "labeled":
|
|
4195
|
+
return `Labeled "${event.details}" by ${actor}`;
|
|
4196
|
+
case "unlabeled":
|
|
4197
|
+
return `Unlabeled "${event.details}" by ${actor}`;
|
|
4198
|
+
case "assigned":
|
|
4199
|
+
return `Assigned to ${event.details || actor}`;
|
|
4200
|
+
case "unassigned":
|
|
4201
|
+
return `Unassigned ${event.details || ""} by ${actor}`;
|
|
4202
|
+
case "closed":
|
|
4203
|
+
return `Closed by ${actor}`;
|
|
4204
|
+
case "reopened":
|
|
4205
|
+
return `Reopened by ${actor}`;
|
|
4206
|
+
case "referenced":
|
|
4207
|
+
return `${event.details} linked by ${actor}`;
|
|
4208
|
+
case "review_submitted":
|
|
4209
|
+
return `${event.details} by ${actor}`;
|
|
4210
|
+
case "review_requested":
|
|
4211
|
+
return `Review requested from ${event.details || "team"} by ${actor}`;
|
|
4212
|
+
case "pr_created":
|
|
4213
|
+
return `PR created by ${actor}`;
|
|
4214
|
+
case "pr_merged":
|
|
4215
|
+
return `PR merged by ${actor}`;
|
|
4216
|
+
default:
|
|
4217
|
+
return `${event.type} by ${actor}`;
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
function truncate(str, maxLen) {
|
|
4221
|
+
if (str.length <= maxLen) return str;
|
|
4222
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
4223
|
+
}
|
|
4154
4224
|
function formatRelativeDate(date) {
|
|
4155
4225
|
const now = /* @__PURE__ */ new Date();
|
|
4156
4226
|
const diffMs = now.getTime() - date.getTime();
|