
Security News
PHP Foundation Says Chainguard Broke Security Embargo Ahead of Emergency Patches
The PHP Foundation says Chainguard broke a security embargo ahead of critical RCE patches, as leaks disrupted the coordinated release.
@forge-glance/sdk
Advanced tools
GitHub & GitLab API client — REST, GraphQL, and real-time ActionCable subscriptions
Provider-agnostic SDK for GitHub & GitLab — types, REST/GraphQL clients, real-time subscriptions, and dashboard helpers. Works in any Node/Bun runtime.
npm install @forge-glance/sdk
# or
bun add @forge-glance/sdk
import { GitLabProvider } from '@forge-glance/sdk';
const provider = new GitLabProvider('https://gitlab.com', process.env.GITLAB_TOKEN!);
const user = await provider.validateToken();
const prs = await provider.fetchPullRequests();
Two built-in providers implement the GitProvider interface:
| Provider | Class | Capabilities |
|---|---|---|
| GitLab | GitLabProvider | Full: merge, rebase, approve, auto-merge, retry pipeline, re-review |
| GitHub | GitHubProvider | Core: merge, approve, rebase |
import { createProvider } from '@forge-glance/sdk';
// Auto-create the right provider by slug
const provider = createProvider('gitlab', 'https://gitlab.com', token);
| Method | Description |
|---|---|
validateToken() | Verify credentials, returns UserRef |
fetchPullRequests() | Fetch all MRs you authored, review, or are assigned to |
fetchSingleMR(path, iid, userId) | Fetch one MR by project path and IID |
fetchPullRequestByBranch(path, branch) | Find an open MR by source branch |
createPullRequest(input) | Create a new MR |
updatePullRequest(path, iid, input) | Update an existing MR |
mergePullRequest(path, iid, input?) | Merge an MR |
rebasePullRequest(path, iid) | Rebase an MR onto its target branch |
approvePullRequest(path, iid) | Approve an MR |
unapprovePullRequest(path, iid) | Remove your approval |
setAutoMerge(path, iid) | Enable auto-merge when pipeline passes |
cancelAutoMerge(path, iid) | Cancel auto-merge |
retryPipeline(path, pipelineId) | Retry a pipeline |
requestReReview(path, iid, usernames?) | Request re-review |
watchMR(path, iid, userId, onUpdate) | Real-time MR subscription (returns dispose()) |
fetchMRDiscussions(repoId, iid) | Fetch MR discussions and notes |
fetchBranchProtectionRules(path) | Fetch branch protection rules |
deleteBranch(path, branch) | Delete a branch |
createDashboardHigh-level factory that bundles real-time MR watching with pre-bound mutation actions. Returns a Dashboard object:
import { createDashboard } from '@forge-glance/sdk';
const { actions, subscribe, dispose } = createDashboard({
provider,
projectPath: 'group/project',
mrIid: 42,
userId
});
// actions are available immediately — no need to wait for the first update
await actions.merge();
await actions.approve();
// subscribe delivers real-time MRDashboardProps on each update
subscribe((mr) => {
console.log(mr.status, mr.pipeline?.status);
renderUI(mr, actions);
});
// When done, stop the subscription
dispose();
| Property | Type | Description |
|---|---|---|
actions | MRDashboardActions | Pre-bound mutation methods — available immediately |
subscribe(cb) | (cb: (mr: MRDashboardProps) => void) => void | Register a listener for real-time updates |
dispose() | () => void | Stop the subscription and clean up |
DashboardGroupPass an array of IIDs to watch multiple MRs over a single WebSocket:
const { actionsFor, subscribe, dispose } = createDashboard({
provider,
projectPath: 'group/project',
mrIid: [42, 43, 44, 45],
userId
});
subscribe((mrs) => {
for (const [iid, mr] of mrs) {
renderRow(mr, actionsFor(iid));
}
});
| Property | Type | Description |
|---|---|---|
actionsFor(iid) | (iid: number) => MRDashboardActions | Get actions for a specific MR |
subscribe(cb) | (cb: (mrs: Map<number, MRDashboardProps>) => void) => void | Real-time updates for all MRs |
dispose() | () => void | Stop all subscriptions |
getMRDashboardPropsLower-level helper that transforms a raw PullRequest into render-ready MRDashboardProps. Useful when you already have the MR data from fetchPullRequests() or fetchSingleMR():
import { getMRDashboardProps } from '@forge-glance/sdk';
const prs = await provider.fetchPullRequests();
const dashboards = prs.map(getMRDashboardProps);
// dashboards[0].status → 'mergeable' | 'blocked' | 'draft' | ...
// dashboards[0].mergeButton.visible, .disabled, .label
// dashboards[0].provider → 'gitlab' | 'github'
MRDashboardPropsPre-computed, UI-ready props — no conditional logic needed in the component layer:
| Field | Description |
|---|---|
provider | 'gitlab' or 'github' — use to pick brand icon |
iid, title, webUrl, state | Identity |
status | 'mergeable' | 'blocked' | 'draft' | 'merged' | 'closed' |
statusDetail | Specific blocker reason (e.g., 'CI_MUST_PASS', 'NEED_REBASE') |
pipeline | Pipeline status breakdown: passing, failing, running counts |
reviews | Reviewer state: required, given, remaining, approvedBy |
mergeButton | { visible, disabled, loading, label } |
rebaseButton | { visible, loading, label, behindBy } |
autoMergeButton | { visible, isActive, strategy, label, cancelLabel } |
blockers | Boolean flags: isDraft, hasConflicts, needsRebase, pipelineFailing, etc. |
diff | { additions, deletions, filesChanged } |
MRDashboardActionsPre-bound mutation methods — call without passing project path or IID:
| Action | Description |
|---|---|
merge(input?) | Merge the MR |
rebase() | Rebase onto target branch |
approve() | Approve the MR |
unapprove() | Remove approval |
setAutoMerge() | Enable auto-merge |
cancelAutoMerge() | Cancel auto-merge |
retryPipeline(id) | Retry a pipeline |
requestReReview(usernames?) | Request re-review |
can | Provider capability flags |
All watchMR calls on a single GitLabProvider instance share one WebSocket connection via ActionCable. Each MR subscribes 3 channels (merge status, approval state, reviewers) on the shared connection. The connection is ref-counted:
watchMR call → opens the WebSocketdispose() a watcher → unsubscribes that MR's channelsThis means watching 30 MRs uses 1 WebSocket with 90 channel subscriptions, not 30 separate connections.
createRealtimeWatcherGeneric self-healing subscription + polling module used internally by watchMR. Also exported for custom use:
All domain types are exported:
import type {
PullRequest,
MRDashboardProps,
MRDashboardActions,
Dashboard,
MRStatus,
Reviewer,
Pipeline,
PipelineJob,
DiffStats,
GitProvider,
ProviderCapabilities,
} from '@forge-glance/sdk';
FAQs
GitHub & GitLab API client — REST, GraphQL, and real-time ActionCable subscriptions
The npm package @forge-glance/sdk receives a total of 0 weekly downloads. As such, @forge-glance/sdk popularity was classified as not popular.
We found that @forge-glance/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
The PHP Foundation says Chainguard broke a security embargo ahead of critical RCE patches, as leaks disrupted the coordinated release.

Security News
PHP releases emergency patches for two critical RCE vulnerabilities as agencies urge organizations to take unpatched sites offline.

Threat Research
/Security News
A supply chain attack compromised LiteLLM 1.107.0 on PyPI and Docker, spreading malware that steals cloud credentials, developer secrets, and AI provider keys.