@bretwardjames/ghp-core 0.8.0 → 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 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,
@@ -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
- await execGit(`git checkout -b "${branchName}"`, options);
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);
@@ -5924,6 +5956,7 @@ EOF
5924
5956
  isGitRepository,
5925
5957
  isTransientError,
5926
5958
  listAgents,
5959
+ listTags,
5927
5960
  listWorktrees,
5928
5961
  loadEventHooksConfig,
5929
5962
  loadHooksConfig,
@@ -5945,6 +5978,7 @@ EOF
5945
5978
  removeWorktree,
5946
5979
  removeWorktreeWorkflow,
5947
5980
  resolveConflicts,
5981
+ resolveRef,
5948
5982
  sanitizeForBranchName,
5949
5983
  saveEventHooksConfig,
5950
5984
  saveHooksConfig,
package/dist/index.d.cts CHANGED
@@ -790,9 +790,13 @@ declare function hasUncommittedChanges(options?: GitOptions): Promise<boolean>;
790
790
  declare function branchExists(branchName: string, options?: GitOptions): Promise<boolean>;
791
791
  /**
792
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.
793
795
  * @throws {GitError} If the branch cannot be created (e.g., already exists, invalid name)
794
796
  */
795
- declare function createBranch(branchName: string, options?: GitOptions): Promise<void>;
797
+ declare function createBranch(branchName: string, options?: GitOptions & {
798
+ startPoint?: string;
799
+ }): Promise<void>;
796
800
  /**
797
801
  * Checkout an existing branch.
798
802
  * @throws {GitError} If the branch cannot be checked out (e.g., doesn't exist, uncommitted changes)
@@ -852,6 +856,19 @@ declare function generateBranchName(pattern: string, vars: {
852
856
  * - ends with #123 or /123
853
857
  */
854
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>;
855
872
  /**
856
873
  * Get all local branches.
857
874
  * @throws {GitError} If the git command fails (e.g., not a git repo)
@@ -3334,4 +3351,4 @@ declare function shouldAbort(results: HookResult[]): boolean;
3334
3351
  */
3335
3352
  declare function hasHooksForEvent(event: EventType): boolean;
3336
3353
 
3337
- 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
@@ -790,9 +790,13 @@ declare function hasUncommittedChanges(options?: GitOptions): Promise<boolean>;
790
790
  declare function branchExists(branchName: string, options?: GitOptions): Promise<boolean>;
791
791
  /**
792
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.
793
795
  * @throws {GitError} If the branch cannot be created (e.g., already exists, invalid name)
794
796
  */
795
- declare function createBranch(branchName: string, options?: GitOptions): Promise<void>;
797
+ declare function createBranch(branchName: string, options?: GitOptions & {
798
+ startPoint?: string;
799
+ }): Promise<void>;
796
800
  /**
797
801
  * Checkout an existing branch.
798
802
  * @throws {GitError} If the branch cannot be checked out (e.g., doesn't exist, uncommitted changes)
@@ -852,6 +856,19 @@ declare function generateBranchName(pattern: string, vars: {
852
856
  * - ends with #123 or /123
853
857
  */
854
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>;
855
872
  /**
856
873
  * Get all local branches.
857
874
  * @throws {GitError} If the git command fails (e.g., not a git repo)
@@ -3334,4 +3351,4 @@ declare function shouldAbort(results: HookResult[]): boolean;
3334
3351
  */
3335
3352
  declare function hasHooksForEvent(event: EventType): boolean;
3336
3353
 
3337
- 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
@@ -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
- await execGit(`git checkout -b "${branchName}"`, options);
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);
@@ -5754,6 +5784,7 @@ export {
5754
5784
  isGitRepository,
5755
5785
  isTransientError,
5756
5786
  listAgents,
5787
+ listTags,
5757
5788
  listWorktrees,
5758
5789
  loadEventHooksConfig,
5759
5790
  loadHooksConfig,
@@ -5775,6 +5806,7 @@ export {
5775
5806
  removeWorktree,
5776
5807
  removeWorktreeWorkflow,
5777
5808
  resolveConflicts,
5809
+ resolveRef,
5778
5810
  sanitizeForBranchName,
5779
5811
  saveEventHooksConfig,
5780
5812
  saveHooksConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bretwardjames/ghp-core",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Shared core library for GitHub Projects tools",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",