@bretwardjames/ghp-core 0.7.1 → 0.9.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 +20 -0
- package/dist/index.cjs +112 -8
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +110 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,21 @@ const result = await withRetry(
|
|
|
105
105
|
const result = await withRetry(() => api.getIssue(repo, 123), DEFAULT_RETRY_CONFIG);
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### Git Utilities
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { listTags, resolveRef, createBranch } from '@bretwardjames/ghp-core';
|
|
112
|
+
|
|
113
|
+
// List git tags sorted by version (newest first)
|
|
114
|
+
const tags = await listTags(); // ['v1.2.0', 'v1.1.0', ...]
|
|
115
|
+
|
|
116
|
+
// Validate and resolve a git ref (tag, commit, branch)
|
|
117
|
+
const sha = await resolveRef('v1.2.0'); // 'abc123...' or null
|
|
118
|
+
|
|
119
|
+
// Create a branch from a specific ref (for hotfixes)
|
|
120
|
+
await createBranch('hotfix/fix-login', { startPoint: 'v1.2.0' });
|
|
121
|
+
```
|
|
122
|
+
|
|
108
123
|
### Shell Utilities
|
|
109
124
|
|
|
110
125
|
Safe shell command construction to prevent injection:
|
|
@@ -120,6 +135,11 @@ const num = validateNumericInput("123", "issue number"); // 123 or throws
|
|
|
120
135
|
|
|
121
136
|
// Validate URLs
|
|
122
137
|
validateUrl("https://github.com/...", "issue URL"); // throws if invalid
|
|
138
|
+
|
|
139
|
+
// Validate git ref strings (rejects shell metacharacters)
|
|
140
|
+
import { validateRefString } from '@bretwardjames/ghp-core';
|
|
141
|
+
validateRefString('v1.2.0'); // ok
|
|
142
|
+
validateRefString('v1; rm -rf /'); // throws Error
|
|
123
143
|
```
|
|
124
144
|
|
|
125
145
|
### Event Hooks
|
package/dist/index.cjs
CHANGED
|
@@ -125,6 +125,7 @@ __export(index_exports, {
|
|
|
125
125
|
isGitRepository: () => isGitRepository,
|
|
126
126
|
isTransientError: () => isTransientError,
|
|
127
127
|
listAgents: () => listAgents,
|
|
128
|
+
listTags: () => listTags,
|
|
128
129
|
listWorktrees: () => listWorktrees,
|
|
129
130
|
loadEventHooksConfig: () => loadEventHooksConfig,
|
|
130
131
|
loadHooksConfig: () => loadHooksConfig,
|
|
@@ -146,6 +147,7 @@ __export(index_exports, {
|
|
|
146
147
|
removeWorktree: () => removeWorktree,
|
|
147
148
|
removeWorktreeWorkflow: () => removeWorktreeWorkflow,
|
|
148
149
|
resolveConflicts: () => resolveConflicts,
|
|
150
|
+
resolveRef: () => resolveRef,
|
|
149
151
|
sanitizeForBranchName: () => sanitizeForBranchName,
|
|
150
152
|
saveEventHooksConfig: () => saveEventHooksConfig,
|
|
151
153
|
saveHooksConfig: () => saveHooksConfig,
|
|
@@ -1908,6 +1910,7 @@ var GitHubAPI = class {
|
|
|
1908
1910
|
*/
|
|
1909
1911
|
async getRecentActivity(repo, since, options) {
|
|
1910
1912
|
if (!this.graphqlWithAuth) throw new Error("Not authenticated");
|
|
1913
|
+
const filterUser = options?.user || (options?.mine ? this.username : null);
|
|
1911
1914
|
const projects = await this.getProjects(repo);
|
|
1912
1915
|
if (projects.length === 0) return [];
|
|
1913
1916
|
const allItems = [];
|
|
@@ -1921,9 +1924,9 @@ var GitHubAPI = class {
|
|
|
1921
1924
|
let recentItems = allItems.filter(
|
|
1922
1925
|
(item) => item.updatedAt && new Date(item.updatedAt).getTime() >= sinceMs
|
|
1923
1926
|
);
|
|
1924
|
-
if (
|
|
1927
|
+
if (filterUser) {
|
|
1925
1928
|
recentItems = recentItems.filter(
|
|
1926
|
-
(item) => item.assignees.includes(
|
|
1929
|
+
(item) => item.assignees.includes(filterUser)
|
|
1927
1930
|
);
|
|
1928
1931
|
}
|
|
1929
1932
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1968,10 +1971,11 @@ var GitHubAPI = class {
|
|
|
1968
1971
|
}
|
|
1969
1972
|
}
|
|
1970
1973
|
const activityNumbers = new Set(activities.map((a) => a.issue.number));
|
|
1971
|
-
|
|
1974
|
+
const prSearchUser = filterUser || this.username;
|
|
1975
|
+
if (prSearchUser) {
|
|
1972
1976
|
const reviewActivities = await this.fetchReviewedPRs(
|
|
1973
1977
|
repo,
|
|
1974
|
-
|
|
1978
|
+
prSearchUser,
|
|
1975
1979
|
sinceDate,
|
|
1976
1980
|
sinceMs,
|
|
1977
1981
|
activityNumbers
|
|
@@ -1980,11 +1984,9 @@ var GitHubAPI = class {
|
|
|
1980
1984
|
activityNumbers.add(a.issue.number);
|
|
1981
1985
|
activities.push(a);
|
|
1982
1986
|
}
|
|
1983
|
-
}
|
|
1984
|
-
if (this.username) {
|
|
1985
1987
|
const authoredActivities = await this.fetchAuthoredPRs(
|
|
1986
1988
|
repo,
|
|
1987
|
-
|
|
1989
|
+
prSearchUser,
|
|
1988
1990
|
sinceDate,
|
|
1989
1991
|
sinceMs,
|
|
1990
1992
|
activityNumbers
|
|
@@ -2333,6 +2335,15 @@ function buildOrgProjectUrl(org, projectNumber) {
|
|
|
2333
2335
|
function sanitizeForPath(input) {
|
|
2334
2336
|
return String(input).replace(/\.\./g, "_").replace(/[;&|`$(){}[\]<>!]/g, "").replace(/\s+/g, "-").replace(/[^a-zA-Z0-9_\-./]/g, "_");
|
|
2335
2337
|
}
|
|
2338
|
+
function validateRefString(ref) {
|
|
2339
|
+
if (!ref || ref.trim().length === 0) {
|
|
2340
|
+
throw new Error("Ref cannot be empty");
|
|
2341
|
+
}
|
|
2342
|
+
const dangerousChars = /[`$\\!;|&<>(){}[\]'"]/;
|
|
2343
|
+
if (dangerousChars.test(ref)) {
|
|
2344
|
+
throw new Error(`Ref contains invalid characters: ${ref}`);
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2336
2347
|
function validateBranchName(branch) {
|
|
2337
2348
|
if (!branch || branch.trim().length === 0) {
|
|
2338
2349
|
throw new Error("Branch name cannot be empty");
|
|
@@ -2393,7 +2404,11 @@ async function branchExists(branchName, options = {}) {
|
|
|
2393
2404
|
}
|
|
2394
2405
|
}
|
|
2395
2406
|
async function createBranch(branchName, options = {}) {
|
|
2396
|
-
|
|
2407
|
+
if (options.startPoint) {
|
|
2408
|
+
validateRefString(options.startPoint);
|
|
2409
|
+
}
|
|
2410
|
+
const cmd = options.startPoint ? `git checkout -b "${branchName}" "${options.startPoint}"` : `git checkout -b "${branchName}"`;
|
|
2411
|
+
await execGit(cmd, options);
|
|
2397
2412
|
}
|
|
2398
2413
|
async function checkoutBranch(branchName, options = {}) {
|
|
2399
2414
|
await execGit(`git checkout "${branchName}"`, options);
|
|
@@ -2465,6 +2480,23 @@ function extractIssueNumberFromBranch(branchName) {
|
|
|
2465
2480
|
}
|
|
2466
2481
|
return null;
|
|
2467
2482
|
}
|
|
2483
|
+
async function listTags(options = {}) {
|
|
2484
|
+
try {
|
|
2485
|
+
const { stdout } = await execGit("git tag -l --sort=-version:refname", options);
|
|
2486
|
+
return stdout.split("\n").filter(Boolean);
|
|
2487
|
+
} catch {
|
|
2488
|
+
return [];
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
async function resolveRef(ref, options = {}) {
|
|
2492
|
+
validateRefString(ref);
|
|
2493
|
+
try {
|
|
2494
|
+
const { stdout } = await execGit(`git rev-parse --verify "${ref}"`, options);
|
|
2495
|
+
return stdout.trim();
|
|
2496
|
+
} catch {
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2468
2500
|
async function getLocalBranches(options = {}) {
|
|
2469
2501
|
const { stdout } = await execGit('git branch --format="%(refname:short)"', options);
|
|
2470
2502
|
return stdout.split("\n").map((b) => b.trim()).filter((b) => b.length > 0);
|
|
@@ -4244,6 +4276,12 @@ function validateUrl(url) {
|
|
|
4244
4276
|
|
|
4245
4277
|
// src/standup.ts
|
|
4246
4278
|
function formatStandupText(activities, options) {
|
|
4279
|
+
if (options.timeline) {
|
|
4280
|
+
return formatTimeline(activities, options);
|
|
4281
|
+
}
|
|
4282
|
+
return formatGrouped(activities, options);
|
|
4283
|
+
}
|
|
4284
|
+
function formatGrouped(activities, options) {
|
|
4247
4285
|
const { since } = options;
|
|
4248
4286
|
const lines = [];
|
|
4249
4287
|
const sinceStr = formatRelativeDate(since);
|
|
@@ -4264,6 +4302,35 @@ function formatStandupText(activities, options) {
|
|
|
4264
4302
|
}
|
|
4265
4303
|
return lines.join("\n").trimEnd();
|
|
4266
4304
|
}
|
|
4305
|
+
function formatTimeline(activities, options) {
|
|
4306
|
+
const { since } = options;
|
|
4307
|
+
const lines = [];
|
|
4308
|
+
const allEvents = [];
|
|
4309
|
+
for (const activity of activities) {
|
|
4310
|
+
for (const event of activity.changes) {
|
|
4311
|
+
allEvents.push({ event, issue: activity.issue });
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
allEvents.sort(
|
|
4315
|
+
(a, b) => new Date(b.event.timestamp).getTime() - new Date(a.event.timestamp).getTime()
|
|
4316
|
+
);
|
|
4317
|
+
const sinceStr = formatRelativeDate(since);
|
|
4318
|
+
const eventCount = allEvents.length;
|
|
4319
|
+
const issueCount = activities.length;
|
|
4320
|
+
lines.push(`Since ${sinceStr} \u2014 ${eventCount} event${eventCount !== 1 ? "s" : ""} across ${issueCount} issue${issueCount !== 1 ? "s" : ""}`);
|
|
4321
|
+
lines.push("");
|
|
4322
|
+
if (allEvents.length === 0) {
|
|
4323
|
+
lines.push("No activity found in this time window.");
|
|
4324
|
+
return lines.join("\n");
|
|
4325
|
+
}
|
|
4326
|
+
for (const { event, issue } of allEvents) {
|
|
4327
|
+
const time = formatShortTimestamp(event.timestamp);
|
|
4328
|
+
const desc = formatEventDescription(event);
|
|
4329
|
+
const issueRef = `#${issue.number} ${truncate(issue.title, 50)}`;
|
|
4330
|
+
lines.push(`${time} ${desc} (${issueRef})`);
|
|
4331
|
+
}
|
|
4332
|
+
return lines.join("\n").trimEnd();
|
|
4333
|
+
}
|
|
4267
4334
|
function parseSince(input) {
|
|
4268
4335
|
const isoDate = new Date(input);
|
|
4269
4336
|
if (!isNaN(isoDate.getTime()) && input.includes("-")) {
|
|
@@ -4320,6 +4387,41 @@ function formatEventLine(event) {
|
|
|
4320
4387
|
return `${arrow} ${event.type} by ${actor} (${timestamp})`;
|
|
4321
4388
|
}
|
|
4322
4389
|
}
|
|
4390
|
+
function formatEventDescription(event) {
|
|
4391
|
+
const actor = event.actor;
|
|
4392
|
+
switch (event.type) {
|
|
4393
|
+
case "comment":
|
|
4394
|
+
return `Comment by ${actor}${event.details ? ": " + event.details : ""}`;
|
|
4395
|
+
case "labeled":
|
|
4396
|
+
return `Labeled "${event.details}" by ${actor}`;
|
|
4397
|
+
case "unlabeled":
|
|
4398
|
+
return `Unlabeled "${event.details}" by ${actor}`;
|
|
4399
|
+
case "assigned":
|
|
4400
|
+
return `Assigned to ${event.details || actor}`;
|
|
4401
|
+
case "unassigned":
|
|
4402
|
+
return `Unassigned ${event.details || ""} by ${actor}`;
|
|
4403
|
+
case "closed":
|
|
4404
|
+
return `Closed by ${actor}`;
|
|
4405
|
+
case "reopened":
|
|
4406
|
+
return `Reopened by ${actor}`;
|
|
4407
|
+
case "referenced":
|
|
4408
|
+
return `${event.details} linked by ${actor}`;
|
|
4409
|
+
case "review_submitted":
|
|
4410
|
+
return `${event.details} by ${actor}`;
|
|
4411
|
+
case "review_requested":
|
|
4412
|
+
return `Review requested from ${event.details || "team"} by ${actor}`;
|
|
4413
|
+
case "pr_created":
|
|
4414
|
+
return `PR created by ${actor}`;
|
|
4415
|
+
case "pr_merged":
|
|
4416
|
+
return `PR merged by ${actor}`;
|
|
4417
|
+
default:
|
|
4418
|
+
return `${event.type} by ${actor}`;
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
function truncate(str, maxLen) {
|
|
4422
|
+
if (str.length <= maxLen) return str;
|
|
4423
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
4424
|
+
}
|
|
4323
4425
|
function formatRelativeDate(date) {
|
|
4324
4426
|
const now = /* @__PURE__ */ new Date();
|
|
4325
4427
|
const diffMs = now.getTime() - date.getTime();
|
|
@@ -5854,6 +5956,7 @@ EOF
|
|
|
5854
5956
|
isGitRepository,
|
|
5855
5957
|
isTransientError,
|
|
5856
5958
|
listAgents,
|
|
5959
|
+
listTags,
|
|
5857
5960
|
listWorktrees,
|
|
5858
5961
|
loadEventHooksConfig,
|
|
5859
5962
|
loadHooksConfig,
|
|
@@ -5875,6 +5978,7 @@ EOF
|
|
|
5875
5978
|
removeWorktree,
|
|
5876
5979
|
removeWorktreeWorkflow,
|
|
5877
5980
|
resolveConflicts,
|
|
5981
|
+
resolveRef,
|
|
5878
5982
|
sanitizeForBranchName,
|
|
5879
5983
|
saveEventHooksConfig,
|
|
5880
5984
|
saveHooksConfig,
|
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.
|
|
@@ -789,9 +790,13 @@ declare function hasUncommittedChanges(options?: GitOptions): Promise<boolean>;
|
|
|
789
790
|
declare function branchExists(branchName: string, options?: GitOptions): Promise<boolean>;
|
|
790
791
|
/**
|
|
791
792
|
* Create and checkout a new branch.
|
|
793
|
+
* @param branchName - Name for the new branch
|
|
794
|
+
* @param options - Git options. Use `startPoint` to branch from a specific tag, commit, or ref.
|
|
792
795
|
* @throws {GitError} If the branch cannot be created (e.g., already exists, invalid name)
|
|
793
796
|
*/
|
|
794
|
-
declare function createBranch(branchName: string, options?: GitOptions
|
|
797
|
+
declare function createBranch(branchName: string, options?: GitOptions & {
|
|
798
|
+
startPoint?: string;
|
|
799
|
+
}): Promise<void>;
|
|
795
800
|
/**
|
|
796
801
|
* Checkout an existing branch.
|
|
797
802
|
* @throws {GitError} If the branch cannot be checked out (e.g., doesn't exist, uncommitted changes)
|
|
@@ -851,6 +856,19 @@ declare function generateBranchName(pattern: string, vars: {
|
|
|
851
856
|
* - ends with #123 or /123
|
|
852
857
|
*/
|
|
853
858
|
declare function extractIssueNumberFromBranch(branchName: string): number | null;
|
|
859
|
+
/**
|
|
860
|
+
* List git tags, sorted by version (highest version first, using semantic version ordering).
|
|
861
|
+
* @param options - Git options
|
|
862
|
+
* @returns Array of tag names, highest version first
|
|
863
|
+
*/
|
|
864
|
+
declare function listTags(options?: GitOptions): Promise<string[]>;
|
|
865
|
+
/**
|
|
866
|
+
* Verify that a git ref (tag, commit, branch) exists and resolve it to a commit hash.
|
|
867
|
+
* @param ref - Tag name, commit hash, or branch name
|
|
868
|
+
* @param options - Git options
|
|
869
|
+
* @returns The resolved commit hash, or null if the ref doesn't exist
|
|
870
|
+
*/
|
|
871
|
+
declare function resolveRef(ref: string, options?: GitOptions): Promise<string | null>;
|
|
854
872
|
/**
|
|
855
873
|
* Get all local branches.
|
|
856
874
|
* @throws {GitError} If the git command fails (e.g., not a git repo)
|
|
@@ -2283,6 +2301,8 @@ declare function validateUrl(url: string): string;
|
|
|
2283
2301
|
interface FormatStandupOptions {
|
|
2284
2302
|
since: Date;
|
|
2285
2303
|
colorize?: boolean;
|
|
2304
|
+
/** If true, show a flat chronological timeline instead of grouping by issue */
|
|
2305
|
+
timeline?: boolean;
|
|
2286
2306
|
}
|
|
2287
2307
|
/**
|
|
2288
2308
|
* Format a standup summary as human-readable text.
|
|
@@ -3331,4 +3351,4 @@ declare function shouldAbort(results: HookResult[]): boolean;
|
|
|
3331
3351
|
*/
|
|
3332
3352
|
declare function hasHooksForEvent(event: EventType): boolean;
|
|
3333
3353
|
|
|
3334
|
-
export { type ActivityEvent, type AgentInstance, type AgentRegistry, type AgentSessionStatus, type AgentStatus, type AgentSummary, type ApiKeyProvider, type AssigneeInfo, type AuthError, type BaseEventPayload, type BlockingIssue, type BlockingRelationships, type BranchDashboardData, BranchLinker, CLI_TO_VSCODE_MAP, ClaudeClient, type ClaudeClientOptions, type ClaudeResult, type ClaudeTool, type Collaborator, type Commit, type ConflictChoices, type ConflictResolution, type ContentBlock, type CreateIssueOptions, type CreateIssueResult, type CreatePROptions, type CreatePRResult, type CreateWorktreeOptions, type CreateWorktreeResult, DEFAULT_RETRY_CONFIG, DEFAULT_VALUES, type DashboardHook, type DashboardOptions, type DateFieldValue, type DiffStats, type EventHook, type EventHookSettings, type EventHooksConfig, type EventPayload, type EventType, type ExpandIssueOptions, type ExpandedIssue, type FieldInfo, type FieldValue, type FieldValueConnection, type FileChange, type FormatStandupOptions, GHP_TOOLS, type GeneratePRDescriptionOptions, GitError, GitHubAPI, type GitHubAPIOptions, type GitOptions, type HookExecutionOptions, type HookExecutionResult, type HookExitCodes, type HookItem, type HookMode, type HookOutcome, type HookResponse, type HookResult, type HooksConfig, type IssueActivity, type IssueCreatedPayload, type IssueDetails, type IssueReference, type IssueRelationships, type IssueStartedPayload, type IterationFieldValue, type LabelInfo, type Message, type NumberFieldValue, type OnFailureBehavior, type PRInfo, type PermissionPrompt, type PlanEpicOptions, type PlanEpicResult, type PrCreatedPayload, type PrCreatingPayload, type PrMergedPayload, type PrePrPayload, type Project, type ProjectConfig, type ProjectConventions, type ProjectItem, type ProjectItemContent, type ProjectItemsQueryResponse, type ProjectV2, type ProjectV2Field, type ProjectV2Item, type ProjectV2View, type ProjectWithViews, type ProjectsQueryResponse, type RegisterAgentOptions, type RelatedIssue, type RemoveWorktreeOptions, type RemoveWorktreeResult, type RepoInfo, type ResolvedClaudeConfig, type ResolvedSettings, type RetryConfig, SETTING_DISPLAY_NAMES, SYNCABLE_KEYS, type SessionEvent, SessionWatcher, type SettingConflict, type SettingsDiff, type SettingsSource, type SingleSelectFieldValue, type StartIssueOptions, type StartIssueResult, type StatusField, type StreamCallbacks, type StreamErrorEvent, type StreamEvent, type StreamEventBase, type StreamMessageCompleteEvent, type StreamOptions, type StreamTextEvent, type StreamToolInputDeltaEvent, type StreamToolUseCompleteEvent, type StreamToolUseStartEvent, type SyncableSettingKey, type SyncableSettings, TOOL_NAMES, type TextFieldValue, type TokenProvider, type TokenUsage, type ToolContext, type ToolHandler, type ToolHandlers, type UpdateAgentOptions, VSCODE_TO_CLI_MAP, type IssueInfo as WorkflowIssueInfo, type WorkflowResult, type WorktreeInfo as WorkflowWorktreeInfo, type WorktreeCreatedPayload, type WorktreeInfo$1 as WorktreeInfo, type WorktreeRemovedPayload, addEventHook, addHook, branchExists, buildConventionsContext, buildIssueUrl, buildOrgProjectUrl, buildProjectUrl, buildPullRequestUrl, buildRepoUrl, calculateBackoffDelay, checkTmuxForPermission, checkoutBranch, index as claudePrompts, cleanupStaleAgents, computeSettingsDiff, createBranch, createIssueWorkflow, createPRWorkflow, createSessionWatcher, createWorktree, createWorktreeWorkflow, detectRepository, disableEventHook, disableHook, enableEventHook, enableHook, executeAllHooks, executeEventHook, executeHook, executeHooksForEvent, extractIssueNumberFromBranch, fetchOrigin, findSessionFile, formatAction, formatConflict, formatStandupText, gatherDashboardData, generateBranchName, generateWorktreePath, getAgent, getAgentByIssue, getAgentSummaries, getAllBranches, getChangedFiles, getCommitHistory, getCommitsAhead, getCommitsBehind, getCurrentBranch$1 as getCurrentBranch, getCurrentBranch as getDashboardCurrentBranch, getDefaultBaseBranch, getDefaultBranch, getDiffStats, getDiffSummary, getEnabledEventHooks, getEnabledHooks, getEventHook, getEventHooks, getEventHooksConfigPath, getEventSettings, getFullDiff, getGitHubRepo, getHook, getHooks, getHooksByCategory, getHooksConfigPath, getHooksForEvent, getIssueReferenceText, getLocalBranches, getRegistryPath, getRemoteBranches, getRepositoryRoot, getTools, getValidEventTypes, getValidModes, getValidOnFailureBehaviors, getWorktreeForBranch, hasDifferences, hasHooksForEvent, hasUncommittedChanges, isGitRepository, isTransientError, listAgents, listWorktrees, loadEventHooksConfig, loadHooksConfig, loadProjectConventions, loadRegistry, normalizeVSCodeSettings, parseBranchLink, parseGitHubUrl, parseIssueUrl, parseRateLimitDelay, parseSessionLine, parseSince, pullLatest, queries, registerAgent, removeBranchLinkFromBody, removeEventHook, removeHook, removeWorktree, removeWorktreeWorkflow, resolveConflicts, sanitizeForBranchName, saveEventHooksConfig, saveHooksConfig, saveRegistry, setBranchLinkInBody, shellEscape, shouldAbort, skip, startIssueWorkflow, substituteTemplateVariables, toVSCodeSettings, unregisterAgent, updateAgent, updateEventHook, updateHook, useCli, useCustom, useVSCode, validateNumericInput, validateSafeString, validateUrl, withRetry, worktreeExists, wrapWithRetry };
|
|
3354
|
+
export { type ActivityEvent, type AgentInstance, type AgentRegistry, type AgentSessionStatus, type AgentStatus, type AgentSummary, type ApiKeyProvider, type AssigneeInfo, type AuthError, type BaseEventPayload, type BlockingIssue, type BlockingRelationships, type BranchDashboardData, BranchLinker, CLI_TO_VSCODE_MAP, ClaudeClient, type ClaudeClientOptions, type ClaudeResult, type ClaudeTool, type Collaborator, type Commit, type ConflictChoices, type ConflictResolution, type ContentBlock, type CreateIssueOptions, type CreateIssueResult, type CreatePROptions, type CreatePRResult, type CreateWorktreeOptions, type CreateWorktreeResult, DEFAULT_RETRY_CONFIG, DEFAULT_VALUES, type DashboardHook, type DashboardOptions, type DateFieldValue, type DiffStats, type EventHook, type EventHookSettings, type EventHooksConfig, type EventPayload, type EventType, type ExpandIssueOptions, type ExpandedIssue, type FieldInfo, type FieldValue, type FieldValueConnection, type FileChange, type FormatStandupOptions, GHP_TOOLS, type GeneratePRDescriptionOptions, GitError, GitHubAPI, type GitHubAPIOptions, type GitOptions, type HookExecutionOptions, type HookExecutionResult, type HookExitCodes, type HookItem, type HookMode, type HookOutcome, type HookResponse, type HookResult, type HooksConfig, type IssueActivity, type IssueCreatedPayload, type IssueDetails, type IssueReference, type IssueRelationships, type IssueStartedPayload, type IterationFieldValue, type LabelInfo, type Message, type NumberFieldValue, type OnFailureBehavior, type PRInfo, type PermissionPrompt, type PlanEpicOptions, type PlanEpicResult, type PrCreatedPayload, type PrCreatingPayload, type PrMergedPayload, type PrePrPayload, type Project, type ProjectConfig, type ProjectConventions, type ProjectItem, type ProjectItemContent, type ProjectItemsQueryResponse, type ProjectV2, type ProjectV2Field, type ProjectV2Item, type ProjectV2View, type ProjectWithViews, type ProjectsQueryResponse, type RegisterAgentOptions, type RelatedIssue, type RemoveWorktreeOptions, type RemoveWorktreeResult, type RepoInfo, type ResolvedClaudeConfig, type ResolvedSettings, type RetryConfig, SETTING_DISPLAY_NAMES, SYNCABLE_KEYS, type SessionEvent, SessionWatcher, type SettingConflict, type SettingsDiff, type SettingsSource, type SingleSelectFieldValue, type StartIssueOptions, type StartIssueResult, type StatusField, type StreamCallbacks, type StreamErrorEvent, type StreamEvent, type StreamEventBase, type StreamMessageCompleteEvent, type StreamOptions, type StreamTextEvent, type StreamToolInputDeltaEvent, type StreamToolUseCompleteEvent, type StreamToolUseStartEvent, type SyncableSettingKey, type SyncableSettings, TOOL_NAMES, type TextFieldValue, type TokenProvider, type TokenUsage, type ToolContext, type ToolHandler, type ToolHandlers, type UpdateAgentOptions, VSCODE_TO_CLI_MAP, type IssueInfo as WorkflowIssueInfo, type WorkflowResult, type WorktreeInfo as WorkflowWorktreeInfo, type WorktreeCreatedPayload, type WorktreeInfo$1 as WorktreeInfo, type WorktreeRemovedPayload, addEventHook, addHook, branchExists, buildConventionsContext, buildIssueUrl, buildOrgProjectUrl, buildProjectUrl, buildPullRequestUrl, buildRepoUrl, calculateBackoffDelay, checkTmuxForPermission, checkoutBranch, index as claudePrompts, cleanupStaleAgents, computeSettingsDiff, createBranch, createIssueWorkflow, createPRWorkflow, createSessionWatcher, createWorktree, createWorktreeWorkflow, detectRepository, disableEventHook, disableHook, enableEventHook, enableHook, executeAllHooks, executeEventHook, executeHook, executeHooksForEvent, extractIssueNumberFromBranch, fetchOrigin, findSessionFile, formatAction, formatConflict, formatStandupText, gatherDashboardData, generateBranchName, generateWorktreePath, getAgent, getAgentByIssue, getAgentSummaries, getAllBranches, getChangedFiles, getCommitHistory, getCommitsAhead, getCommitsBehind, getCurrentBranch$1 as getCurrentBranch, getCurrentBranch as getDashboardCurrentBranch, getDefaultBaseBranch, getDefaultBranch, getDiffStats, getDiffSummary, getEnabledEventHooks, getEnabledHooks, getEventHook, getEventHooks, getEventHooksConfigPath, getEventSettings, getFullDiff, getGitHubRepo, getHook, getHooks, getHooksByCategory, getHooksConfigPath, getHooksForEvent, getIssueReferenceText, getLocalBranches, getRegistryPath, getRemoteBranches, getRepositoryRoot, getTools, getValidEventTypes, getValidModes, getValidOnFailureBehaviors, getWorktreeForBranch, hasDifferences, hasHooksForEvent, hasUncommittedChanges, isGitRepository, isTransientError, listAgents, listTags, listWorktrees, loadEventHooksConfig, loadHooksConfig, loadProjectConventions, loadRegistry, normalizeVSCodeSettings, parseBranchLink, parseGitHubUrl, parseIssueUrl, parseRateLimitDelay, parseSessionLine, parseSince, pullLatest, queries, registerAgent, removeBranchLinkFromBody, removeEventHook, removeHook, removeWorktree, removeWorktreeWorkflow, resolveConflicts, resolveRef, sanitizeForBranchName, saveEventHooksConfig, saveHooksConfig, saveRegistry, setBranchLinkInBody, shellEscape, shouldAbort, skip, startIssueWorkflow, substituteTemplateVariables, toVSCodeSettings, unregisterAgent, updateAgent, updateEventHook, updateHook, useCli, useCustom, useVSCode, validateNumericInput, validateSafeString, validateUrl, withRetry, worktreeExists, wrapWithRetry };
|
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.
|
|
@@ -789,9 +790,13 @@ declare function hasUncommittedChanges(options?: GitOptions): Promise<boolean>;
|
|
|
789
790
|
declare function branchExists(branchName: string, options?: GitOptions): Promise<boolean>;
|
|
790
791
|
/**
|
|
791
792
|
* Create and checkout a new branch.
|
|
793
|
+
* @param branchName - Name for the new branch
|
|
794
|
+
* @param options - Git options. Use `startPoint` to branch from a specific tag, commit, or ref.
|
|
792
795
|
* @throws {GitError} If the branch cannot be created (e.g., already exists, invalid name)
|
|
793
796
|
*/
|
|
794
|
-
declare function createBranch(branchName: string, options?: GitOptions
|
|
797
|
+
declare function createBranch(branchName: string, options?: GitOptions & {
|
|
798
|
+
startPoint?: string;
|
|
799
|
+
}): Promise<void>;
|
|
795
800
|
/**
|
|
796
801
|
* Checkout an existing branch.
|
|
797
802
|
* @throws {GitError} If the branch cannot be checked out (e.g., doesn't exist, uncommitted changes)
|
|
@@ -851,6 +856,19 @@ declare function generateBranchName(pattern: string, vars: {
|
|
|
851
856
|
* - ends with #123 or /123
|
|
852
857
|
*/
|
|
853
858
|
declare function extractIssueNumberFromBranch(branchName: string): number | null;
|
|
859
|
+
/**
|
|
860
|
+
* List git tags, sorted by version (highest version first, using semantic version ordering).
|
|
861
|
+
* @param options - Git options
|
|
862
|
+
* @returns Array of tag names, highest version first
|
|
863
|
+
*/
|
|
864
|
+
declare function listTags(options?: GitOptions): Promise<string[]>;
|
|
865
|
+
/**
|
|
866
|
+
* Verify that a git ref (tag, commit, branch) exists and resolve it to a commit hash.
|
|
867
|
+
* @param ref - Tag name, commit hash, or branch name
|
|
868
|
+
* @param options - Git options
|
|
869
|
+
* @returns The resolved commit hash, or null if the ref doesn't exist
|
|
870
|
+
*/
|
|
871
|
+
declare function resolveRef(ref: string, options?: GitOptions): Promise<string | null>;
|
|
854
872
|
/**
|
|
855
873
|
* Get all local branches.
|
|
856
874
|
* @throws {GitError} If the git command fails (e.g., not a git repo)
|
|
@@ -2283,6 +2301,8 @@ declare function validateUrl(url: string): string;
|
|
|
2283
2301
|
interface FormatStandupOptions {
|
|
2284
2302
|
since: Date;
|
|
2285
2303
|
colorize?: boolean;
|
|
2304
|
+
/** If true, show a flat chronological timeline instead of grouping by issue */
|
|
2305
|
+
timeline?: boolean;
|
|
2286
2306
|
}
|
|
2287
2307
|
/**
|
|
2288
2308
|
* Format a standup summary as human-readable text.
|
|
@@ -3331,4 +3351,4 @@ declare function shouldAbort(results: HookResult[]): boolean;
|
|
|
3331
3351
|
*/
|
|
3332
3352
|
declare function hasHooksForEvent(event: EventType): boolean;
|
|
3333
3353
|
|
|
3334
|
-
export { type ActivityEvent, type AgentInstance, type AgentRegistry, type AgentSessionStatus, type AgentStatus, type AgentSummary, type ApiKeyProvider, type AssigneeInfo, type AuthError, type BaseEventPayload, type BlockingIssue, type BlockingRelationships, type BranchDashboardData, BranchLinker, CLI_TO_VSCODE_MAP, ClaudeClient, type ClaudeClientOptions, type ClaudeResult, type ClaudeTool, type Collaborator, type Commit, type ConflictChoices, type ConflictResolution, type ContentBlock, type CreateIssueOptions, type CreateIssueResult, type CreatePROptions, type CreatePRResult, type CreateWorktreeOptions, type CreateWorktreeResult, DEFAULT_RETRY_CONFIG, DEFAULT_VALUES, type DashboardHook, type DashboardOptions, type DateFieldValue, type DiffStats, type EventHook, type EventHookSettings, type EventHooksConfig, type EventPayload, type EventType, type ExpandIssueOptions, type ExpandedIssue, type FieldInfo, type FieldValue, type FieldValueConnection, type FileChange, type FormatStandupOptions, GHP_TOOLS, type GeneratePRDescriptionOptions, GitError, GitHubAPI, type GitHubAPIOptions, type GitOptions, type HookExecutionOptions, type HookExecutionResult, type HookExitCodes, type HookItem, type HookMode, type HookOutcome, type HookResponse, type HookResult, type HooksConfig, type IssueActivity, type IssueCreatedPayload, type IssueDetails, type IssueReference, type IssueRelationships, type IssueStartedPayload, type IterationFieldValue, type LabelInfo, type Message, type NumberFieldValue, type OnFailureBehavior, type PRInfo, type PermissionPrompt, type PlanEpicOptions, type PlanEpicResult, type PrCreatedPayload, type PrCreatingPayload, type PrMergedPayload, type PrePrPayload, type Project, type ProjectConfig, type ProjectConventions, type ProjectItem, type ProjectItemContent, type ProjectItemsQueryResponse, type ProjectV2, type ProjectV2Field, type ProjectV2Item, type ProjectV2View, type ProjectWithViews, type ProjectsQueryResponse, type RegisterAgentOptions, type RelatedIssue, type RemoveWorktreeOptions, type RemoveWorktreeResult, type RepoInfo, type ResolvedClaudeConfig, type ResolvedSettings, type RetryConfig, SETTING_DISPLAY_NAMES, SYNCABLE_KEYS, type SessionEvent, SessionWatcher, type SettingConflict, type SettingsDiff, type SettingsSource, type SingleSelectFieldValue, type StartIssueOptions, type StartIssueResult, type StatusField, type StreamCallbacks, type StreamErrorEvent, type StreamEvent, type StreamEventBase, type StreamMessageCompleteEvent, type StreamOptions, type StreamTextEvent, type StreamToolInputDeltaEvent, type StreamToolUseCompleteEvent, type StreamToolUseStartEvent, type SyncableSettingKey, type SyncableSettings, TOOL_NAMES, type TextFieldValue, type TokenProvider, type TokenUsage, type ToolContext, type ToolHandler, type ToolHandlers, type UpdateAgentOptions, VSCODE_TO_CLI_MAP, type IssueInfo as WorkflowIssueInfo, type WorkflowResult, type WorktreeInfo as WorkflowWorktreeInfo, type WorktreeCreatedPayload, type WorktreeInfo$1 as WorktreeInfo, type WorktreeRemovedPayload, addEventHook, addHook, branchExists, buildConventionsContext, buildIssueUrl, buildOrgProjectUrl, buildProjectUrl, buildPullRequestUrl, buildRepoUrl, calculateBackoffDelay, checkTmuxForPermission, checkoutBranch, index as claudePrompts, cleanupStaleAgents, computeSettingsDiff, createBranch, createIssueWorkflow, createPRWorkflow, createSessionWatcher, createWorktree, createWorktreeWorkflow, detectRepository, disableEventHook, disableHook, enableEventHook, enableHook, executeAllHooks, executeEventHook, executeHook, executeHooksForEvent, extractIssueNumberFromBranch, fetchOrigin, findSessionFile, formatAction, formatConflict, formatStandupText, gatherDashboardData, generateBranchName, generateWorktreePath, getAgent, getAgentByIssue, getAgentSummaries, getAllBranches, getChangedFiles, getCommitHistory, getCommitsAhead, getCommitsBehind, getCurrentBranch$1 as getCurrentBranch, getCurrentBranch as getDashboardCurrentBranch, getDefaultBaseBranch, getDefaultBranch, getDiffStats, getDiffSummary, getEnabledEventHooks, getEnabledHooks, getEventHook, getEventHooks, getEventHooksConfigPath, getEventSettings, getFullDiff, getGitHubRepo, getHook, getHooks, getHooksByCategory, getHooksConfigPath, getHooksForEvent, getIssueReferenceText, getLocalBranches, getRegistryPath, getRemoteBranches, getRepositoryRoot, getTools, getValidEventTypes, getValidModes, getValidOnFailureBehaviors, getWorktreeForBranch, hasDifferences, hasHooksForEvent, hasUncommittedChanges, isGitRepository, isTransientError, listAgents, listWorktrees, loadEventHooksConfig, loadHooksConfig, loadProjectConventions, loadRegistry, normalizeVSCodeSettings, parseBranchLink, parseGitHubUrl, parseIssueUrl, parseRateLimitDelay, parseSessionLine, parseSince, pullLatest, queries, registerAgent, removeBranchLinkFromBody, removeEventHook, removeHook, removeWorktree, removeWorktreeWorkflow, resolveConflicts, sanitizeForBranchName, saveEventHooksConfig, saveHooksConfig, saveRegistry, setBranchLinkInBody, shellEscape, shouldAbort, skip, startIssueWorkflow, substituteTemplateVariables, toVSCodeSettings, unregisterAgent, updateAgent, updateEventHook, updateHook, useCli, useCustom, useVSCode, validateNumericInput, validateSafeString, validateUrl, withRetry, worktreeExists, wrapWithRetry };
|
|
3354
|
+
export { type ActivityEvent, type AgentInstance, type AgentRegistry, type AgentSessionStatus, type AgentStatus, type AgentSummary, type ApiKeyProvider, type AssigneeInfo, type AuthError, type BaseEventPayload, type BlockingIssue, type BlockingRelationships, type BranchDashboardData, BranchLinker, CLI_TO_VSCODE_MAP, ClaudeClient, type ClaudeClientOptions, type ClaudeResult, type ClaudeTool, type Collaborator, type Commit, type ConflictChoices, type ConflictResolution, type ContentBlock, type CreateIssueOptions, type CreateIssueResult, type CreatePROptions, type CreatePRResult, type CreateWorktreeOptions, type CreateWorktreeResult, DEFAULT_RETRY_CONFIG, DEFAULT_VALUES, type DashboardHook, type DashboardOptions, type DateFieldValue, type DiffStats, type EventHook, type EventHookSettings, type EventHooksConfig, type EventPayload, type EventType, type ExpandIssueOptions, type ExpandedIssue, type FieldInfo, type FieldValue, type FieldValueConnection, type FileChange, type FormatStandupOptions, GHP_TOOLS, type GeneratePRDescriptionOptions, GitError, GitHubAPI, type GitHubAPIOptions, type GitOptions, type HookExecutionOptions, type HookExecutionResult, type HookExitCodes, type HookItem, type HookMode, type HookOutcome, type HookResponse, type HookResult, type HooksConfig, type IssueActivity, type IssueCreatedPayload, type IssueDetails, type IssueReference, type IssueRelationships, type IssueStartedPayload, type IterationFieldValue, type LabelInfo, type Message, type NumberFieldValue, type OnFailureBehavior, type PRInfo, type PermissionPrompt, type PlanEpicOptions, type PlanEpicResult, type PrCreatedPayload, type PrCreatingPayload, type PrMergedPayload, type PrePrPayload, type Project, type ProjectConfig, type ProjectConventions, type ProjectItem, type ProjectItemContent, type ProjectItemsQueryResponse, type ProjectV2, type ProjectV2Field, type ProjectV2Item, type ProjectV2View, type ProjectWithViews, type ProjectsQueryResponse, type RegisterAgentOptions, type RelatedIssue, type RemoveWorktreeOptions, type RemoveWorktreeResult, type RepoInfo, type ResolvedClaudeConfig, type ResolvedSettings, type RetryConfig, SETTING_DISPLAY_NAMES, SYNCABLE_KEYS, type SessionEvent, SessionWatcher, type SettingConflict, type SettingsDiff, type SettingsSource, type SingleSelectFieldValue, type StartIssueOptions, type StartIssueResult, type StatusField, type StreamCallbacks, type StreamErrorEvent, type StreamEvent, type StreamEventBase, type StreamMessageCompleteEvent, type StreamOptions, type StreamTextEvent, type StreamToolInputDeltaEvent, type StreamToolUseCompleteEvent, type StreamToolUseStartEvent, type SyncableSettingKey, type SyncableSettings, TOOL_NAMES, type TextFieldValue, type TokenProvider, type TokenUsage, type ToolContext, type ToolHandler, type ToolHandlers, type UpdateAgentOptions, VSCODE_TO_CLI_MAP, type IssueInfo as WorkflowIssueInfo, type WorkflowResult, type WorktreeInfo as WorkflowWorktreeInfo, type WorktreeCreatedPayload, type WorktreeInfo$1 as WorktreeInfo, type WorktreeRemovedPayload, addEventHook, addHook, branchExists, buildConventionsContext, buildIssueUrl, buildOrgProjectUrl, buildProjectUrl, buildPullRequestUrl, buildRepoUrl, calculateBackoffDelay, checkTmuxForPermission, checkoutBranch, index as claudePrompts, cleanupStaleAgents, computeSettingsDiff, createBranch, createIssueWorkflow, createPRWorkflow, createSessionWatcher, createWorktree, createWorktreeWorkflow, detectRepository, disableEventHook, disableHook, enableEventHook, enableHook, executeAllHooks, executeEventHook, executeHook, executeHooksForEvent, extractIssueNumberFromBranch, fetchOrigin, findSessionFile, formatAction, formatConflict, formatStandupText, gatherDashboardData, generateBranchName, generateWorktreePath, getAgent, getAgentByIssue, getAgentSummaries, getAllBranches, getChangedFiles, getCommitHistory, getCommitsAhead, getCommitsBehind, getCurrentBranch$1 as getCurrentBranch, getCurrentBranch as getDashboardCurrentBranch, getDefaultBaseBranch, getDefaultBranch, getDiffStats, getDiffSummary, getEnabledEventHooks, getEnabledHooks, getEventHook, getEventHooks, getEventHooksConfigPath, getEventSettings, getFullDiff, getGitHubRepo, getHook, getHooks, getHooksByCategory, getHooksConfigPath, getHooksForEvent, getIssueReferenceText, getLocalBranches, getRegistryPath, getRemoteBranches, getRepositoryRoot, getTools, getValidEventTypes, getValidModes, getValidOnFailureBehaviors, getWorktreeForBranch, hasDifferences, hasHooksForEvent, hasUncommittedChanges, isGitRepository, isTransientError, listAgents, listTags, listWorktrees, loadEventHooksConfig, loadHooksConfig, loadProjectConventions, loadRegistry, normalizeVSCodeSettings, parseBranchLink, parseGitHubUrl, parseIssueUrl, parseRateLimitDelay, parseSessionLine, parseSince, pullLatest, queries, registerAgent, removeBranchLinkFromBody, removeEventHook, removeHook, removeWorktree, removeWorktreeWorkflow, resolveConflicts, resolveRef, sanitizeForBranchName, saveEventHooksConfig, saveHooksConfig, saveRegistry, setBranchLinkInBody, shellEscape, shouldAbort, skip, startIssueWorkflow, substituteTemplateVariables, toVSCodeSettings, unregisterAgent, updateAgent, updateEventHook, updateHook, useCli, useCustom, useVSCode, validateNumericInput, validateSafeString, validateUrl, withRetry, worktreeExists, wrapWithRetry };
|
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
|
|
@@ -2164,6 +2164,15 @@ function buildOrgProjectUrl(org, projectNumber) {
|
|
|
2164
2164
|
function sanitizeForPath(input) {
|
|
2165
2165
|
return String(input).replace(/\.\./g, "_").replace(/[;&|`$(){}[\]<>!]/g, "").replace(/\s+/g, "-").replace(/[^a-zA-Z0-9_\-./]/g, "_");
|
|
2166
2166
|
}
|
|
2167
|
+
function validateRefString(ref) {
|
|
2168
|
+
if (!ref || ref.trim().length === 0) {
|
|
2169
|
+
throw new Error("Ref cannot be empty");
|
|
2170
|
+
}
|
|
2171
|
+
const dangerousChars = /[`$\\!;|&<>(){}[\]'"]/;
|
|
2172
|
+
if (dangerousChars.test(ref)) {
|
|
2173
|
+
throw new Error(`Ref contains invalid characters: ${ref}`);
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2167
2176
|
function validateBranchName(branch) {
|
|
2168
2177
|
if (!branch || branch.trim().length === 0) {
|
|
2169
2178
|
throw new Error("Branch name cannot be empty");
|
|
@@ -2224,7 +2233,11 @@ async function branchExists(branchName, options = {}) {
|
|
|
2224
2233
|
}
|
|
2225
2234
|
}
|
|
2226
2235
|
async function createBranch(branchName, options = {}) {
|
|
2227
|
-
|
|
2236
|
+
if (options.startPoint) {
|
|
2237
|
+
validateRefString(options.startPoint);
|
|
2238
|
+
}
|
|
2239
|
+
const cmd = options.startPoint ? `git checkout -b "${branchName}" "${options.startPoint}"` : `git checkout -b "${branchName}"`;
|
|
2240
|
+
await execGit(cmd, options);
|
|
2228
2241
|
}
|
|
2229
2242
|
async function checkoutBranch(branchName, options = {}) {
|
|
2230
2243
|
await execGit(`git checkout "${branchName}"`, options);
|
|
@@ -2296,6 +2309,23 @@ function extractIssueNumberFromBranch(branchName) {
|
|
|
2296
2309
|
}
|
|
2297
2310
|
return null;
|
|
2298
2311
|
}
|
|
2312
|
+
async function listTags(options = {}) {
|
|
2313
|
+
try {
|
|
2314
|
+
const { stdout } = await execGit("git tag -l --sort=-version:refname", options);
|
|
2315
|
+
return stdout.split("\n").filter(Boolean);
|
|
2316
|
+
} catch {
|
|
2317
|
+
return [];
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
async function resolveRef(ref, options = {}) {
|
|
2321
|
+
validateRefString(ref);
|
|
2322
|
+
try {
|
|
2323
|
+
const { stdout } = await execGit(`git rev-parse --verify "${ref}"`, options);
|
|
2324
|
+
return stdout.trim();
|
|
2325
|
+
} catch {
|
|
2326
|
+
return null;
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2299
2329
|
async function getLocalBranches(options = {}) {
|
|
2300
2330
|
const { stdout } = await execGit('git branch --format="%(refname:short)"', options);
|
|
2301
2331
|
return stdout.split("\n").map((b) => b.trim()).filter((b) => b.length > 0);
|
|
@@ -4075,6 +4105,12 @@ function validateUrl(url) {
|
|
|
4075
4105
|
|
|
4076
4106
|
// src/standup.ts
|
|
4077
4107
|
function formatStandupText(activities, options) {
|
|
4108
|
+
if (options.timeline) {
|
|
4109
|
+
return formatTimeline(activities, options);
|
|
4110
|
+
}
|
|
4111
|
+
return formatGrouped(activities, options);
|
|
4112
|
+
}
|
|
4113
|
+
function formatGrouped(activities, options) {
|
|
4078
4114
|
const { since } = options;
|
|
4079
4115
|
const lines = [];
|
|
4080
4116
|
const sinceStr = formatRelativeDate(since);
|
|
@@ -4095,6 +4131,35 @@ function formatStandupText(activities, options) {
|
|
|
4095
4131
|
}
|
|
4096
4132
|
return lines.join("\n").trimEnd();
|
|
4097
4133
|
}
|
|
4134
|
+
function formatTimeline(activities, options) {
|
|
4135
|
+
const { since } = options;
|
|
4136
|
+
const lines = [];
|
|
4137
|
+
const allEvents = [];
|
|
4138
|
+
for (const activity of activities) {
|
|
4139
|
+
for (const event of activity.changes) {
|
|
4140
|
+
allEvents.push({ event, issue: activity.issue });
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
allEvents.sort(
|
|
4144
|
+
(a, b) => new Date(b.event.timestamp).getTime() - new Date(a.event.timestamp).getTime()
|
|
4145
|
+
);
|
|
4146
|
+
const sinceStr = formatRelativeDate(since);
|
|
4147
|
+
const eventCount = allEvents.length;
|
|
4148
|
+
const issueCount = activities.length;
|
|
4149
|
+
lines.push(`Since ${sinceStr} \u2014 ${eventCount} event${eventCount !== 1 ? "s" : ""} across ${issueCount} issue${issueCount !== 1 ? "s" : ""}`);
|
|
4150
|
+
lines.push("");
|
|
4151
|
+
if (allEvents.length === 0) {
|
|
4152
|
+
lines.push("No activity found in this time window.");
|
|
4153
|
+
return lines.join("\n");
|
|
4154
|
+
}
|
|
4155
|
+
for (const { event, issue } of allEvents) {
|
|
4156
|
+
const time = formatShortTimestamp(event.timestamp);
|
|
4157
|
+
const desc = formatEventDescription(event);
|
|
4158
|
+
const issueRef = `#${issue.number} ${truncate(issue.title, 50)}`;
|
|
4159
|
+
lines.push(`${time} ${desc} (${issueRef})`);
|
|
4160
|
+
}
|
|
4161
|
+
return lines.join("\n").trimEnd();
|
|
4162
|
+
}
|
|
4098
4163
|
function parseSince(input) {
|
|
4099
4164
|
const isoDate = new Date(input);
|
|
4100
4165
|
if (!isNaN(isoDate.getTime()) && input.includes("-")) {
|
|
@@ -4151,6 +4216,41 @@ function formatEventLine(event) {
|
|
|
4151
4216
|
return `${arrow} ${event.type} by ${actor} (${timestamp})`;
|
|
4152
4217
|
}
|
|
4153
4218
|
}
|
|
4219
|
+
function formatEventDescription(event) {
|
|
4220
|
+
const actor = event.actor;
|
|
4221
|
+
switch (event.type) {
|
|
4222
|
+
case "comment":
|
|
4223
|
+
return `Comment by ${actor}${event.details ? ": " + event.details : ""}`;
|
|
4224
|
+
case "labeled":
|
|
4225
|
+
return `Labeled "${event.details}" by ${actor}`;
|
|
4226
|
+
case "unlabeled":
|
|
4227
|
+
return `Unlabeled "${event.details}" by ${actor}`;
|
|
4228
|
+
case "assigned":
|
|
4229
|
+
return `Assigned to ${event.details || actor}`;
|
|
4230
|
+
case "unassigned":
|
|
4231
|
+
return `Unassigned ${event.details || ""} by ${actor}`;
|
|
4232
|
+
case "closed":
|
|
4233
|
+
return `Closed by ${actor}`;
|
|
4234
|
+
case "reopened":
|
|
4235
|
+
return `Reopened by ${actor}`;
|
|
4236
|
+
case "referenced":
|
|
4237
|
+
return `${event.details} linked by ${actor}`;
|
|
4238
|
+
case "review_submitted":
|
|
4239
|
+
return `${event.details} by ${actor}`;
|
|
4240
|
+
case "review_requested":
|
|
4241
|
+
return `Review requested from ${event.details || "team"} by ${actor}`;
|
|
4242
|
+
case "pr_created":
|
|
4243
|
+
return `PR created by ${actor}`;
|
|
4244
|
+
case "pr_merged":
|
|
4245
|
+
return `PR merged by ${actor}`;
|
|
4246
|
+
default:
|
|
4247
|
+
return `${event.type} by ${actor}`;
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
function truncate(str, maxLen) {
|
|
4251
|
+
if (str.length <= maxLen) return str;
|
|
4252
|
+
return str.slice(0, maxLen - 1) + "\u2026";
|
|
4253
|
+
}
|
|
4154
4254
|
function formatRelativeDate(date) {
|
|
4155
4255
|
const now = /* @__PURE__ */ new Date();
|
|
4156
4256
|
const diffMs = now.getTime() - date.getTime();
|
|
@@ -5684,6 +5784,7 @@ export {
|
|
|
5684
5784
|
isGitRepository,
|
|
5685
5785
|
isTransientError,
|
|
5686
5786
|
listAgents,
|
|
5787
|
+
listTags,
|
|
5687
5788
|
listWorktrees,
|
|
5688
5789
|
loadEventHooksConfig,
|
|
5689
5790
|
loadHooksConfig,
|
|
@@ -5705,6 +5806,7 @@ export {
|
|
|
5705
5806
|
removeWorktree,
|
|
5706
5807
|
removeWorktreeWorkflow,
|
|
5707
5808
|
resolveConflicts,
|
|
5809
|
+
resolveRef,
|
|
5708
5810
|
sanitizeForBranchName,
|
|
5709
5811
|
saveEventHooksConfig,
|
|
5710
5812
|
saveHooksConfig,
|