agent-relay 6.0.10 → 6.0.12
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
CHANGED
|
@@ -5411,8 +5411,8 @@ var require_ignore = __commonJS({
|
|
|
5411
5411
|
(prev, [matcher, replacer]) => prev.replace(matcher, replacer.bind(pattern)),
|
|
5412
5412
|
pattern
|
|
5413
5413
|
);
|
|
5414
|
-
var
|
|
5415
|
-
var checkPattern = (pattern) => pattern &&
|
|
5414
|
+
var isString2 = (subject) => typeof subject === "string";
|
|
5415
|
+
var checkPattern = (pattern) => pattern && isString2(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0;
|
|
5416
5416
|
var splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
|
|
5417
5417
|
var IgnoreRule = class {
|
|
5418
5418
|
constructor(pattern, mark, body, ignoreCase, negative, prefix) {
|
|
@@ -5479,7 +5479,7 @@ var require_ignore = __commonJS({
|
|
|
5479
5479
|
this._added = true;
|
|
5480
5480
|
return;
|
|
5481
5481
|
}
|
|
5482
|
-
if (
|
|
5482
|
+
if (isString2(pattern)) {
|
|
5483
5483
|
pattern = {
|
|
5484
5484
|
pattern
|
|
5485
5485
|
};
|
|
@@ -5494,7 +5494,7 @@ var require_ignore = __commonJS({
|
|
|
5494
5494
|
add(pattern) {
|
|
5495
5495
|
this._added = false;
|
|
5496
5496
|
makeArray(
|
|
5497
|
-
|
|
5497
|
+
isString2(pattern) ? splitPattern(pattern) : pattern
|
|
5498
5498
|
).forEach(this._add, this);
|
|
5499
5499
|
return this._added;
|
|
5500
5500
|
}
|
|
@@ -5536,7 +5536,7 @@ var require_ignore = __commonJS({
|
|
|
5536
5536
|
throw new Ctor(message);
|
|
5537
5537
|
};
|
|
5538
5538
|
var checkPath = (path25, originalPath, doThrow) => {
|
|
5539
|
-
if (!
|
|
5539
|
+
if (!isString2(path25)) {
|
|
5540
5540
|
return doThrow(
|
|
5541
5541
|
`path must be a string, but got \`${originalPath}\``,
|
|
5542
5542
|
TypeError
|
|
@@ -18730,6 +18730,1794 @@ var init_listr_renderer = __esm({
|
|
|
18730
18730
|
}
|
|
18731
18731
|
});
|
|
18732
18732
|
|
|
18733
|
+
// packages/github-primitive/src/constants.ts
|
|
18734
|
+
var DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_GH_PATH, DEFAULT_NANGO_BASE_URL, DEFAULT_NANGO_PROVIDER_CONFIG_KEY, DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT, DEFAULT_USER_AGENT;
|
|
18735
|
+
var init_constants = __esm({
|
|
18736
|
+
"packages/github-primitive/src/constants.ts"() {
|
|
18737
|
+
"use strict";
|
|
18738
|
+
DEFAULT_TIMEOUT = 3e4;
|
|
18739
|
+
DEFAULT_MAX_RETRIES = 3;
|
|
18740
|
+
DEFAULT_GH_PATH = "gh";
|
|
18741
|
+
DEFAULT_NANGO_BASE_URL = "https://api.nango.dev";
|
|
18742
|
+
DEFAULT_NANGO_PROVIDER_CONFIG_KEY = "github";
|
|
18743
|
+
DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT = "/api/integrations/github/proxy";
|
|
18744
|
+
DEFAULT_USER_AGENT = "agent-relay-github-primitive";
|
|
18745
|
+
}
|
|
18746
|
+
});
|
|
18747
|
+
|
|
18748
|
+
// packages/github-primitive/src/types.ts
|
|
18749
|
+
var GitHubAction, GITHUB_ACTIONS, GitHubApiError, GitHubClientInterface;
|
|
18750
|
+
var init_types = __esm({
|
|
18751
|
+
"packages/github-primitive/src/types.ts"() {
|
|
18752
|
+
"use strict";
|
|
18753
|
+
GitHubAction = /* @__PURE__ */ ((GitHubAction2) => {
|
|
18754
|
+
GitHubAction2["ListRepos"] = "listRepos";
|
|
18755
|
+
GitHubAction2["GetRepo"] = "getRepo";
|
|
18756
|
+
GitHubAction2["ListIssues"] = "listIssues";
|
|
18757
|
+
GitHubAction2["CreateIssue"] = "createIssue";
|
|
18758
|
+
GitHubAction2["UpdateIssue"] = "updateIssue";
|
|
18759
|
+
GitHubAction2["CloseIssue"] = "closeIssue";
|
|
18760
|
+
GitHubAction2["ListPRs"] = "listPRs";
|
|
18761
|
+
GitHubAction2["GetPR"] = "getPR";
|
|
18762
|
+
GitHubAction2["CreatePR"] = "createPR";
|
|
18763
|
+
GitHubAction2["UpdatePR"] = "updatePR";
|
|
18764
|
+
GitHubAction2["MergePR"] = "mergePR";
|
|
18765
|
+
GitHubAction2["ListFiles"] = "listFiles";
|
|
18766
|
+
GitHubAction2["ReadFile"] = "readFile";
|
|
18767
|
+
GitHubAction2["CreateFile"] = "createFile";
|
|
18768
|
+
GitHubAction2["UpdateFile"] = "updateFile";
|
|
18769
|
+
GitHubAction2["DeleteFile"] = "deleteFile";
|
|
18770
|
+
GitHubAction2["CreateBranch"] = "createBranch";
|
|
18771
|
+
GitHubAction2["ListBranches"] = "listBranches";
|
|
18772
|
+
GitHubAction2["ListCommits"] = "listCommits";
|
|
18773
|
+
GitHubAction2["CreateCommit"] = "createCommit";
|
|
18774
|
+
GitHubAction2["GetUser"] = "getUser";
|
|
18775
|
+
GitHubAction2["ListOrganizations"] = "listOrganizations";
|
|
18776
|
+
return GitHubAction2;
|
|
18777
|
+
})(GitHubAction || {});
|
|
18778
|
+
GITHUB_ACTIONS = Object.values(GitHubAction);
|
|
18779
|
+
GitHubApiError = class extends Error {
|
|
18780
|
+
status;
|
|
18781
|
+
responseBody;
|
|
18782
|
+
responseHeaders;
|
|
18783
|
+
cause;
|
|
18784
|
+
constructor(message, options = {}) {
|
|
18785
|
+
super(message);
|
|
18786
|
+
this.name = "GitHubApiError";
|
|
18787
|
+
this.status = options.status;
|
|
18788
|
+
this.responseBody = options.responseBody;
|
|
18789
|
+
this.responseHeaders = options.responseHeaders;
|
|
18790
|
+
this.cause = options.cause;
|
|
18791
|
+
}
|
|
18792
|
+
};
|
|
18793
|
+
GitHubClientInterface = class {
|
|
18794
|
+
config;
|
|
18795
|
+
constructor(config2) {
|
|
18796
|
+
this.config = config2;
|
|
18797
|
+
}
|
|
18798
|
+
getRuntimeConfig() {
|
|
18799
|
+
return this.config;
|
|
18800
|
+
}
|
|
18801
|
+
};
|
|
18802
|
+
}
|
|
18803
|
+
});
|
|
18804
|
+
|
|
18805
|
+
// packages/github-primitive/src/actions/utils.ts
|
|
18806
|
+
async function withActionError(description, operation) {
|
|
18807
|
+
try {
|
|
18808
|
+
return await operation();
|
|
18809
|
+
} catch (error51) {
|
|
18810
|
+
if (error51 instanceof GitHubApiError) {
|
|
18811
|
+
throw new GitHubApiError(`Failed to ${description}: ${error51.message}`, {
|
|
18812
|
+
status: error51.status,
|
|
18813
|
+
responseBody: error51.responseBody,
|
|
18814
|
+
responseHeaders: error51.responseHeaders,
|
|
18815
|
+
cause: error51
|
|
18816
|
+
});
|
|
18817
|
+
}
|
|
18818
|
+
throw new GitHubApiError(`Failed to ${description}: ${errorMessage(error51)}`, { cause: error51 });
|
|
18819
|
+
}
|
|
18820
|
+
}
|
|
18821
|
+
function assertOwnerRepo(owner, repo) {
|
|
18822
|
+
assertNonEmptyString(owner, "owner");
|
|
18823
|
+
assertNonEmptyString(repo, "repo");
|
|
18824
|
+
}
|
|
18825
|
+
function assertNonEmptyString(value, name) {
|
|
18826
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
18827
|
+
throw new GitHubApiError(`GitHub ${name} must be a non-empty string.`);
|
|
18828
|
+
}
|
|
18829
|
+
return value.trim();
|
|
18830
|
+
}
|
|
18831
|
+
function assertPositiveInteger(value, name) {
|
|
18832
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
18833
|
+
throw new GitHubApiError(`GitHub ${name} must be a positive integer.`);
|
|
18834
|
+
}
|
|
18835
|
+
return value;
|
|
18836
|
+
}
|
|
18837
|
+
function repoEndpoint(owner, repo, suffix = "") {
|
|
18838
|
+
assertOwnerRepo(owner, repo);
|
|
18839
|
+
return `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}${suffix}`;
|
|
18840
|
+
}
|
|
18841
|
+
function contentsEndpoint(owner, repo, path25 = "") {
|
|
18842
|
+
const normalizedPath = normalizeRepoPath(path25);
|
|
18843
|
+
const suffix = normalizedPath ? `/contents/${encodeRepoPath(normalizedPath)}` : "/contents";
|
|
18844
|
+
return repoEndpoint(owner, repo, suffix);
|
|
18845
|
+
}
|
|
18846
|
+
function branchEndpoint(owner, repo, branch) {
|
|
18847
|
+
const normalizedBranch = assertNonEmptyString(branch, "branch");
|
|
18848
|
+
return repoEndpoint(owner, repo, `/branches/${encodeURIComponent(normalizedBranch)}`);
|
|
18849
|
+
}
|
|
18850
|
+
function normalizeRepoPath(path25) {
|
|
18851
|
+
return path25?.trim().replace(/^\/+/, "").replace(/\/+$/, "") ?? "";
|
|
18852
|
+
}
|
|
18853
|
+
function normalizePerPage(perPage) {
|
|
18854
|
+
if (typeof perPage === "undefined") {
|
|
18855
|
+
return void 0;
|
|
18856
|
+
}
|
|
18857
|
+
if (!Number.isInteger(perPage) || perPage < 1) {
|
|
18858
|
+
throw new GitHubApiError("GitHub perPage must be a positive integer.");
|
|
18859
|
+
}
|
|
18860
|
+
return Math.min(perPage, 100);
|
|
18861
|
+
}
|
|
18862
|
+
function removeUndefinedValues(values) {
|
|
18863
|
+
const result = {};
|
|
18864
|
+
for (const [key, value] of Object.entries(values)) {
|
|
18865
|
+
if (typeof value !== "undefined") {
|
|
18866
|
+
result[key] = value;
|
|
18867
|
+
}
|
|
18868
|
+
}
|
|
18869
|
+
return result;
|
|
18870
|
+
}
|
|
18871
|
+
function hasDefinedValue(values) {
|
|
18872
|
+
return Object.values(values).some((value) => typeof value !== "undefined");
|
|
18873
|
+
}
|
|
18874
|
+
function optionalRecord(value) {
|
|
18875
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
18876
|
+
}
|
|
18877
|
+
function appendQuery(path25, query) {
|
|
18878
|
+
if (!query) {
|
|
18879
|
+
return path25;
|
|
18880
|
+
}
|
|
18881
|
+
const params = new URLSearchParams();
|
|
18882
|
+
for (const [name, rawValue] of Object.entries(query)) {
|
|
18883
|
+
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
18884
|
+
for (const value of values) {
|
|
18885
|
+
if (value !== null && typeof value !== "undefined") {
|
|
18886
|
+
params.append(name, String(value));
|
|
18887
|
+
}
|
|
18888
|
+
}
|
|
18889
|
+
}
|
|
18890
|
+
const serialized = params.toString();
|
|
18891
|
+
if (!serialized) {
|
|
18892
|
+
return path25;
|
|
18893
|
+
}
|
|
18894
|
+
return `${path25}${path25.includes("?") ? "&" : "?"}${serialized}`;
|
|
18895
|
+
}
|
|
18896
|
+
function nonEmpty(value) {
|
|
18897
|
+
const trimmed = value?.trim();
|
|
18898
|
+
return trimmed ? trimmed : void 0;
|
|
18899
|
+
}
|
|
18900
|
+
function trimTrailingSlash(value) {
|
|
18901
|
+
const trimmed = nonEmpty(value);
|
|
18902
|
+
return trimmed?.replace(/\/+$/, "");
|
|
18903
|
+
}
|
|
18904
|
+
function queryWithPerPage(query, perPage) {
|
|
18905
|
+
const normalizedPerPage = normalizePerPage(perPage);
|
|
18906
|
+
return typeof normalizedPerPage === "undefined" ? query : {
|
|
18907
|
+
...query,
|
|
18908
|
+
per_page: normalizedPerPage
|
|
18909
|
+
};
|
|
18910
|
+
}
|
|
18911
|
+
function asRecord(value, name) {
|
|
18912
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
18913
|
+
throw new GitHubApiError(`GitHub API response for ${name} was not an object.`);
|
|
18914
|
+
}
|
|
18915
|
+
return value;
|
|
18916
|
+
}
|
|
18917
|
+
function asArray(value, name) {
|
|
18918
|
+
if (!Array.isArray(value)) {
|
|
18919
|
+
throw new GitHubApiError(`GitHub API response for ${name} was not an array.`);
|
|
18920
|
+
}
|
|
18921
|
+
return value;
|
|
18922
|
+
}
|
|
18923
|
+
function mapGitHubOwner(value) {
|
|
18924
|
+
const owner = asRecord(value, "owner");
|
|
18925
|
+
return {
|
|
18926
|
+
login: stringValue(owner.login),
|
|
18927
|
+
type: stringValue(owner.type, "User"),
|
|
18928
|
+
id: numberValue(owner.id),
|
|
18929
|
+
avatarUrl: optionalString(owner.avatar_url),
|
|
18930
|
+
htmlUrl: optionalString(owner.html_url)
|
|
18931
|
+
};
|
|
18932
|
+
}
|
|
18933
|
+
function mapLogin(value) {
|
|
18934
|
+
const record2 = asRecord(value, "user");
|
|
18935
|
+
return {
|
|
18936
|
+
login: stringValue(record2.login)
|
|
18937
|
+
};
|
|
18938
|
+
}
|
|
18939
|
+
function mapLogins(value) {
|
|
18940
|
+
if (!Array.isArray(value)) {
|
|
18941
|
+
return [];
|
|
18942
|
+
}
|
|
18943
|
+
return value.map(mapLogin);
|
|
18944
|
+
}
|
|
18945
|
+
function stringValue(value, fallback = "") {
|
|
18946
|
+
return typeof value === "string" ? value : fallback;
|
|
18947
|
+
}
|
|
18948
|
+
function optionalString(value) {
|
|
18949
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
18950
|
+
}
|
|
18951
|
+
function numberValue(value, fallback = 0) {
|
|
18952
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
18953
|
+
}
|
|
18954
|
+
function booleanValue(value, fallback = false) {
|
|
18955
|
+
return typeof value === "boolean" ? value : fallback;
|
|
18956
|
+
}
|
|
18957
|
+
function stateValue(value) {
|
|
18958
|
+
return value === "closed" ? "closed" : "open";
|
|
18959
|
+
}
|
|
18960
|
+
function visibilityValue(value, isPrivate) {
|
|
18961
|
+
if (value === "public" || value === "private" || value === "internal") {
|
|
18962
|
+
return value;
|
|
18963
|
+
}
|
|
18964
|
+
return isPrivate ? "private" : "public";
|
|
18965
|
+
}
|
|
18966
|
+
function errorMessage(error51) {
|
|
18967
|
+
return error51 instanceof Error ? error51.message : String(error51);
|
|
18968
|
+
}
|
|
18969
|
+
function encodeRepoPath(path25) {
|
|
18970
|
+
return path25.split("/").map(encodeURIComponent).join("/");
|
|
18971
|
+
}
|
|
18972
|
+
var init_utils = __esm({
|
|
18973
|
+
"packages/github-primitive/src/actions/utils.ts"() {
|
|
18974
|
+
"use strict";
|
|
18975
|
+
init_types();
|
|
18976
|
+
}
|
|
18977
|
+
});
|
|
18978
|
+
|
|
18979
|
+
// packages/github-primitive/src/actions/branches.ts
|
|
18980
|
+
async function listBranches(adapter, owner, repo) {
|
|
18981
|
+
return withActionError(`list GitHub branches for ${owner}/${repo}`, async () => {
|
|
18982
|
+
assertOwnerRepo(owner, repo);
|
|
18983
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo, "/branches"));
|
|
18984
|
+
return asArray(response, "branches").map(mapBranch);
|
|
18985
|
+
});
|
|
18986
|
+
}
|
|
18987
|
+
async function createBranch(adapter, params) {
|
|
18988
|
+
const { owner, repo } = params;
|
|
18989
|
+
return withActionError(`create GitHub branch ${params.branch} in ${owner}/${repo}`, async () => {
|
|
18990
|
+
assertOwnerRepo(owner, repo);
|
|
18991
|
+
const branch = assertNonEmptyString(params.branch, "branch");
|
|
18992
|
+
const sourceBranch = params.fromBranch ?? await getDefaultBranch(adapter, params);
|
|
18993
|
+
const source = await getBranch(adapter, owner, repo, sourceBranch);
|
|
18994
|
+
const sha = assertNonEmptyString(source.commit.sha, "source branch sha");
|
|
18995
|
+
await adapter.request("POST", repoEndpoint(owner, repo, "/git/refs"), {
|
|
18996
|
+
body: {
|
|
18997
|
+
ref: `refs/heads/${branch}`,
|
|
18998
|
+
sha
|
|
18999
|
+
}
|
|
19000
|
+
});
|
|
19001
|
+
});
|
|
19002
|
+
}
|
|
19003
|
+
async function getBranch(adapter, owner, repo, branch) {
|
|
19004
|
+
const response = await adapter.request("GET", branchEndpoint(owner, repo, branch));
|
|
19005
|
+
return mapBranch(response);
|
|
19006
|
+
}
|
|
19007
|
+
function mapBranch(value) {
|
|
19008
|
+
const branch = asRecord(value, "branch");
|
|
19009
|
+
const commit = asRecord(branch.commit, "branch commit");
|
|
19010
|
+
return {
|
|
19011
|
+
name: stringValue(branch.name),
|
|
19012
|
+
commit: {
|
|
19013
|
+
sha: stringValue(commit.sha),
|
|
19014
|
+
url: stringValue(commit.url)
|
|
19015
|
+
},
|
|
19016
|
+
protected: booleanValue(branch.protected)
|
|
19017
|
+
};
|
|
19018
|
+
}
|
|
19019
|
+
async function getDefaultBranch(adapter, params) {
|
|
19020
|
+
const response = await adapter.request("GET", repoEndpoint(params.owner, params.repo));
|
|
19021
|
+
const repository = asRecord(response, "repository");
|
|
19022
|
+
const branch = stringValue(repository.default_branch);
|
|
19023
|
+
if (!branch) {
|
|
19024
|
+
const id = numberValue(repository.id);
|
|
19025
|
+
throw new Error(
|
|
19026
|
+
id ? `Repository ${params.owner}/${params.repo} did not include a default branch.` : `Repository ${params.owner}/${params.repo} was not a valid repository response.`
|
|
19027
|
+
);
|
|
19028
|
+
}
|
|
19029
|
+
return branch;
|
|
19030
|
+
}
|
|
19031
|
+
var init_branches = __esm({
|
|
19032
|
+
"packages/github-primitive/src/actions/branches.ts"() {
|
|
19033
|
+
"use strict";
|
|
19034
|
+
init_utils();
|
|
19035
|
+
}
|
|
19036
|
+
});
|
|
19037
|
+
|
|
19038
|
+
// packages/github-primitive/src/actions/commits.ts
|
|
19039
|
+
async function listCommits(adapter, params) {
|
|
19040
|
+
const { owner, repo } = params;
|
|
19041
|
+
return withActionError(`list GitHub commits for ${owner}/${repo}`, async () => {
|
|
19042
|
+
assertOwnerRepo(owner, repo);
|
|
19043
|
+
const query = {
|
|
19044
|
+
sha: params.sha,
|
|
19045
|
+
path: params.path,
|
|
19046
|
+
author: params.author,
|
|
19047
|
+
since: params.since,
|
|
19048
|
+
until: params.until,
|
|
19049
|
+
per_page: normalizePerPage(params.perPage)
|
|
19050
|
+
};
|
|
19051
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo, "/commits"), {
|
|
19052
|
+
query
|
|
19053
|
+
});
|
|
19054
|
+
return asArray(response, "commits").map(mapCommit);
|
|
19055
|
+
});
|
|
19056
|
+
}
|
|
19057
|
+
async function createCommit(adapter, params) {
|
|
19058
|
+
const { owner, repo } = params;
|
|
19059
|
+
return withActionError(`create GitHub commit in ${owner}/${repo}`, async () => {
|
|
19060
|
+
assertOwnerRepo(owner, repo);
|
|
19061
|
+
const message = assertNonEmptyString(params.message, "commit message");
|
|
19062
|
+
const tree = assertNonEmptyString(params.tree, "commit tree");
|
|
19063
|
+
if (!Array.isArray(params.parents)) {
|
|
19064
|
+
throw new Error("GitHub commit parents must be an array of parent SHAs.");
|
|
19065
|
+
}
|
|
19066
|
+
const response = await adapter.request("POST", repoEndpoint(owner, repo, "/git/commits"), {
|
|
19067
|
+
body: removeUndefinedValues({
|
|
19068
|
+
message,
|
|
19069
|
+
tree,
|
|
19070
|
+
parents: params.parents.map((parent) => assertNonEmptyString(parent, "parent sha")),
|
|
19071
|
+
author: params.author,
|
|
19072
|
+
committer: params.committer
|
|
19073
|
+
})
|
|
19074
|
+
});
|
|
19075
|
+
return mapCommit(response);
|
|
19076
|
+
});
|
|
19077
|
+
}
|
|
19078
|
+
function mapCommit(value) {
|
|
19079
|
+
const topLevel = asRecord(value, "commit");
|
|
19080
|
+
const nestedCommit = optionalRecord(topLevel.commit);
|
|
19081
|
+
const author = optionalRecord(nestedCommit?.author ?? topLevel.author);
|
|
19082
|
+
const committer = optionalRecord(nestedCommit?.committer ?? topLevel.committer);
|
|
19083
|
+
return {
|
|
19084
|
+
sha: stringValue(topLevel.sha),
|
|
19085
|
+
url: optionalString(topLevel.url),
|
|
19086
|
+
htmlUrl: optionalString(topLevel.html_url),
|
|
19087
|
+
message: optionalString(nestedCommit?.message ?? topLevel.message),
|
|
19088
|
+
author: author ? mapCommitAuthor(author) : void 0,
|
|
19089
|
+
committer: committer ? mapCommitAuthor(committer) : void 0
|
|
19090
|
+
};
|
|
19091
|
+
}
|
|
19092
|
+
function mapCommitAuthor(value) {
|
|
19093
|
+
return {
|
|
19094
|
+
name: stringValue(value.name),
|
|
19095
|
+
email: stringValue(value.email),
|
|
19096
|
+
date: optionalString(value.date)
|
|
19097
|
+
};
|
|
19098
|
+
}
|
|
19099
|
+
var init_commits = __esm({
|
|
19100
|
+
"packages/github-primitive/src/actions/commits.ts"() {
|
|
19101
|
+
"use strict";
|
|
19102
|
+
init_utils();
|
|
19103
|
+
}
|
|
19104
|
+
});
|
|
19105
|
+
|
|
19106
|
+
// packages/github-primitive/src/actions/files.ts
|
|
19107
|
+
async function listFiles(adapter, owner, repo, path25 = "", options = {}) {
|
|
19108
|
+
return withActionError(`list GitHub files at ${owner}/${repo}/${path25}`, async () => {
|
|
19109
|
+
assertOwnerRepo(owner, repo);
|
|
19110
|
+
const response = await adapter.request("GET", contentsEndpoint(owner, repo, path25), {
|
|
19111
|
+
query: {
|
|
19112
|
+
ref: options.ref
|
|
19113
|
+
}
|
|
19114
|
+
});
|
|
19115
|
+
return Array.isArray(response) ? asArray(response, "repository contents").map(mapFile) : [mapFile(response)];
|
|
19116
|
+
});
|
|
19117
|
+
}
|
|
19118
|
+
async function readFile3(adapter, owner, repo, path25, ref) {
|
|
19119
|
+
return withActionError(`read GitHub file ${owner}/${repo}/${path25}`, async () => {
|
|
19120
|
+
assertOwnerRepo(owner, repo);
|
|
19121
|
+
assertNonEmptyString(normalizeRepoPath(path25), "file path");
|
|
19122
|
+
const response = await adapter.request("GET", contentsEndpoint(owner, repo, path25), {
|
|
19123
|
+
query: {
|
|
19124
|
+
ref
|
|
19125
|
+
}
|
|
19126
|
+
});
|
|
19127
|
+
const file2 = mapFile(response);
|
|
19128
|
+
if (file2.type !== "file") {
|
|
19129
|
+
throw new Error(`GitHub path "${path25}" is not a file.`);
|
|
19130
|
+
}
|
|
19131
|
+
if (!file2.content) {
|
|
19132
|
+
throw new Error(`GitHub file "${path25}" did not include content in the API response.`);
|
|
19133
|
+
}
|
|
19134
|
+
if (file2.encoding && file2.encoding !== "base64") {
|
|
19135
|
+
throw new Error(`GitHub file "${path25}" used unsupported encoding "${file2.encoding}".`);
|
|
19136
|
+
}
|
|
19137
|
+
return import_node_buffer.Buffer.from(file2.content.replace(/\s/g, ""), "base64").toString("utf8");
|
|
19138
|
+
});
|
|
19139
|
+
}
|
|
19140
|
+
async function createFile(adapter, owner, repo, path25, content, message, options = {}) {
|
|
19141
|
+
return withActionError(`create GitHub file ${owner}/${repo}/${path25}`, async () => {
|
|
19142
|
+
assertOwnerRepo(owner, repo);
|
|
19143
|
+
const normalizedPath = assertNonEmptyString(normalizeRepoPath(path25), "file path");
|
|
19144
|
+
const commitMessage = assertNonEmptyString(message, "commit message");
|
|
19145
|
+
await adapter.request("PUT", contentsEndpoint(owner, repo, normalizedPath), {
|
|
19146
|
+
body: removeUndefinedValues({
|
|
19147
|
+
message: commitMessage,
|
|
19148
|
+
content: import_node_buffer.Buffer.from(content, "utf8").toString("base64"),
|
|
19149
|
+
branch: options.branch,
|
|
19150
|
+
author: options.author
|
|
19151
|
+
})
|
|
19152
|
+
});
|
|
19153
|
+
});
|
|
19154
|
+
}
|
|
19155
|
+
async function updateFile(adapter, owner, repo, path25, content, message, sha, options = {}) {
|
|
19156
|
+
return withActionError(`update GitHub file ${owner}/${repo}/${path25}`, async () => {
|
|
19157
|
+
assertOwnerRepo(owner, repo);
|
|
19158
|
+
const normalizedPath = assertNonEmptyString(normalizeRepoPath(path25), "file path");
|
|
19159
|
+
const commitMessage = assertNonEmptyString(message, "commit message");
|
|
19160
|
+
const fileSha = assertNonEmptyString(sha, "file sha");
|
|
19161
|
+
const response = await adapter.request("PUT", contentsEndpoint(owner, repo, normalizedPath), {
|
|
19162
|
+
body: removeUndefinedValues({
|
|
19163
|
+
message: commitMessage,
|
|
19164
|
+
content: import_node_buffer.Buffer.from(content, "utf8").toString("base64"),
|
|
19165
|
+
sha: fileSha,
|
|
19166
|
+
branch: options.branch,
|
|
19167
|
+
author: options.author
|
|
19168
|
+
})
|
|
19169
|
+
});
|
|
19170
|
+
const contentRecord = asRecord(response, "update file response").content;
|
|
19171
|
+
return mapFile(contentRecord);
|
|
19172
|
+
});
|
|
19173
|
+
}
|
|
19174
|
+
async function deleteFile(adapter, owner, repo, path25, sha, message, options = {}) {
|
|
19175
|
+
return withActionError(`delete GitHub file ${owner}/${repo}/${path25}`, async () => {
|
|
19176
|
+
assertOwnerRepo(owner, repo);
|
|
19177
|
+
const normalizedPath = assertNonEmptyString(normalizeRepoPath(path25), "file path");
|
|
19178
|
+
const fileSha = assertNonEmptyString(sha, "file sha");
|
|
19179
|
+
const commitMessage = assertNonEmptyString(message, "commit message");
|
|
19180
|
+
await adapter.request("DELETE", contentsEndpoint(owner, repo, normalizedPath), {
|
|
19181
|
+
body: removeUndefinedValues({
|
|
19182
|
+
message: commitMessage,
|
|
19183
|
+
sha: fileSha,
|
|
19184
|
+
branch: options.branch,
|
|
19185
|
+
author: options.author
|
|
19186
|
+
})
|
|
19187
|
+
});
|
|
19188
|
+
});
|
|
19189
|
+
}
|
|
19190
|
+
function mapFile(value) {
|
|
19191
|
+
const file2 = asRecord(value, "repository content");
|
|
19192
|
+
const type = stringValue(file2.type) === "dir" ? "dir" : "file";
|
|
19193
|
+
return {
|
|
19194
|
+
name: stringValue(file2.name),
|
|
19195
|
+
path: stringValue(file2.path),
|
|
19196
|
+
sha: stringValue(file2.sha),
|
|
19197
|
+
size: numberValue(file2.size),
|
|
19198
|
+
url: stringValue(file2.url),
|
|
19199
|
+
htmlUrl: stringValue(file2.html_url),
|
|
19200
|
+
gitUrl: stringValue(file2.git_url),
|
|
19201
|
+
downloadUrl: optionalString(file2.download_url),
|
|
19202
|
+
type,
|
|
19203
|
+
content: optionalString(file2.content),
|
|
19204
|
+
encoding: optionalString(file2.encoding),
|
|
19205
|
+
target: optionalString(file2.target)
|
|
19206
|
+
};
|
|
19207
|
+
}
|
|
19208
|
+
var import_node_buffer;
|
|
19209
|
+
var init_files = __esm({
|
|
19210
|
+
"packages/github-primitive/src/actions/files.ts"() {
|
|
19211
|
+
"use strict";
|
|
19212
|
+
import_node_buffer = require("node:buffer");
|
|
19213
|
+
init_utils();
|
|
19214
|
+
}
|
|
19215
|
+
});
|
|
19216
|
+
|
|
19217
|
+
// packages/github-primitive/src/actions/issues.ts
|
|
19218
|
+
async function listIssues(adapter, owner, repo, options = {}) {
|
|
19219
|
+
return withActionError(`list GitHub issues for ${owner}/${repo}`, async () => {
|
|
19220
|
+
assertOwnerRepo(owner, repo);
|
|
19221
|
+
const query = queryWithPerPage(
|
|
19222
|
+
{
|
|
19223
|
+
state: options.state,
|
|
19224
|
+
assignee: options.assignee,
|
|
19225
|
+
labels: options.labels,
|
|
19226
|
+
sort: options.sort,
|
|
19227
|
+
direction: options.direction
|
|
19228
|
+
},
|
|
19229
|
+
options.perPage
|
|
19230
|
+
);
|
|
19231
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo, "/issues"), {
|
|
19232
|
+
query
|
|
19233
|
+
});
|
|
19234
|
+
return asArray(response, "issues").filter(isIssueResponse).map(mapIssue);
|
|
19235
|
+
});
|
|
19236
|
+
}
|
|
19237
|
+
async function createIssue(adapter, owner, repo, title, body, options = {}) {
|
|
19238
|
+
return withActionError(`create GitHub issue in ${owner}/${repo}`, async () => {
|
|
19239
|
+
assertOwnerRepo(owner, repo);
|
|
19240
|
+
const issueTitle = assertNonEmptyString(title, "issue title");
|
|
19241
|
+
const response = await adapter.request("POST", repoEndpoint(owner, repo, "/issues"), {
|
|
19242
|
+
body: removeUndefinedValues({
|
|
19243
|
+
title: issueTitle,
|
|
19244
|
+
body,
|
|
19245
|
+
assignees: options.assignee ? [options.assignee] : void 0,
|
|
19246
|
+
labels: options.labels,
|
|
19247
|
+
milestone: options.milestone
|
|
19248
|
+
})
|
|
19249
|
+
});
|
|
19250
|
+
return mapIssue(response);
|
|
19251
|
+
});
|
|
19252
|
+
}
|
|
19253
|
+
async function updateIssue(adapter, owner, repo, number4, updates) {
|
|
19254
|
+
return withActionError(`update GitHub issue #${number4} in ${owner}/${repo}`, async () => {
|
|
19255
|
+
assertOwnerRepo(owner, repo);
|
|
19256
|
+
assertPositiveInteger(number4, "issue number");
|
|
19257
|
+
if (!hasDefinedValue(updates)) {
|
|
19258
|
+
throw new Error("At least one issue update field must be provided.");
|
|
19259
|
+
}
|
|
19260
|
+
const response = await adapter.request("PATCH", repoEndpoint(owner, repo, `/issues/${number4}`), {
|
|
19261
|
+
body: removeUndefinedValues({
|
|
19262
|
+
title: updates.title,
|
|
19263
|
+
body: updates.body,
|
|
19264
|
+
state: updates.state,
|
|
19265
|
+
assignees: updates.assignee ? [updates.assignee] : void 0,
|
|
19266
|
+
labels: updates.labels
|
|
19267
|
+
})
|
|
19268
|
+
});
|
|
19269
|
+
return mapIssue(response);
|
|
19270
|
+
});
|
|
19271
|
+
}
|
|
19272
|
+
function mapIssue(value) {
|
|
19273
|
+
const issue2 = asRecord(value, "issue");
|
|
19274
|
+
const milestone = optionalRecord(issue2.milestone);
|
|
19275
|
+
const reactions = optionalRecord(issue2.reactions);
|
|
19276
|
+
return {
|
|
19277
|
+
number: numberValue(issue2.number),
|
|
19278
|
+
id: numberValue(issue2.id),
|
|
19279
|
+
title: stringValue(issue2.title),
|
|
19280
|
+
body: optionalString(issue2.body),
|
|
19281
|
+
user: mapGitHubOwner(issue2.user),
|
|
19282
|
+
labels: Array.isArray(issue2.labels) ? issue2.labels.map(mapIssueLabel) : [],
|
|
19283
|
+
state: stateValue(issue2.state),
|
|
19284
|
+
locked: booleanValue(issue2.locked),
|
|
19285
|
+
assignee: issue2.assignee ? mapLogin(issue2.assignee) : void 0,
|
|
19286
|
+
assignees: mapLogins(issue2.assignees),
|
|
19287
|
+
milestone: milestone ? {
|
|
19288
|
+
number: numberValue(milestone.number),
|
|
19289
|
+
title: stringValue(milestone.title)
|
|
19290
|
+
} : void 0,
|
|
19291
|
+
commentsCount: numberValue(issue2.comments),
|
|
19292
|
+
createdAt: stringValue(issue2.created_at),
|
|
19293
|
+
updatedAt: stringValue(issue2.updated_at),
|
|
19294
|
+
closedAt: optionalString(issue2.closed_at),
|
|
19295
|
+
authorAssociation: stringValue(issue2.author_association),
|
|
19296
|
+
reactions: {
|
|
19297
|
+
totalCount: numberValue(reactions?.total_count)
|
|
19298
|
+
}
|
|
19299
|
+
};
|
|
19300
|
+
}
|
|
19301
|
+
function mapIssueLabel(value) {
|
|
19302
|
+
if (typeof value === "string") {
|
|
19303
|
+
return {
|
|
19304
|
+
name: value,
|
|
19305
|
+
color: ""
|
|
19306
|
+
};
|
|
19307
|
+
}
|
|
19308
|
+
const label = asRecord(value, "issue label");
|
|
19309
|
+
return {
|
|
19310
|
+
name: stringValue(label.name),
|
|
19311
|
+
color: stringValue(label.color),
|
|
19312
|
+
description: optionalString(label.description)
|
|
19313
|
+
};
|
|
19314
|
+
}
|
|
19315
|
+
function isIssueResponse(value) {
|
|
19316
|
+
return !("pull_request" in asRecord(value, "issue"));
|
|
19317
|
+
}
|
|
19318
|
+
var init_issues = __esm({
|
|
19319
|
+
"packages/github-primitive/src/actions/issues.ts"() {
|
|
19320
|
+
"use strict";
|
|
19321
|
+
init_utils();
|
|
19322
|
+
}
|
|
19323
|
+
});
|
|
19324
|
+
|
|
19325
|
+
// packages/github-primitive/src/actions/pulls.ts
|
|
19326
|
+
async function listPRs(adapter, owner, repo, options = {}) {
|
|
19327
|
+
return withActionError(`list GitHub pull requests for ${owner}/${repo}`, async () => {
|
|
19328
|
+
assertOwnerRepo(owner, repo);
|
|
19329
|
+
const query = queryWithPerPage(
|
|
19330
|
+
{
|
|
19331
|
+
state: options.state,
|
|
19332
|
+
base: options.base,
|
|
19333
|
+
head: options.head,
|
|
19334
|
+
sort: options.sort,
|
|
19335
|
+
direction: options.direction
|
|
19336
|
+
},
|
|
19337
|
+
options.perPage
|
|
19338
|
+
);
|
|
19339
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo, "/pulls"), {
|
|
19340
|
+
query
|
|
19341
|
+
});
|
|
19342
|
+
return asArray(response, "pull requests").map(mapPR);
|
|
19343
|
+
});
|
|
19344
|
+
}
|
|
19345
|
+
async function getPR(adapter, owner, repo, number4) {
|
|
19346
|
+
return withActionError(`get GitHub pull request #${number4} in ${owner}/${repo}`, async () => {
|
|
19347
|
+
assertOwnerRepo(owner, repo);
|
|
19348
|
+
assertPositiveInteger(number4, "pull request number");
|
|
19349
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo, `/pulls/${number4}`));
|
|
19350
|
+
return mapPR(response);
|
|
19351
|
+
});
|
|
19352
|
+
}
|
|
19353
|
+
async function createPR(adapter, owner, repo, title, body, base, head, options = {}) {
|
|
19354
|
+
return withActionError(`create GitHub pull request in ${owner}/${repo}`, async () => {
|
|
19355
|
+
assertOwnerRepo(owner, repo);
|
|
19356
|
+
const prTitle = assertNonEmptyString(title, "pull request title");
|
|
19357
|
+
const baseRef = assertNonEmptyString(base, "pull request base");
|
|
19358
|
+
const headRef = assertNonEmptyString(head, "pull request head");
|
|
19359
|
+
const response = await adapter.request("POST", repoEndpoint(owner, repo, "/pulls"), {
|
|
19360
|
+
body: removeUndefinedValues({
|
|
19361
|
+
title: prTitle,
|
|
19362
|
+
body,
|
|
19363
|
+
base: baseRef,
|
|
19364
|
+
head: headRef,
|
|
19365
|
+
draft: options.draft,
|
|
19366
|
+
maintainer_can_modify: options.maintainerCanModify
|
|
19367
|
+
})
|
|
19368
|
+
});
|
|
19369
|
+
return mapPR(response);
|
|
19370
|
+
});
|
|
19371
|
+
}
|
|
19372
|
+
async function updatePR(adapter, owner, repo, number4, updates) {
|
|
19373
|
+
return withActionError(`update GitHub pull request #${number4} in ${owner}/${repo}`, async () => {
|
|
19374
|
+
assertOwnerRepo(owner, repo);
|
|
19375
|
+
assertPositiveInteger(number4, "pull request number");
|
|
19376
|
+
if (!hasDefinedValue(updates)) {
|
|
19377
|
+
throw new Error("At least one pull request update field must be provided.");
|
|
19378
|
+
}
|
|
19379
|
+
const response = await adapter.request("PATCH", repoEndpoint(owner, repo, `/pulls/${number4}`), {
|
|
19380
|
+
body: removeUndefinedValues({
|
|
19381
|
+
title: updates.title,
|
|
19382
|
+
body: updates.body,
|
|
19383
|
+
state: updates.state,
|
|
19384
|
+
base: updates.base,
|
|
19385
|
+
maintainer_can_modify: updates.maintainerCanModify
|
|
19386
|
+
})
|
|
19387
|
+
});
|
|
19388
|
+
return mapPR(response);
|
|
19389
|
+
});
|
|
19390
|
+
}
|
|
19391
|
+
async function mergePR(adapter, owner, repo, number4, options = {}) {
|
|
19392
|
+
return withActionError(`merge GitHub pull request #${number4} in ${owner}/${repo}`, async () => {
|
|
19393
|
+
assertOwnerRepo(owner, repo);
|
|
19394
|
+
assertPositiveInteger(number4, "pull request number");
|
|
19395
|
+
await adapter.request("PUT", repoEndpoint(owner, repo, `/pulls/${number4}/merge`), {
|
|
19396
|
+
body: removeUndefinedValues({
|
|
19397
|
+
commit_title: options.commitTitle,
|
|
19398
|
+
commit_message: options.commitMessage,
|
|
19399
|
+
merge_method: options.mergeMethod
|
|
19400
|
+
})
|
|
19401
|
+
});
|
|
19402
|
+
return getPR(adapter, owner, repo, number4);
|
|
19403
|
+
});
|
|
19404
|
+
}
|
|
19405
|
+
function mapPR(value) {
|
|
19406
|
+
const pull = asRecord(value, "pull request");
|
|
19407
|
+
const base = asRecord(pull.base, "pull request base");
|
|
19408
|
+
const head = asRecord(pull.head, "pull request head");
|
|
19409
|
+
const baseRepo = optionalRecord(base.repo);
|
|
19410
|
+
const headRepo = optionalRecord(head.repo);
|
|
19411
|
+
return {
|
|
19412
|
+
number: numberValue(pull.number),
|
|
19413
|
+
id: numberValue(pull.id),
|
|
19414
|
+
title: stringValue(pull.title),
|
|
19415
|
+
body: optionalString(pull.body),
|
|
19416
|
+
user: mapGitHubOwner(pull.user),
|
|
19417
|
+
state: stateValue(pull.state),
|
|
19418
|
+
draft: booleanValue(pull.draft),
|
|
19419
|
+
locked: booleanValue(pull.locked),
|
|
19420
|
+
mergeable: typeof pull.mergeable === "boolean" ? pull.mergeable : void 0,
|
|
19421
|
+
mergeableState: stringValue(pull.mergeable_state),
|
|
19422
|
+
merged: booleanValue(pull.merged),
|
|
19423
|
+
mergedAt: optionalString(pull.merged_at),
|
|
19424
|
+
mergedBy: pull.merged_by ? mapLogin(pull.merged_by) : void 0,
|
|
19425
|
+
base: {
|
|
19426
|
+
ref: stringValue(base.ref),
|
|
19427
|
+
sha: stringValue(base.sha),
|
|
19428
|
+
repo: {
|
|
19429
|
+
name: stringValue(baseRepo?.name),
|
|
19430
|
+
fullName: stringValue(baseRepo?.full_name)
|
|
19431
|
+
}
|
|
19432
|
+
},
|
|
19433
|
+
head: {
|
|
19434
|
+
ref: stringValue(head.ref),
|
|
19435
|
+
sha: stringValue(head.sha),
|
|
19436
|
+
repo: headRepo ? {
|
|
19437
|
+
name: stringValue(headRepo.name),
|
|
19438
|
+
fullName: stringValue(headRepo.full_name)
|
|
19439
|
+
} : void 0
|
|
19440
|
+
},
|
|
19441
|
+
requestedReviewers: mapLogins(pull.requested_reviewers),
|
|
19442
|
+
labels: Array.isArray(pull.labels) ? pull.labels.map(mapPullLabel) : [],
|
|
19443
|
+
commentsCount: numberValue(pull.comments),
|
|
19444
|
+
reviewCommentsCount: numberValue(pull.review_comments),
|
|
19445
|
+
commitsCount: numberValue(pull.commits),
|
|
19446
|
+
additionsCount: numberValue(pull.additions),
|
|
19447
|
+
deletionsCount: numberValue(pull.deletions),
|
|
19448
|
+
changedFilesCount: numberValue(pull.changed_files),
|
|
19449
|
+
createdAt: stringValue(pull.created_at),
|
|
19450
|
+
updatedAt: stringValue(pull.updated_at)
|
|
19451
|
+
};
|
|
19452
|
+
}
|
|
19453
|
+
function mapPullLabel(value) {
|
|
19454
|
+
if (typeof value === "string") {
|
|
19455
|
+
return {
|
|
19456
|
+
name: value,
|
|
19457
|
+
color: ""
|
|
19458
|
+
};
|
|
19459
|
+
}
|
|
19460
|
+
const label = asRecord(value, "pull request label");
|
|
19461
|
+
return {
|
|
19462
|
+
name: stringValue(label.name),
|
|
19463
|
+
color: stringValue(label.color)
|
|
19464
|
+
};
|
|
19465
|
+
}
|
|
19466
|
+
var init_pulls = __esm({
|
|
19467
|
+
"packages/github-primitive/src/actions/pulls.ts"() {
|
|
19468
|
+
"use strict";
|
|
19469
|
+
init_utils();
|
|
19470
|
+
}
|
|
19471
|
+
});
|
|
19472
|
+
|
|
19473
|
+
// packages/github-primitive/src/actions/repos.ts
|
|
19474
|
+
async function listRepos(adapter, options = {}) {
|
|
19475
|
+
return withActionError("list GitHub repositories", async () => {
|
|
19476
|
+
const query = queryWithPerPage(
|
|
19477
|
+
{
|
|
19478
|
+
visibility: options.visibility,
|
|
19479
|
+
affiliation: options.affiliation,
|
|
19480
|
+
sort: options.sort,
|
|
19481
|
+
direction: options.direction
|
|
19482
|
+
},
|
|
19483
|
+
options.perPage
|
|
19484
|
+
);
|
|
19485
|
+
const response = await adapter.request("GET", "/user/repos", { query });
|
|
19486
|
+
return asArray(response, "repositories").map(mapRepo);
|
|
19487
|
+
});
|
|
19488
|
+
}
|
|
19489
|
+
async function getRepo(adapter, owner, repo) {
|
|
19490
|
+
return withActionError(`get GitHub repository ${owner}/${repo}`, async () => {
|
|
19491
|
+
const response = await adapter.request("GET", repoEndpoint(owner, repo));
|
|
19492
|
+
return mapRepo(response);
|
|
19493
|
+
});
|
|
19494
|
+
}
|
|
19495
|
+
function mapRepo(value) {
|
|
19496
|
+
const repo = asRecord(value, "repository");
|
|
19497
|
+
const isPrivate = booleanValue(repo.private);
|
|
19498
|
+
const permissions = optionalRecord(repo.permissions);
|
|
19499
|
+
return {
|
|
19500
|
+
id: numberValue(repo.id),
|
|
19501
|
+
name: stringValue(repo.name),
|
|
19502
|
+
fullName: stringValue(repo.full_name, stringValue(repo.name)),
|
|
19503
|
+
owner: mapGitHubOwner(repo.owner),
|
|
19504
|
+
description: optionalString(repo.description),
|
|
19505
|
+
private: isPrivate,
|
|
19506
|
+
fork: booleanValue(repo.fork),
|
|
19507
|
+
createdAt: stringValue(repo.created_at),
|
|
19508
|
+
updatedAt: stringValue(repo.updated_at),
|
|
19509
|
+
pushedAt: stringValue(repo.pushed_at),
|
|
19510
|
+
size: numberValue(repo.size),
|
|
19511
|
+
stargazersCount: numberValue(repo.stargazers_count),
|
|
19512
|
+
watchersCount: numberValue(repo.watchers_count),
|
|
19513
|
+
language: optionalString(repo.language),
|
|
19514
|
+
forksCount: numberValue(repo.forks_count),
|
|
19515
|
+
openIssuesCount: numberValue(repo.open_issues_count),
|
|
19516
|
+
defaultBranch: stringValue(repo.default_branch),
|
|
19517
|
+
topics: Array.isArray(repo.topics) ? repo.topics.filter(isString) : [],
|
|
19518
|
+
visibility: visibilityValue(repo.visibility, isPrivate),
|
|
19519
|
+
permissions: permissions ? {
|
|
19520
|
+
admin: booleanValue(permissions.admin),
|
|
19521
|
+
maintain: booleanValue(permissions.maintain),
|
|
19522
|
+
push: booleanValue(permissions.push),
|
|
19523
|
+
triage: booleanValue(permissions.triage),
|
|
19524
|
+
pull: booleanValue(permissions.pull)
|
|
19525
|
+
} : void 0
|
|
19526
|
+
};
|
|
19527
|
+
}
|
|
19528
|
+
function isString(value) {
|
|
19529
|
+
return typeof value === "string";
|
|
19530
|
+
}
|
|
19531
|
+
var init_repos = __esm({
|
|
19532
|
+
"packages/github-primitive/src/actions/repos.ts"() {
|
|
19533
|
+
"use strict";
|
|
19534
|
+
init_utils();
|
|
19535
|
+
}
|
|
19536
|
+
});
|
|
19537
|
+
|
|
19538
|
+
// packages/github-primitive/src/actions/users.ts
|
|
19539
|
+
async function getUser(adapter, params = {}) {
|
|
19540
|
+
return withActionError("get GitHub user", async () => {
|
|
19541
|
+
const path25 = params.username ? `/users/${encodeURIComponent(assertNonEmptyString(params.username, "username"))}` : "/user";
|
|
19542
|
+
const response = await adapter.request("GET", path25);
|
|
19543
|
+
return mapUser(response);
|
|
19544
|
+
});
|
|
19545
|
+
}
|
|
19546
|
+
async function listOrganizations(adapter, params = {}) {
|
|
19547
|
+
return withActionError("list GitHub organizations", async () => {
|
|
19548
|
+
const path25 = params.username ? `/users/${encodeURIComponent(assertNonEmptyString(params.username, "username"))}/orgs` : "/user/orgs";
|
|
19549
|
+
const response = await adapter.request("GET", path25, {
|
|
19550
|
+
query: queryWithPerPage({}, params.perPage)
|
|
19551
|
+
});
|
|
19552
|
+
return asArray(response, "organizations").map(mapOrganization);
|
|
19553
|
+
});
|
|
19554
|
+
}
|
|
19555
|
+
function mapUser(value) {
|
|
19556
|
+
const user = asRecord(value, "user");
|
|
19557
|
+
const login = stringValue(user.login);
|
|
19558
|
+
if (!login) {
|
|
19559
|
+
throw new Error("GitHub user response did not include a login.");
|
|
19560
|
+
}
|
|
19561
|
+
return {
|
|
19562
|
+
login,
|
|
19563
|
+
name: optionalString(user.name),
|
|
19564
|
+
id: numberValue(user.id),
|
|
19565
|
+
type: optionalString(user.type)
|
|
19566
|
+
};
|
|
19567
|
+
}
|
|
19568
|
+
function mapOrganization(value) {
|
|
19569
|
+
const organization = asRecord(value, "organization");
|
|
19570
|
+
return {
|
|
19571
|
+
login: stringValue(organization.login),
|
|
19572
|
+
id: numberValue(organization.id),
|
|
19573
|
+
description: optionalString(organization.description),
|
|
19574
|
+
url: optionalString(organization.url),
|
|
19575
|
+
avatarUrl: optionalString(organization.avatar_url)
|
|
19576
|
+
};
|
|
19577
|
+
}
|
|
19578
|
+
var init_users = __esm({
|
|
19579
|
+
"packages/github-primitive/src/actions/users.ts"() {
|
|
19580
|
+
"use strict";
|
|
19581
|
+
init_utils();
|
|
19582
|
+
}
|
|
19583
|
+
});
|
|
19584
|
+
|
|
19585
|
+
// packages/github-primitive/src/local-runtime.ts
|
|
19586
|
+
var local_runtime_exports = {};
|
|
19587
|
+
__export(local_runtime_exports, {
|
|
19588
|
+
GhCliClient: () => GhCliClient,
|
|
19589
|
+
GhCliError: () => GhCliError
|
|
19590
|
+
});
|
|
19591
|
+
var import_node_child_process10, GhCliError, GhCliClient;
|
|
19592
|
+
var init_local_runtime = __esm({
|
|
19593
|
+
"packages/github-primitive/src/local-runtime.ts"() {
|
|
19594
|
+
"use strict";
|
|
19595
|
+
import_node_child_process10 = require("node:child_process");
|
|
19596
|
+
init_adapter();
|
|
19597
|
+
init_utils();
|
|
19598
|
+
init_types();
|
|
19599
|
+
GhCliError = class extends Error {
|
|
19600
|
+
command;
|
|
19601
|
+
args;
|
|
19602
|
+
exitCode;
|
|
19603
|
+
stdout;
|
|
19604
|
+
stderr;
|
|
19605
|
+
cause;
|
|
19606
|
+
constructor(message, options) {
|
|
19607
|
+
super(message);
|
|
19608
|
+
this.name = "GhCliError";
|
|
19609
|
+
this.command = options.command;
|
|
19610
|
+
this.args = options.args;
|
|
19611
|
+
this.exitCode = options.exitCode;
|
|
19612
|
+
this.stdout = options.stdout ?? "";
|
|
19613
|
+
this.stderr = options.stderr ?? "";
|
|
19614
|
+
this.cause = options.cause;
|
|
19615
|
+
}
|
|
19616
|
+
};
|
|
19617
|
+
GhCliClient = class extends BaseGitHubAdapter {
|
|
19618
|
+
constructor(config2 = {}) {
|
|
19619
|
+
super({
|
|
19620
|
+
...config2,
|
|
19621
|
+
runtime: "local"
|
|
19622
|
+
});
|
|
19623
|
+
}
|
|
19624
|
+
getRuntime() {
|
|
19625
|
+
return "local";
|
|
19626
|
+
}
|
|
19627
|
+
async isAuthenticated() {
|
|
19628
|
+
try {
|
|
19629
|
+
await this.runGhCommand(["auth", "status"], {
|
|
19630
|
+
parseJson: false,
|
|
19631
|
+
timeout: Math.min(this.config.timeout, 1e4)
|
|
19632
|
+
});
|
|
19633
|
+
return true;
|
|
19634
|
+
} catch {
|
|
19635
|
+
return false;
|
|
19636
|
+
}
|
|
19637
|
+
}
|
|
19638
|
+
async getCurrentUser() {
|
|
19639
|
+
const user = await this.request("GET", "/user");
|
|
19640
|
+
if (!user.login) {
|
|
19641
|
+
throw new GitHubApiError("GitHub user response did not include a login.");
|
|
19642
|
+
}
|
|
19643
|
+
return {
|
|
19644
|
+
login: user.login,
|
|
19645
|
+
name: user.name ?? void 0,
|
|
19646
|
+
id: user.id,
|
|
19647
|
+
type: user.type
|
|
19648
|
+
};
|
|
19649
|
+
}
|
|
19650
|
+
async request(method, path25, options = {}) {
|
|
19651
|
+
return this.executeWithRetries(async () => {
|
|
19652
|
+
const request = this.buildApiCommand(method, path25, options);
|
|
19653
|
+
const result = await this.runGhCommand(request.args, {
|
|
19654
|
+
input: request.input,
|
|
19655
|
+
parseJson: true,
|
|
19656
|
+
allowEmpty: true,
|
|
19657
|
+
timeout: options.timeout ?? this.config.timeout,
|
|
19658
|
+
signal: options.signal
|
|
19659
|
+
});
|
|
19660
|
+
return result.data;
|
|
19661
|
+
});
|
|
19662
|
+
}
|
|
19663
|
+
runGhCommand(args, options = {}) {
|
|
19664
|
+
const command = this.config.ghPath;
|
|
19665
|
+
const timeout = options.timeout ?? this.config.timeout;
|
|
19666
|
+
const env = {
|
|
19667
|
+
...process.env,
|
|
19668
|
+
...this.config.env,
|
|
19669
|
+
...options.env
|
|
19670
|
+
};
|
|
19671
|
+
return new Promise((resolve4, reject) => {
|
|
19672
|
+
const child = (0, import_node_child_process10.spawn)(command, args, {
|
|
19673
|
+
cwd: options.cwd ?? this.config.cwd,
|
|
19674
|
+
env,
|
|
19675
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
19676
|
+
});
|
|
19677
|
+
let stdout = "";
|
|
19678
|
+
let stderr = "";
|
|
19679
|
+
let finished = false;
|
|
19680
|
+
const finish = (callback) => {
|
|
19681
|
+
if (finished) {
|
|
19682
|
+
return;
|
|
19683
|
+
}
|
|
19684
|
+
finished = true;
|
|
19685
|
+
clearTimeout(timer);
|
|
19686
|
+
options.signal?.removeEventListener("abort", abort);
|
|
19687
|
+
callback();
|
|
19688
|
+
};
|
|
19689
|
+
const rejectWith = (error51) => {
|
|
19690
|
+
finish(() => reject(error51));
|
|
19691
|
+
};
|
|
19692
|
+
const abort = () => {
|
|
19693
|
+
child.kill("SIGTERM");
|
|
19694
|
+
rejectWith(
|
|
19695
|
+
new GhCliError(`gh command aborted: ${command} ${args.join(" ")}`, {
|
|
19696
|
+
command,
|
|
19697
|
+
args,
|
|
19698
|
+
stdout,
|
|
19699
|
+
stderr
|
|
19700
|
+
})
|
|
19701
|
+
);
|
|
19702
|
+
};
|
|
19703
|
+
const timer = setTimeout(() => {
|
|
19704
|
+
child.kill("SIGTERM");
|
|
19705
|
+
rejectWith(
|
|
19706
|
+
new GhCliError(`gh command timed out after ${timeout}ms: ${command} ${args.join(" ")}`, {
|
|
19707
|
+
command,
|
|
19708
|
+
args,
|
|
19709
|
+
stdout,
|
|
19710
|
+
stderr
|
|
19711
|
+
})
|
|
19712
|
+
);
|
|
19713
|
+
}, timeout);
|
|
19714
|
+
if (options.signal?.aborted) {
|
|
19715
|
+
abort();
|
|
19716
|
+
return;
|
|
19717
|
+
}
|
|
19718
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
19719
|
+
child.stdout.setEncoding("utf8");
|
|
19720
|
+
child.stderr.setEncoding("utf8");
|
|
19721
|
+
child.stdout.on("data", (chunk) => {
|
|
19722
|
+
stdout += chunk;
|
|
19723
|
+
});
|
|
19724
|
+
child.stderr.on("data", (chunk) => {
|
|
19725
|
+
stderr += chunk;
|
|
19726
|
+
});
|
|
19727
|
+
child.on("error", (error51) => {
|
|
19728
|
+
rejectWith(
|
|
19729
|
+
new GhCliError(`Failed to start gh command: ${error51.message}`, {
|
|
19730
|
+
command,
|
|
19731
|
+
args,
|
|
19732
|
+
stdout,
|
|
19733
|
+
stderr,
|
|
19734
|
+
cause: error51
|
|
19735
|
+
})
|
|
19736
|
+
);
|
|
19737
|
+
});
|
|
19738
|
+
child.on("close", (exitCode) => {
|
|
19739
|
+
if (finished) {
|
|
19740
|
+
return;
|
|
19741
|
+
}
|
|
19742
|
+
if (exitCode !== 0) {
|
|
19743
|
+
rejectWith(
|
|
19744
|
+
new GhCliError(stderr.trim() || `gh command failed with exit code ${exitCode}`, {
|
|
19745
|
+
command,
|
|
19746
|
+
args,
|
|
19747
|
+
exitCode: exitCode ?? void 0,
|
|
19748
|
+
stdout,
|
|
19749
|
+
stderr
|
|
19750
|
+
})
|
|
19751
|
+
);
|
|
19752
|
+
return;
|
|
19753
|
+
}
|
|
19754
|
+
try {
|
|
19755
|
+
const data = this.parseCommandOutput(stdout, options);
|
|
19756
|
+
finish(
|
|
19757
|
+
() => resolve4({
|
|
19758
|
+
args,
|
|
19759
|
+
command,
|
|
19760
|
+
exitCode: exitCode ?? 0,
|
|
19761
|
+
stdout,
|
|
19762
|
+
stderr,
|
|
19763
|
+
data
|
|
19764
|
+
})
|
|
19765
|
+
);
|
|
19766
|
+
} catch (error51) {
|
|
19767
|
+
rejectWith(
|
|
19768
|
+
new GhCliError(error51 instanceof Error ? error51.message : String(error51), {
|
|
19769
|
+
command,
|
|
19770
|
+
args,
|
|
19771
|
+
exitCode: exitCode ?? void 0,
|
|
19772
|
+
stdout,
|
|
19773
|
+
stderr,
|
|
19774
|
+
cause: error51
|
|
19775
|
+
})
|
|
19776
|
+
);
|
|
19777
|
+
}
|
|
19778
|
+
});
|
|
19779
|
+
if (typeof options.input === "string") {
|
|
19780
|
+
child.stdin.end(options.input);
|
|
19781
|
+
} else {
|
|
19782
|
+
child.stdin.end();
|
|
19783
|
+
}
|
|
19784
|
+
});
|
|
19785
|
+
}
|
|
19786
|
+
buildApiCommand(method, path25, options) {
|
|
19787
|
+
const args = [
|
|
19788
|
+
"api",
|
|
19789
|
+
appendQuery(path25, options.query),
|
|
19790
|
+
"--method",
|
|
19791
|
+
method,
|
|
19792
|
+
"--header",
|
|
19793
|
+
"Accept: application/vnd.github+json",
|
|
19794
|
+
"--header",
|
|
19795
|
+
"X-GitHub-Api-Version: 2022-11-28"
|
|
19796
|
+
];
|
|
19797
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
19798
|
+
args.push("--header", `${name}: ${value}`);
|
|
19799
|
+
}
|
|
19800
|
+
if (typeof options.body !== "undefined") {
|
|
19801
|
+
args.push("--input", "-");
|
|
19802
|
+
return {
|
|
19803
|
+
args,
|
|
19804
|
+
input: JSON.stringify(options.body)
|
|
19805
|
+
};
|
|
19806
|
+
}
|
|
19807
|
+
return { args };
|
|
19808
|
+
}
|
|
19809
|
+
parseCommandOutput(stdout, options) {
|
|
19810
|
+
if (options.parseJson === false) {
|
|
19811
|
+
return stdout;
|
|
19812
|
+
}
|
|
19813
|
+
const trimmed = stdout.trim();
|
|
19814
|
+
if (!trimmed) {
|
|
19815
|
+
if (options.allowEmpty) {
|
|
19816
|
+
return void 0;
|
|
19817
|
+
}
|
|
19818
|
+
throw new Error("gh command returned empty output where JSON was expected.");
|
|
19819
|
+
}
|
|
19820
|
+
try {
|
|
19821
|
+
return JSON.parse(trimmed);
|
|
19822
|
+
} catch (error51) {
|
|
19823
|
+
throw new Error(
|
|
19824
|
+
`Failed to parse gh JSON output: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
19825
|
+
);
|
|
19826
|
+
}
|
|
19827
|
+
}
|
|
19828
|
+
};
|
|
19829
|
+
}
|
|
19830
|
+
});
|
|
19831
|
+
|
|
19832
|
+
// packages/github-primitive/src/cloud-runtime.ts
|
|
19833
|
+
var cloud_runtime_exports = {};
|
|
19834
|
+
__export(cloud_runtime_exports, {
|
|
19835
|
+
NangoClient: () => NangoClient
|
|
19836
|
+
});
|
|
19837
|
+
async function parseJsonResponse(response) {
|
|
19838
|
+
const text = await response.text();
|
|
19839
|
+
if (!response.ok) {
|
|
19840
|
+
throw new GitHubApiError(
|
|
19841
|
+
text || `GitHub API request failed with ${response.status} ${response.statusText}`,
|
|
19842
|
+
{
|
|
19843
|
+
status: response.status,
|
|
19844
|
+
responseBody: text,
|
|
19845
|
+
responseHeaders: headersToRecord(response.headers)
|
|
19846
|
+
}
|
|
19847
|
+
);
|
|
19848
|
+
}
|
|
19849
|
+
if (!text.trim()) {
|
|
19850
|
+
return void 0;
|
|
19851
|
+
}
|
|
19852
|
+
try {
|
|
19853
|
+
return JSON.parse(text);
|
|
19854
|
+
} catch (error51) {
|
|
19855
|
+
throw new GitHubApiError(
|
|
19856
|
+
`Failed to parse GitHub API JSON response: ${error51 instanceof Error ? error51.message : String(error51)}`,
|
|
19857
|
+
{
|
|
19858
|
+
status: response.status,
|
|
19859
|
+
responseBody: text,
|
|
19860
|
+
responseHeaders: headersToRecord(response.headers),
|
|
19861
|
+
cause: error51
|
|
19862
|
+
}
|
|
19863
|
+
);
|
|
19864
|
+
}
|
|
19865
|
+
}
|
|
19866
|
+
function buildNangoProxyUrl(baseUrl, path25, query) {
|
|
19867
|
+
const base = trimTrailingSlash(baseUrl) ?? DEFAULT_NANGO_BASE_URL;
|
|
19868
|
+
const endpoint = stripLeadingSlash(path25);
|
|
19869
|
+
return appendQuery(`${base}/proxy/${endpoint}`, query);
|
|
19870
|
+
}
|
|
19871
|
+
function joinUrl(baseUrl, path25) {
|
|
19872
|
+
return `${trimTrailingSlash(baseUrl) ?? baseUrl}/${stripLeadingSlash(path25)}`;
|
|
19873
|
+
}
|
|
19874
|
+
function stripLeadingSlash(value) {
|
|
19875
|
+
return value.replace(/^\/+/, "");
|
|
19876
|
+
}
|
|
19877
|
+
function headersToRecord(headers) {
|
|
19878
|
+
const record2 = {};
|
|
19879
|
+
headers.forEach((value, key) => {
|
|
19880
|
+
record2[key] = value;
|
|
19881
|
+
});
|
|
19882
|
+
return record2;
|
|
19883
|
+
}
|
|
19884
|
+
function errorMessage2(error51) {
|
|
19885
|
+
return error51 instanceof Error ? error51.message : String(error51);
|
|
19886
|
+
}
|
|
19887
|
+
var NangoClient;
|
|
19888
|
+
var init_cloud_runtime = __esm({
|
|
19889
|
+
"packages/github-primitive/src/cloud-runtime.ts"() {
|
|
19890
|
+
"use strict";
|
|
19891
|
+
init_adapter();
|
|
19892
|
+
init_utils();
|
|
19893
|
+
init_constants();
|
|
19894
|
+
init_types();
|
|
19895
|
+
NangoClient = class extends BaseGitHubAdapter {
|
|
19896
|
+
lastNangoFallbackError;
|
|
19897
|
+
constructor(config2 = {}) {
|
|
19898
|
+
super({
|
|
19899
|
+
...config2,
|
|
19900
|
+
runtime: "cloud"
|
|
19901
|
+
});
|
|
19902
|
+
}
|
|
19903
|
+
getRuntime() {
|
|
19904
|
+
return "cloud";
|
|
19905
|
+
}
|
|
19906
|
+
async isAuthenticated() {
|
|
19907
|
+
try {
|
|
19908
|
+
await this.getCurrentUser();
|
|
19909
|
+
return true;
|
|
19910
|
+
} catch {
|
|
19911
|
+
return false;
|
|
19912
|
+
}
|
|
19913
|
+
}
|
|
19914
|
+
async getCurrentUser() {
|
|
19915
|
+
const user = await this.request("GET", "/user");
|
|
19916
|
+
if (!user.login) {
|
|
19917
|
+
throw new GitHubApiError("GitHub user response did not include a login.");
|
|
19918
|
+
}
|
|
19919
|
+
return {
|
|
19920
|
+
login: user.login,
|
|
19921
|
+
name: user.name ?? void 0,
|
|
19922
|
+
id: user.id,
|
|
19923
|
+
type: user.type
|
|
19924
|
+
};
|
|
19925
|
+
}
|
|
19926
|
+
async request(method, path25, options = {}) {
|
|
19927
|
+
return this.executeWithRetries(async () => {
|
|
19928
|
+
if (this.hasNangoCredentials()) {
|
|
19929
|
+
try {
|
|
19930
|
+
return await this.requestViaNango(method, path25, options);
|
|
19931
|
+
} catch (error51) {
|
|
19932
|
+
if (!this.hasRelayCloudCredentials()) {
|
|
19933
|
+
throw error51;
|
|
19934
|
+
}
|
|
19935
|
+
this.lastNangoFallbackError = error51;
|
|
19936
|
+
try {
|
|
19937
|
+
return await this.requestViaRelayCloud(method, path25, options);
|
|
19938
|
+
} catch (relayError) {
|
|
19939
|
+
throw new GitHubApiError(
|
|
19940
|
+
`Nango GitHub proxy failed, then relay-cloud fallback failed: ${errorMessage2(relayError)}`,
|
|
19941
|
+
{
|
|
19942
|
+
cause: {
|
|
19943
|
+
nango: error51,
|
|
19944
|
+
relayCloud: relayError
|
|
19945
|
+
}
|
|
19946
|
+
}
|
|
19947
|
+
);
|
|
19948
|
+
}
|
|
19949
|
+
}
|
|
19950
|
+
}
|
|
19951
|
+
if (this.hasRelayCloudCredentials()) {
|
|
19952
|
+
return this.requestViaRelayCloud(method, path25, options);
|
|
19953
|
+
}
|
|
19954
|
+
throw new GitHubApiError(
|
|
19955
|
+
"Cloud GitHub runtime requires Nango credentials or relay-cloud proxy configuration."
|
|
19956
|
+
);
|
|
19957
|
+
});
|
|
19958
|
+
}
|
|
19959
|
+
/**
|
|
19960
|
+
* Returns the most recent Nango failure that triggered a relay-cloud fallback.
|
|
19961
|
+
*/
|
|
19962
|
+
getLastNangoFallbackError() {
|
|
19963
|
+
return this.lastNangoFallbackError;
|
|
19964
|
+
}
|
|
19965
|
+
async requestViaNango(method, path25, options) {
|
|
19966
|
+
const secretKey = this.config.nango.secretKey;
|
|
19967
|
+
const connectionId = this.config.nango.connectionId;
|
|
19968
|
+
const providerConfigKey = this.config.nango.providerConfigKey;
|
|
19969
|
+
if (!secretKey || !connectionId || !providerConfigKey) {
|
|
19970
|
+
throw new GitHubApiError("Nango GitHub proxy requires secretKey, connectionId, and providerConfigKey.");
|
|
19971
|
+
}
|
|
19972
|
+
const url2 = buildNangoProxyUrl(this.config.nango.baseUrl, path25, options.query);
|
|
19973
|
+
const response = await this.fetchWithTimeout(url2, {
|
|
19974
|
+
method,
|
|
19975
|
+
headers: {
|
|
19976
|
+
Authorization: `Bearer ${secretKey}`,
|
|
19977
|
+
"Connection-Id": connectionId,
|
|
19978
|
+
"Provider-Config-Key": providerConfigKey,
|
|
19979
|
+
Accept: "application/json",
|
|
19980
|
+
"Content-Type": "application/json",
|
|
19981
|
+
"User-Agent": this.config.userAgent,
|
|
19982
|
+
...options.headers
|
|
19983
|
+
},
|
|
19984
|
+
body: typeof options.body === "undefined" ? void 0 : JSON.stringify(options.body),
|
|
19985
|
+
signal: options.signal,
|
|
19986
|
+
timeout: options.timeout
|
|
19987
|
+
});
|
|
19988
|
+
return parseJsonResponse(response);
|
|
19989
|
+
}
|
|
19990
|
+
async requestViaRelayCloud(method, path25, options) {
|
|
19991
|
+
const apiUrl = this.config.relayCloud.apiUrl;
|
|
19992
|
+
const accessToken = this.config.relayCloud.accessToken;
|
|
19993
|
+
const endpoint = this.config.relayCloud.endpoint ?? DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT;
|
|
19994
|
+
if (!apiUrl || !accessToken) {
|
|
19995
|
+
throw new GitHubApiError("Relay cloud GitHub proxy requires apiUrl and accessToken configuration.");
|
|
19996
|
+
}
|
|
19997
|
+
const payload = {
|
|
19998
|
+
method,
|
|
19999
|
+
path: path25,
|
|
20000
|
+
query: options.query,
|
|
20001
|
+
body: options.body,
|
|
20002
|
+
headers: options.headers,
|
|
20003
|
+
nango: {
|
|
20004
|
+
connectionId: this.config.nango.connectionId,
|
|
20005
|
+
providerConfigKey: this.config.nango.providerConfigKey
|
|
20006
|
+
}
|
|
20007
|
+
};
|
|
20008
|
+
const response = await this.fetchWithTimeout(joinUrl(apiUrl, endpoint), {
|
|
20009
|
+
method: "POST",
|
|
20010
|
+
headers: {
|
|
20011
|
+
Authorization: `Bearer ${accessToken}`,
|
|
20012
|
+
Accept: "application/json",
|
|
20013
|
+
"Content-Type": "application/json",
|
|
20014
|
+
"User-Agent": this.config.userAgent,
|
|
20015
|
+
...this.config.relayCloud.workspaceId ? { "X-Relay-Workspace-Id": this.config.relayCloud.workspaceId } : {}
|
|
20016
|
+
},
|
|
20017
|
+
body: JSON.stringify(payload),
|
|
20018
|
+
signal: options.signal,
|
|
20019
|
+
timeout: options.timeout
|
|
20020
|
+
});
|
|
20021
|
+
const result = await parseJsonResponse(response);
|
|
20022
|
+
if (typeof result === "object" && result !== null && "data" in result && Object.keys(result).some((key) => key === "data")) {
|
|
20023
|
+
return result.data;
|
|
20024
|
+
}
|
|
20025
|
+
return result;
|
|
20026
|
+
}
|
|
20027
|
+
async fetchWithTimeout(input, init) {
|
|
20028
|
+
const fetchImpl = this.config.fetch ?? fetch;
|
|
20029
|
+
const timeout = init.timeout ?? this.config.timeout;
|
|
20030
|
+
const signal = init.signal ?? AbortSignal.timeout(timeout);
|
|
20031
|
+
const { timeout: _timeout, ...requestInit } = init;
|
|
20032
|
+
return fetchImpl(input, {
|
|
20033
|
+
...requestInit,
|
|
20034
|
+
signal
|
|
20035
|
+
});
|
|
20036
|
+
}
|
|
20037
|
+
hasNangoCredentials() {
|
|
20038
|
+
return Boolean(
|
|
20039
|
+
this.config.nango.secretKey && this.config.nango.connectionId && this.config.nango.providerConfigKey
|
|
20040
|
+
);
|
|
20041
|
+
}
|
|
20042
|
+
hasRelayCloudCredentials() {
|
|
20043
|
+
return Boolean(this.config.relayCloud.apiUrl && this.config.relayCloud.accessToken);
|
|
20044
|
+
}
|
|
20045
|
+
};
|
|
20046
|
+
}
|
|
20047
|
+
});
|
|
20048
|
+
|
|
20049
|
+
// packages/github-primitive/src/adapter.ts
|
|
20050
|
+
function normalizeGitHubRuntimeConfig(config2 = {}) {
|
|
20051
|
+
const env = config2.env ?? process.env;
|
|
20052
|
+
const nango = config2.nango ?? {};
|
|
20053
|
+
const relayCloud = config2.relayCloud ?? {};
|
|
20054
|
+
return {
|
|
20055
|
+
...config2,
|
|
20056
|
+
runtime: config2.runtime ?? "auto",
|
|
20057
|
+
ghPath: nonEmpty(config2.ghPath) ?? nonEmpty(env.GH_PATH) ?? DEFAULT_GH_PATH,
|
|
20058
|
+
cwd: config2.cwd,
|
|
20059
|
+
env,
|
|
20060
|
+
timeout: config2.timeout ?? DEFAULT_TIMEOUT,
|
|
20061
|
+
retryOnRateLimit: config2.retryOnRateLimit ?? true,
|
|
20062
|
+
maxRetries: config2.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
20063
|
+
userAgent: config2.userAgent ?? DEFAULT_USER_AGENT,
|
|
20064
|
+
fetch: config2.fetch,
|
|
20065
|
+
nango: {
|
|
20066
|
+
connectionId: nonEmpty(nango.connectionId) ?? nonEmpty(env.NANGO_GITHUB_CONNECTION_ID) ?? nonEmpty(env.GITHUB_NANGO_CONNECTION_ID) ?? nonEmpty(env.NANGO_CONNECTION_ID),
|
|
20067
|
+
providerConfigKey: nonEmpty(nango.providerConfigKey) ?? nonEmpty(env.NANGO_GITHUB_PROVIDER_CONFIG_KEY) ?? nonEmpty(env.GITHUB_NANGO_PROVIDER_CONFIG_KEY) ?? nonEmpty(env.NANGO_PROVIDER_CONFIG_KEY) ?? DEFAULT_NANGO_PROVIDER_CONFIG_KEY,
|
|
20068
|
+
secretKey: nonEmpty(nango.secretKey) ?? nonEmpty(env.NANGO_SECRET_KEY),
|
|
20069
|
+
baseUrl: trimTrailingSlash(nonEmpty(nango.baseUrl) ?? nonEmpty(env.NANGO_HOST)) ?? DEFAULT_NANGO_BASE_URL
|
|
20070
|
+
},
|
|
20071
|
+
relayCloud: {
|
|
20072
|
+
apiUrl: trimTrailingSlash(
|
|
20073
|
+
nonEmpty(relayCloud.apiUrl) ?? nonEmpty(env.RELAY_CLOUD_API_URL) ?? nonEmpty(env.CLOUD_API_URL)
|
|
20074
|
+
) ?? void 0,
|
|
20075
|
+
accessToken: nonEmpty(relayCloud.accessToken) ?? nonEmpty(env.RELAY_CLOUD_API_TOKEN) ?? nonEmpty(env.CLOUD_API_ACCESS_TOKEN) ?? nonEmpty(env.WORKSPACE_TOKEN),
|
|
20076
|
+
workspaceId: nonEmpty(relayCloud.workspaceId) ?? nonEmpty(env.WORKSPACE_ID),
|
|
20077
|
+
workspaceToken: nonEmpty(relayCloud.workspaceToken) ?? nonEmpty(env.WORKSPACE_TOKEN),
|
|
20078
|
+
endpoint: nonEmpty(relayCloud.endpoint) ?? nonEmpty(env.RELAY_CLOUD_GITHUB_PROXY_ENDPOINT) ?? DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT
|
|
20079
|
+
}
|
|
20080
|
+
};
|
|
20081
|
+
}
|
|
20082
|
+
function detectGitHubRuntime(config2 = {}) {
|
|
20083
|
+
return GitHubRuntimeDetector.detect(config2);
|
|
20084
|
+
}
|
|
20085
|
+
function createGitHubAdapter(config2 = {}) {
|
|
20086
|
+
return GitHubAdapterFactory.create(config2);
|
|
20087
|
+
}
|
|
20088
|
+
async function testLocalRuntime(config2) {
|
|
20089
|
+
try {
|
|
20090
|
+
const { stdout } = await execFileAsync2(config2.ghPath, ["--version"], {
|
|
20091
|
+
cwd: config2.cwd,
|
|
20092
|
+
env: config2.env,
|
|
20093
|
+
timeout: Math.min(config2.timeout, 5e3),
|
|
20094
|
+
maxBuffer: 1024 * 1024
|
|
20095
|
+
});
|
|
20096
|
+
const version2 = String(stdout).split("\n")[0]?.trim();
|
|
20097
|
+
return {
|
|
20098
|
+
runtime: "local",
|
|
20099
|
+
available: true,
|
|
20100
|
+
reason: version2 ? `gh CLI available: ${version2}` : "gh CLI available.",
|
|
20101
|
+
details: version2 ? { version: version2 } : void 0
|
|
20102
|
+
};
|
|
20103
|
+
} catch (error51) {
|
|
20104
|
+
return {
|
|
20105
|
+
runtime: "local",
|
|
20106
|
+
available: false,
|
|
20107
|
+
reason: `gh CLI was not available at "${config2.ghPath}".`,
|
|
20108
|
+
error: errorMessage3(error51)
|
|
20109
|
+
};
|
|
20110
|
+
}
|
|
20111
|
+
}
|
|
20112
|
+
async function testCloudRuntime(config2) {
|
|
20113
|
+
if (hasNangoConfig(config2)) {
|
|
20114
|
+
return {
|
|
20115
|
+
runtime: "cloud",
|
|
20116
|
+
available: true,
|
|
20117
|
+
reason: "Nango configuration is available.",
|
|
20118
|
+
details: {
|
|
20119
|
+
providerConfigKey: config2.nango.providerConfigKey ?? DEFAULT_NANGO_PROVIDER_CONFIG_KEY,
|
|
20120
|
+
hasConnectionId: Boolean(config2.nango.connectionId)
|
|
20121
|
+
}
|
|
20122
|
+
};
|
|
20123
|
+
}
|
|
20124
|
+
if (hasRelayCloudConfig(config2)) {
|
|
20125
|
+
return {
|
|
20126
|
+
runtime: "cloud",
|
|
20127
|
+
available: true,
|
|
20128
|
+
reason: "Relay cloud API configuration is available.",
|
|
20129
|
+
details: {
|
|
20130
|
+
endpoint: config2.relayCloud.endpoint ?? DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT,
|
|
20131
|
+
hasWorkspaceId: Boolean(config2.relayCloud.workspaceId)
|
|
20132
|
+
}
|
|
20133
|
+
};
|
|
20134
|
+
}
|
|
20135
|
+
return {
|
|
20136
|
+
runtime: "cloud",
|
|
20137
|
+
available: false,
|
|
20138
|
+
reason: "No Nango or relay-cloud GitHub proxy configuration was found."
|
|
20139
|
+
};
|
|
20140
|
+
}
|
|
20141
|
+
function detectionResult(input) {
|
|
20142
|
+
return {
|
|
20143
|
+
runtime: input.runtime,
|
|
20144
|
+
requestedRuntime: input.requestedRuntime,
|
|
20145
|
+
source: input.source,
|
|
20146
|
+
available: input.selected.available,
|
|
20147
|
+
reason: input.reason,
|
|
20148
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20149
|
+
local: input.local,
|
|
20150
|
+
cloud: input.cloud
|
|
20151
|
+
};
|
|
20152
|
+
}
|
|
20153
|
+
function hasNangoConfig(config2) {
|
|
20154
|
+
return Boolean(config2.nango.secretKey);
|
|
20155
|
+
}
|
|
20156
|
+
function hasRelayCloudConfig(config2) {
|
|
20157
|
+
return Boolean(config2.relayCloud.apiUrl && config2.relayCloud.accessToken);
|
|
20158
|
+
}
|
|
20159
|
+
function hasCloudEnvironment(env) {
|
|
20160
|
+
return Boolean(
|
|
20161
|
+
env.WORKSPACE_ID || env.CLOUD_API_URL || env.VERCEL || env.RAILWAY_ENVIRONMENT || env.FLY_APP_NAME || env.AWS_REGION || env.GOOGLE_CLOUD_PROJECT || env.NODE_ENV === "production"
|
|
20162
|
+
);
|
|
20163
|
+
}
|
|
20164
|
+
function statusFromError(error51) {
|
|
20165
|
+
if (error51 instanceof GitHubApiError) {
|
|
20166
|
+
return error51.status;
|
|
20167
|
+
}
|
|
20168
|
+
if (typeof error51 === "object" && error51 !== null && "status" in error51) {
|
|
20169
|
+
const status = error51.status;
|
|
20170
|
+
return typeof status === "number" ? status : void 0;
|
|
20171
|
+
}
|
|
20172
|
+
return void 0;
|
|
20173
|
+
}
|
|
20174
|
+
function resetHeaderFromError(error51) {
|
|
20175
|
+
const headers = error51 instanceof GitHubApiError ? error51.responseHeaders : typeof error51 === "object" && error51 !== null && "responseHeaders" in error51 ? error51.responseHeaders : void 0;
|
|
20176
|
+
return headers?.["x-ratelimit-reset"] ?? headers?.["X-RateLimit-Reset"];
|
|
20177
|
+
}
|
|
20178
|
+
function stringifyOutput(value) {
|
|
20179
|
+
if (typeof value === "string") {
|
|
20180
|
+
return value;
|
|
20181
|
+
}
|
|
20182
|
+
if (typeof value === "undefined") {
|
|
20183
|
+
return "";
|
|
20184
|
+
}
|
|
20185
|
+
return JSON.stringify(value);
|
|
20186
|
+
}
|
|
20187
|
+
function errorMessage3(error51) {
|
|
20188
|
+
return error51 instanceof Error ? error51.message : String(error51);
|
|
20189
|
+
}
|
|
20190
|
+
function delay3(ms2) {
|
|
20191
|
+
return new Promise((resolve4) => {
|
|
20192
|
+
setTimeout(resolve4, ms2);
|
|
20193
|
+
});
|
|
20194
|
+
}
|
|
20195
|
+
var import_node_child_process11, import_node_util4, execFileAsync2, GitHubRuntimeDetector, BaseGitHubAdapter, GitHubAdapterFactory, GitHubClientFactory;
|
|
20196
|
+
var init_adapter = __esm({
|
|
20197
|
+
"packages/github-primitive/src/adapter.ts"() {
|
|
20198
|
+
"use strict";
|
|
20199
|
+
import_node_child_process11 = require("node:child_process");
|
|
20200
|
+
import_node_util4 = require("node:util");
|
|
20201
|
+
init_branches();
|
|
20202
|
+
init_commits();
|
|
20203
|
+
init_files();
|
|
20204
|
+
init_issues();
|
|
20205
|
+
init_pulls();
|
|
20206
|
+
init_repos();
|
|
20207
|
+
init_users();
|
|
20208
|
+
init_utils();
|
|
20209
|
+
init_constants();
|
|
20210
|
+
init_types();
|
|
20211
|
+
execFileAsync2 = (0, import_node_util4.promisify)(import_node_child_process11.execFile);
|
|
20212
|
+
GitHubRuntimeDetector = class {
|
|
20213
|
+
static async detect(config2 = {}) {
|
|
20214
|
+
const normalized = normalizeGitHubRuntimeConfig(config2);
|
|
20215
|
+
const [local, cloud] = await Promise.all([
|
|
20216
|
+
this.testRuntime("local", normalized),
|
|
20217
|
+
this.testRuntime("cloud", normalized)
|
|
20218
|
+
]);
|
|
20219
|
+
const requestedRuntime = normalized.runtime;
|
|
20220
|
+
if (requestedRuntime === "local" || requestedRuntime === "cloud") {
|
|
20221
|
+
const selected = requestedRuntime === "local" ? local : cloud;
|
|
20222
|
+
return detectionResult({
|
|
20223
|
+
runtime: requestedRuntime,
|
|
20224
|
+
requestedRuntime,
|
|
20225
|
+
source: "config",
|
|
20226
|
+
selected,
|
|
20227
|
+
local,
|
|
20228
|
+
cloud,
|
|
20229
|
+
reason: selected.available ? `Runtime explicitly configured as ${requestedRuntime}.` : `Runtime explicitly configured as ${requestedRuntime}, but availability check failed: ${selected.reason}`
|
|
20230
|
+
});
|
|
20231
|
+
}
|
|
20232
|
+
if (hasNangoConfig(normalized)) {
|
|
20233
|
+
return detectionResult({
|
|
20234
|
+
runtime: "cloud",
|
|
20235
|
+
requestedRuntime,
|
|
20236
|
+
source: "nango",
|
|
20237
|
+
selected: cloud,
|
|
20238
|
+
local,
|
|
20239
|
+
cloud,
|
|
20240
|
+
reason: cloud.available ? "Using cloud runtime because Nango configuration is available." : `Cloud runtime selected from Nango configuration, but availability check failed: ${cloud.reason}`
|
|
20241
|
+
});
|
|
20242
|
+
}
|
|
20243
|
+
if (hasCloudEnvironment(normalized.env)) {
|
|
20244
|
+
if (cloud.available) {
|
|
20245
|
+
return detectionResult({
|
|
20246
|
+
runtime: "cloud",
|
|
20247
|
+
requestedRuntime,
|
|
20248
|
+
source: "environment",
|
|
20249
|
+
selected: cloud,
|
|
20250
|
+
local,
|
|
20251
|
+
cloud,
|
|
20252
|
+
reason: "Using cloud runtime because a cloud workspace or deployment environment was detected."
|
|
20253
|
+
});
|
|
20254
|
+
}
|
|
20255
|
+
if (local.available) {
|
|
20256
|
+
return detectionResult({
|
|
20257
|
+
runtime: "local",
|
|
20258
|
+
requestedRuntime,
|
|
20259
|
+
source: "gh-cli",
|
|
20260
|
+
selected: local,
|
|
20261
|
+
local,
|
|
20262
|
+
cloud,
|
|
20263
|
+
reason: "Cloud environment was detected, but cloud credentials were unavailable; using local gh CLI."
|
|
20264
|
+
});
|
|
20265
|
+
}
|
|
20266
|
+
}
|
|
20267
|
+
if (local.available) {
|
|
20268
|
+
return detectionResult({
|
|
20269
|
+
runtime: "local",
|
|
20270
|
+
requestedRuntime,
|
|
20271
|
+
source: "gh-cli",
|
|
20272
|
+
selected: local,
|
|
20273
|
+
local,
|
|
20274
|
+
cloud,
|
|
20275
|
+
reason: "Using local runtime because gh CLI is available."
|
|
20276
|
+
});
|
|
20277
|
+
}
|
|
20278
|
+
return detectionResult({
|
|
20279
|
+
runtime: "cloud",
|
|
20280
|
+
requestedRuntime,
|
|
20281
|
+
source: "fallback",
|
|
20282
|
+
selected: cloud,
|
|
20283
|
+
local,
|
|
20284
|
+
cloud,
|
|
20285
|
+
reason: cloud.available ? "Using cloud runtime because local gh CLI was unavailable." : "Falling back to cloud runtime because local gh CLI was unavailable; cloud credentials may still be required."
|
|
20286
|
+
});
|
|
20287
|
+
}
|
|
20288
|
+
static async testRuntime(runtime, config2 = {}) {
|
|
20289
|
+
const normalized = normalizeGitHubRuntimeConfig(config2);
|
|
20290
|
+
if (runtime === "local") {
|
|
20291
|
+
return testLocalRuntime(normalized);
|
|
20292
|
+
}
|
|
20293
|
+
return testCloudRuntime(normalized);
|
|
20294
|
+
}
|
|
20295
|
+
static async detectRuntime(config2 = {}) {
|
|
20296
|
+
const result = await this.detect(config2);
|
|
20297
|
+
return result.runtime;
|
|
20298
|
+
}
|
|
20299
|
+
};
|
|
20300
|
+
BaseGitHubAdapter = class extends GitHubClientInterface {
|
|
20301
|
+
retryUsed = false;
|
|
20302
|
+
constructor(config2 = {}) {
|
|
20303
|
+
super(normalizeGitHubRuntimeConfig(config2));
|
|
20304
|
+
}
|
|
20305
|
+
async executeAction(action, params) {
|
|
20306
|
+
const startedAt = Date.now();
|
|
20307
|
+
this.retryUsed = false;
|
|
20308
|
+
try {
|
|
20309
|
+
const data = await this.dispatchAction(action, params);
|
|
20310
|
+
return {
|
|
20311
|
+
success: true,
|
|
20312
|
+
output: stringifyOutput(data),
|
|
20313
|
+
data,
|
|
20314
|
+
metadata: {
|
|
20315
|
+
runtime: this.getRuntime(),
|
|
20316
|
+
executionTime: Date.now() - startedAt,
|
|
20317
|
+
retried: this.retryUsed
|
|
20318
|
+
}
|
|
20319
|
+
};
|
|
20320
|
+
} catch (error51) {
|
|
20321
|
+
return {
|
|
20322
|
+
success: false,
|
|
20323
|
+
output: "",
|
|
20324
|
+
error: errorMessage3(error51),
|
|
20325
|
+
metadata: {
|
|
20326
|
+
runtime: this.getRuntime(),
|
|
20327
|
+
executionTime: Date.now() - startedAt,
|
|
20328
|
+
retried: this.retryUsed
|
|
20329
|
+
}
|
|
20330
|
+
};
|
|
20331
|
+
}
|
|
20332
|
+
}
|
|
20333
|
+
async listRepositories(params = {}) {
|
|
20334
|
+
return listRepos(this, params);
|
|
20335
|
+
}
|
|
20336
|
+
async getRepository(params) {
|
|
20337
|
+
return getRepo(this, params.owner, params.repo);
|
|
20338
|
+
}
|
|
20339
|
+
async listIssues(params) {
|
|
20340
|
+
const { owner, repo, ...options } = params;
|
|
20341
|
+
return listIssues(this, owner, repo, options);
|
|
20342
|
+
}
|
|
20343
|
+
async createIssue(params) {
|
|
20344
|
+
const { owner, repo, title, body, ...options } = params;
|
|
20345
|
+
return createIssue(this, owner, repo, title, body, options);
|
|
20346
|
+
}
|
|
20347
|
+
async updateIssue(params) {
|
|
20348
|
+
const { owner, repo, issueNumber, ...updates } = params;
|
|
20349
|
+
return updateIssue(this, owner, repo, issueNumber, updates);
|
|
20350
|
+
}
|
|
20351
|
+
async closeIssue(params) {
|
|
20352
|
+
return updateIssue(this, params.owner, params.repo, params.issueNumber, {
|
|
20353
|
+
state: "closed"
|
|
20354
|
+
});
|
|
20355
|
+
}
|
|
20356
|
+
async listPullRequests(params) {
|
|
20357
|
+
const { owner, repo, ...options } = params;
|
|
20358
|
+
return listPRs(this, owner, repo, options);
|
|
20359
|
+
}
|
|
20360
|
+
async getPullRequest(params) {
|
|
20361
|
+
return getPR(this, params.owner, params.repo, params.pullNumber);
|
|
20362
|
+
}
|
|
20363
|
+
async createPullRequest(params) {
|
|
20364
|
+
const { owner, repo, title, body, base, head, ...options } = params;
|
|
20365
|
+
return createPR(this, owner, repo, title, body, base, head, options);
|
|
20366
|
+
}
|
|
20367
|
+
async updatePullRequest(params) {
|
|
20368
|
+
const { owner, repo, pullNumber, ...updates } = params;
|
|
20369
|
+
return updatePR(this, owner, repo, pullNumber, updates);
|
|
20370
|
+
}
|
|
20371
|
+
async mergePullRequest(params) {
|
|
20372
|
+
const { owner, repo, pullNumber, ...options } = params;
|
|
20373
|
+
return mergePR(this, owner, repo, pullNumber, options);
|
|
20374
|
+
}
|
|
20375
|
+
async listFiles(params) {
|
|
20376
|
+
const { owner, repo, path: path25, ...options } = params;
|
|
20377
|
+
return listFiles(this, owner, repo, path25, options);
|
|
20378
|
+
}
|
|
20379
|
+
async readFile(params) {
|
|
20380
|
+
return readFile3(this, params.owner, params.repo, params.path, params.ref);
|
|
20381
|
+
}
|
|
20382
|
+
async createFile(params) {
|
|
20383
|
+
const { owner, repo, path: path25, content, message, ...options } = params;
|
|
20384
|
+
return createFile(this, owner, repo, path25, content, message, options);
|
|
20385
|
+
}
|
|
20386
|
+
async updateFile(params) {
|
|
20387
|
+
const { owner, repo, path: path25, content, message, sha, ...options } = params;
|
|
20388
|
+
return updateFile(this, owner, repo, path25, content, message, sha, options);
|
|
20389
|
+
}
|
|
20390
|
+
async deleteFile(params) {
|
|
20391
|
+
const { owner, repo, path: path25, sha, message, ...options } = params;
|
|
20392
|
+
return deleteFile(this, owner, repo, path25, sha, message, options);
|
|
20393
|
+
}
|
|
20394
|
+
async listBranches(params) {
|
|
20395
|
+
return listBranches(this, params.owner, params.repo);
|
|
20396
|
+
}
|
|
20397
|
+
async createBranch(params) {
|
|
20398
|
+
return createBranch(this, params);
|
|
20399
|
+
}
|
|
20400
|
+
async listCommits(params) {
|
|
20401
|
+
return listCommits(this, params);
|
|
20402
|
+
}
|
|
20403
|
+
async createCommit(params) {
|
|
20404
|
+
return createCommit(this, params);
|
|
20405
|
+
}
|
|
20406
|
+
async getUser(params) {
|
|
20407
|
+
return getUser(this, params);
|
|
20408
|
+
}
|
|
20409
|
+
async listOrganizations(params) {
|
|
20410
|
+
return listOrganizations(this, params);
|
|
20411
|
+
}
|
|
20412
|
+
async executeWithRetries(operation) {
|
|
20413
|
+
const maxRetries = this.config.retryOnRateLimit ? this.config.maxRetries : 0;
|
|
20414
|
+
let attempt = 0;
|
|
20415
|
+
while (true) {
|
|
20416
|
+
try {
|
|
20417
|
+
return await operation();
|
|
20418
|
+
} catch (error51) {
|
|
20419
|
+
if (attempt >= maxRetries || !this.isRetryableError(error51)) {
|
|
20420
|
+
throw error51;
|
|
20421
|
+
}
|
|
20422
|
+
attempt += 1;
|
|
20423
|
+
this.retryUsed = true;
|
|
20424
|
+
await delay3(this.retryDelayMs(attempt, error51));
|
|
20425
|
+
}
|
|
20426
|
+
}
|
|
20427
|
+
}
|
|
20428
|
+
isRetryableError(error51) {
|
|
20429
|
+
const status = statusFromError(error51);
|
|
20430
|
+
return status === 403 || status === 429 || typeof status === "number" && status >= 500;
|
|
20431
|
+
}
|
|
20432
|
+
retryDelayMs(attempt, error51) {
|
|
20433
|
+
const reset = resetHeaderFromError(error51);
|
|
20434
|
+
if (reset) {
|
|
20435
|
+
const resetMs = Number(reset) * 1e3;
|
|
20436
|
+
if (Number.isFinite(resetMs) && resetMs > Date.now()) {
|
|
20437
|
+
return Math.min(resetMs - Date.now(), 6e4);
|
|
20438
|
+
}
|
|
20439
|
+
}
|
|
20440
|
+
return Math.min(500 * 2 ** (attempt - 1), 1e4);
|
|
20441
|
+
}
|
|
20442
|
+
async dispatchAction(action, params) {
|
|
20443
|
+
switch (action) {
|
|
20444
|
+
case "listRepos" /* ListRepos */:
|
|
20445
|
+
return this.listRepositories(params);
|
|
20446
|
+
case "getRepo" /* GetRepo */:
|
|
20447
|
+
return this.getRepository(params);
|
|
20448
|
+
case "listIssues" /* ListIssues */:
|
|
20449
|
+
return this.listIssues(params);
|
|
20450
|
+
case "createIssue" /* CreateIssue */:
|
|
20451
|
+
return this.createIssue(params);
|
|
20452
|
+
case "updateIssue" /* UpdateIssue */:
|
|
20453
|
+
return this.updateIssue(params);
|
|
20454
|
+
case "closeIssue" /* CloseIssue */:
|
|
20455
|
+
return this.closeIssue(params);
|
|
20456
|
+
case "listPRs" /* ListPRs */:
|
|
20457
|
+
return this.listPullRequests(params);
|
|
20458
|
+
case "getPR" /* GetPR */:
|
|
20459
|
+
return this.getPullRequest(params);
|
|
20460
|
+
case "createPR" /* CreatePR */:
|
|
20461
|
+
return this.createPullRequest(params);
|
|
20462
|
+
case "updatePR" /* UpdatePR */:
|
|
20463
|
+
return this.updatePullRequest(params);
|
|
20464
|
+
case "mergePR" /* MergePR */:
|
|
20465
|
+
return this.mergePullRequest(params);
|
|
20466
|
+
case "listFiles" /* ListFiles */:
|
|
20467
|
+
return this.listFiles(params);
|
|
20468
|
+
case "readFile" /* ReadFile */:
|
|
20469
|
+
return this.readFile(params);
|
|
20470
|
+
case "createFile" /* CreateFile */:
|
|
20471
|
+
return this.createFile(params);
|
|
20472
|
+
case "updateFile" /* UpdateFile */:
|
|
20473
|
+
return this.updateFile(params);
|
|
20474
|
+
case "deleteFile" /* DeleteFile */:
|
|
20475
|
+
return this.deleteFile(params);
|
|
20476
|
+
case "createBranch" /* CreateBranch */:
|
|
20477
|
+
return this.createBranch(params);
|
|
20478
|
+
case "listBranches" /* ListBranches */:
|
|
20479
|
+
return this.listBranches(params);
|
|
20480
|
+
case "listCommits" /* ListCommits */:
|
|
20481
|
+
return this.listCommits(params);
|
|
20482
|
+
case "createCommit" /* CreateCommit */:
|
|
20483
|
+
return this.createCommit(params);
|
|
20484
|
+
case "getUser" /* GetUser */:
|
|
20485
|
+
return this.getUser(params);
|
|
20486
|
+
case "listOrganizations" /* ListOrganizations */:
|
|
20487
|
+
return this.listOrganizations(params);
|
|
20488
|
+
default:
|
|
20489
|
+
throw new Error(`Unsupported GitHub action: ${String(action)}`);
|
|
20490
|
+
}
|
|
20491
|
+
}
|
|
20492
|
+
};
|
|
20493
|
+
GitHubAdapterFactory = class {
|
|
20494
|
+
static async create(config2 = {}) {
|
|
20495
|
+
const detection = await GitHubRuntimeDetector.detect(config2);
|
|
20496
|
+
const runtimeConfig = {
|
|
20497
|
+
...config2,
|
|
20498
|
+
runtime: detection.runtime
|
|
20499
|
+
};
|
|
20500
|
+
if (detection.runtime === "local") {
|
|
20501
|
+
const { GhCliClient: GhCliClient2 } = await Promise.resolve().then(() => (init_local_runtime(), local_runtime_exports));
|
|
20502
|
+
return new GhCliClient2(runtimeConfig);
|
|
20503
|
+
}
|
|
20504
|
+
const { NangoClient: NangoClient2 } = await Promise.resolve().then(() => (init_cloud_runtime(), cloud_runtime_exports));
|
|
20505
|
+
return new NangoClient2(runtimeConfig);
|
|
20506
|
+
}
|
|
20507
|
+
static detect(config2 = {}) {
|
|
20508
|
+
return GitHubRuntimeDetector.detect(config2);
|
|
20509
|
+
}
|
|
20510
|
+
static detectRuntime(config2 = {}) {
|
|
20511
|
+
return GitHubRuntimeDetector.detectRuntime(config2);
|
|
20512
|
+
}
|
|
20513
|
+
static testRuntime(runtime, config2 = {}) {
|
|
20514
|
+
return GitHubRuntimeDetector.testRuntime(runtime, config2);
|
|
20515
|
+
}
|
|
20516
|
+
};
|
|
20517
|
+
GitHubClientFactory = GitHubAdapterFactory;
|
|
20518
|
+
}
|
|
20519
|
+
});
|
|
20520
|
+
|
|
18733
20521
|
// node_modules/compare-versions/lib/umd/index.js
|
|
18734
20522
|
var require_umd = __commonJS({
|
|
18735
20523
|
"node_modules/compare-versions/lib/umd/index.js"(exports2, module2) {
|
|
@@ -18856,7 +20644,7 @@ var require_umd = __commonJS({
|
|
|
18856
20644
|
});
|
|
18857
20645
|
|
|
18858
20646
|
// packages/memory/dist/types.js
|
|
18859
|
-
var
|
|
20647
|
+
var init_types2 = __esm({
|
|
18860
20648
|
"packages/memory/dist/types.js"() {
|
|
18861
20649
|
"use strict";
|
|
18862
20650
|
}
|
|
@@ -20180,7 +21968,7 @@ __export(dist_exports2, {
|
|
|
20180
21968
|
var init_dist2 = __esm({
|
|
20181
21969
|
"packages/memory/dist/index.js"() {
|
|
20182
21970
|
"use strict";
|
|
20183
|
-
|
|
21971
|
+
init_types2();
|
|
20184
21972
|
init_adapters();
|
|
20185
21973
|
init_factory();
|
|
20186
21974
|
init_service();
|
|
@@ -20223,6 +22011,7 @@ __export(index_exports, {
|
|
|
20223
22011
|
ERROR_SEARCH_HINT: () => ERROR_SEARCH_HINT,
|
|
20224
22012
|
GEMINI_MODEL_OPTIONS: () => GEMINI_MODEL_OPTIONS,
|
|
20225
22013
|
GeminiModels: () => GeminiModels,
|
|
22014
|
+
GitHubClient: () => GitHubClient,
|
|
20226
22015
|
HARNESS_VALUES: () => HARNESS_VALUES,
|
|
20227
22016
|
HOOK_ABI_VERSION: () => HOOK_ABI_VERSION,
|
|
20228
22017
|
HookEmitter: () => HookEmitter,
|
|
@@ -20286,6 +22075,7 @@ __export(index_exports, {
|
|
|
20286
22075
|
createConsensusEngine: () => createConsensusEngine,
|
|
20287
22076
|
createContextCompactor: () => createContextCompactor,
|
|
20288
22077
|
createDefaultEventLogger: () => createDefaultEventLogger,
|
|
22078
|
+
createGitHubStep: () => createGitHubStep,
|
|
20289
22079
|
createLogger: () => createLogger,
|
|
20290
22080
|
createMemoryAdapter: () => createMemoryAdapter,
|
|
20291
22081
|
createMemoryHooks: () => createMemoryHooks,
|
|
@@ -20345,6 +22135,7 @@ __export(index_exports, {
|
|
|
20345
22135
|
getSupportedPlatforms: () => getSupportedPlatforms,
|
|
20346
22136
|
getSupportedReasoningEfforts: () => getSupportedReasoningEfforts,
|
|
20347
22137
|
getTrajectoryHooks: () => getTrajectoryHooks,
|
|
22138
|
+
github: () => github_exports,
|
|
20348
22139
|
handleResponse: () => handleResponse2,
|
|
20349
22140
|
hasRelayPtyBinary: () => hasRelayPtyBinary,
|
|
20350
22141
|
hasUnreadMessages: () => hasUnreadMessages,
|
|
@@ -20956,13 +22747,21 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
20956
22747
|
requestTimeoutMs: options?.requestTimeoutMs
|
|
20957
22748
|
});
|
|
20958
22749
|
client.child = child;
|
|
22750
|
+
const brokerExited = new Promise((_2, reject) => {
|
|
22751
|
+
child.once("exit", (code) => {
|
|
22752
|
+
reject(new Error(formatBrokerStartupError(`Broker process exited with code ${code} during initial handshake`, child, { binaryPath, args, cwd, stdoutLines, stderrLines })));
|
|
22753
|
+
});
|
|
22754
|
+
});
|
|
22755
|
+
brokerExited.catch(() => {
|
|
22756
|
+
});
|
|
20959
22757
|
let session;
|
|
20960
22758
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
20961
22759
|
try {
|
|
20962
|
-
session = await client.getSession();
|
|
22760
|
+
session = await Promise.race([client.getSession(), brokerExited]);
|
|
20963
22761
|
break;
|
|
20964
22762
|
} catch (err) {
|
|
20965
|
-
const
|
|
22763
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22764
|
+
const is503 = message.includes("503") || message.includes("Service Unavailable");
|
|
20966
22765
|
if (!is503 || attempt >= 9)
|
|
20967
22766
|
throw err;
|
|
20968
22767
|
await new Promise((resolve4) => setTimeout(resolve4, 1e3));
|
|
@@ -21817,15 +23616,15 @@ var makeIssue = (params) => {
|
|
|
21817
23616
|
message: issueData.message
|
|
21818
23617
|
};
|
|
21819
23618
|
}
|
|
21820
|
-
let
|
|
23619
|
+
let errorMessage4 = "";
|
|
21821
23620
|
const maps = errorMaps.filter((m2) => !!m2).slice().reverse();
|
|
21822
23621
|
for (const map2 of maps) {
|
|
21823
|
-
|
|
23622
|
+
errorMessage4 = map2(fullIssue, { data, defaultError: errorMessage4 }).message;
|
|
21824
23623
|
}
|
|
21825
23624
|
return {
|
|
21826
23625
|
...issueData,
|
|
21827
23626
|
path: fullPath,
|
|
21828
|
-
message:
|
|
23627
|
+
message: errorMessage4
|
|
21829
23628
|
};
|
|
21830
23629
|
};
|
|
21831
23630
|
var EMPTY_PATH = [];
|
|
@@ -25423,19 +27222,19 @@ var getRefs = (options) => {
|
|
|
25423
27222
|
};
|
|
25424
27223
|
|
|
25425
27224
|
// node_modules/zod-to-json-schema/dist/esm/errorMessages.js
|
|
25426
|
-
function addErrorMessage(res, key,
|
|
27225
|
+
function addErrorMessage(res, key, errorMessage4, refs) {
|
|
25427
27226
|
if (!refs?.errorMessages)
|
|
25428
27227
|
return;
|
|
25429
|
-
if (
|
|
27228
|
+
if (errorMessage4) {
|
|
25430
27229
|
res.errorMessage = {
|
|
25431
27230
|
...res.errorMessage,
|
|
25432
|
-
[key]:
|
|
27231
|
+
[key]: errorMessage4
|
|
25433
27232
|
};
|
|
25434
27233
|
}
|
|
25435
27234
|
}
|
|
25436
|
-
function setResponseValueAndErrors(res, key, value,
|
|
27235
|
+
function setResponseValueAndErrors(res, key, value, errorMessage4, refs) {
|
|
25437
27236
|
res[key] = value;
|
|
25438
|
-
addErrorMessage(res, key,
|
|
27237
|
+
addErrorMessage(res, key, errorMessage4, refs);
|
|
25439
27238
|
}
|
|
25440
27239
|
|
|
25441
27240
|
// node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
|
|
@@ -43422,11 +45221,11 @@ var WsClient = class {
|
|
|
43422
45221
|
this.reconnectAttempt += 1;
|
|
43423
45222
|
const reconnectingEvent = { type: "reconnecting", attempt: this.reconnectAttempt };
|
|
43424
45223
|
this.emit("reconnecting", reconnectingEvent);
|
|
43425
|
-
const
|
|
45224
|
+
const delay4 = this.computeReconnectDelayMs(this.reconnectAttempt);
|
|
43426
45225
|
this.reconnectTimer = setTimeout(() => {
|
|
43427
45226
|
this.reconnectTimer = null;
|
|
43428
45227
|
this.connect();
|
|
43429
|
-
},
|
|
45228
|
+
}, delay4);
|
|
43430
45229
|
}
|
|
43431
45230
|
};
|
|
43432
45231
|
|
|
@@ -53941,12 +55740,12 @@ function isUtf8(raw) {
|
|
|
53941
55740
|
}
|
|
53942
55741
|
}
|
|
53943
55742
|
function buildSeedFilePayload(filePath, rootDir) {
|
|
53944
|
-
const
|
|
55743
|
+
const relative3 = import_node_path22.default.relative(rootDir, filePath).split(import_node_path22.default.sep).join("/");
|
|
53945
55744
|
const raw = import_node_fs15.default.readFileSync(filePath);
|
|
53946
55745
|
if (isUtf8(raw)) {
|
|
53947
|
-
return { path: `/${
|
|
55746
|
+
return { path: `/${relative3}`, content: raw.toString("utf8"), encoding: "utf-8" };
|
|
53948
55747
|
}
|
|
53949
|
-
return { path: `/${
|
|
55748
|
+
return { path: `/${relative3}`, content: raw.toString("base64"), encoding: "base64" };
|
|
53950
55749
|
}
|
|
53951
55750
|
function collectSeedPaths(rootDir, currentRelative, excludeDirs, output) {
|
|
53952
55751
|
const absoluteDir = import_node_path22.default.join(rootDir, currentRelative);
|
|
@@ -56767,7 +58566,7 @@ function delay(ms2) {
|
|
|
56767
58566
|
// packages/sdk/dist/workflows/trajectory.js
|
|
56768
58567
|
var import_node_path28 = require("node:path");
|
|
56769
58568
|
|
|
56770
|
-
// node_modules/agent-trajectories/dist/chunk-
|
|
58569
|
+
// node_modules/agent-trajectories/dist/chunk-WMJRBQB4.js
|
|
56771
58570
|
var import_module = require("module");
|
|
56772
58571
|
var import_crypto = require("crypto");
|
|
56773
58572
|
var import_crypto2 = require("crypto");
|
|
@@ -57322,6 +59121,20 @@ function expandPath(path25) {
|
|
|
57322
59121
|
}
|
|
57323
59122
|
return path25;
|
|
57324
59123
|
}
|
|
59124
|
+
function describeReadFailure(reason, error51) {
|
|
59125
|
+
if (reason === "schema_violation" && error51 && typeof error51 === "object" && "issues" in error51) {
|
|
59126
|
+
const issues = error51.issues ?? [];
|
|
59127
|
+
if (issues.length > 0) {
|
|
59128
|
+
const first = issues[0];
|
|
59129
|
+
const where = first.path.length > 0 ? first.path.join(".") : "root";
|
|
59130
|
+
const extra = issues.length > 1 ? ` (+${issues.length - 1} more)` : "";
|
|
59131
|
+
return `${where}: ${first.message}${extra}`;
|
|
59132
|
+
}
|
|
59133
|
+
return "schema validation failed";
|
|
59134
|
+
}
|
|
59135
|
+
if (error51 instanceof Error) return error51.message;
|
|
59136
|
+
return String(error51);
|
|
59137
|
+
}
|
|
57325
59138
|
var indexLocks = /* @__PURE__ */ new Map();
|
|
57326
59139
|
function withIndexLock(path25, task) {
|
|
57327
59140
|
const prev = indexLocks.get(path25) ?? Promise.resolve();
|
|
@@ -57338,6 +59151,7 @@ var FileStorage = class {
|
|
|
57338
59151
|
activeDir;
|
|
57339
59152
|
completedDir;
|
|
57340
59153
|
indexPath;
|
|
59154
|
+
lastReconcileSummary;
|
|
57341
59155
|
constructor(baseDir) {
|
|
57342
59156
|
this.baseDir = baseDir ?? process.cwd();
|
|
57343
59157
|
const dataDir = process.env.TRAJECTORIES_DATA_DIR;
|
|
@@ -57387,7 +59201,8 @@ var FileStorage = class {
|
|
|
57387
59201
|
alreadyIndexed: 0,
|
|
57388
59202
|
skippedMalformedJson: 0,
|
|
57389
59203
|
skippedSchemaViolation: 0,
|
|
57390
|
-
skippedIoError: 0
|
|
59204
|
+
skippedIoError: 0,
|
|
59205
|
+
failures: []
|
|
57391
59206
|
};
|
|
57392
59207
|
await withIndexLock(this.indexPath, async () => {
|
|
57393
59208
|
const index = await this.loadIndex();
|
|
@@ -57414,6 +59229,11 @@ var FileStorage = class {
|
|
|
57414
59229
|
} else {
|
|
57415
59230
|
summary.skippedIoError += 1;
|
|
57416
59231
|
}
|
|
59232
|
+
summary.failures.push({
|
|
59233
|
+
path: result.path,
|
|
59234
|
+
reason: result.reason,
|
|
59235
|
+
message: describeReadFailure(result.reason, result.error)
|
|
59236
|
+
});
|
|
57417
59237
|
continue;
|
|
57418
59238
|
}
|
|
57419
59239
|
const trajectory2 = result.trajectory;
|
|
@@ -57448,8 +59268,74 @@ var FileStorage = class {
|
|
|
57448
59268
|
}
|
|
57449
59269
|
console.warn(`[trajectories] ${parts.join(", ")}`);
|
|
57450
59270
|
}
|
|
59271
|
+
this.lastReconcileSummary = summary;
|
|
57451
59272
|
return summary;
|
|
57452
59273
|
}
|
|
59274
|
+
/**
|
|
59275
|
+
* Returns the most recent reconcile summary, if any. Lets the CLI
|
|
59276
|
+
* inspect the failures collected during `initialize()` without having
|
|
59277
|
+
* to re-walk the directory tree (and re-emit the warn line).
|
|
59278
|
+
*/
|
|
59279
|
+
getLastReconcileSummary() {
|
|
59280
|
+
return this.lastReconcileSummary;
|
|
59281
|
+
}
|
|
59282
|
+
/**
|
|
59283
|
+
* Move trajectory files that fail to load into `.trajectories/invalid/`
|
|
59284
|
+
* so reconcile no longer scans them. Only quarantines parse and schema
|
|
59285
|
+
* failures — transient io_error failures are left in place because the
|
|
59286
|
+
* file may load fine on the next attempt.
|
|
59287
|
+
*
|
|
59288
|
+
* Returns the list of files that were moved (with their original paths
|
|
59289
|
+
* and the destination directory) so the caller can report what changed.
|
|
59290
|
+
*/
|
|
59291
|
+
async quarantineInvalid() {
|
|
59292
|
+
const summary = await this.reconcileIndex();
|
|
59293
|
+
const targetDir = (0, import_path4.join)(this.trajectoriesDir, "invalid");
|
|
59294
|
+
const candidates = summary.failures.filter((f2) => f2.reason !== "io_error");
|
|
59295
|
+
if (candidates.length === 0) {
|
|
59296
|
+
return { moved: [], targetDir };
|
|
59297
|
+
}
|
|
59298
|
+
await (0, import_promises7.mkdir)(targetDir, { recursive: true });
|
|
59299
|
+
const moved = [];
|
|
59300
|
+
for (const failure of candidates) {
|
|
59301
|
+
const dest = await this.resolveQuarantineDest(failure.path, targetDir);
|
|
59302
|
+
try {
|
|
59303
|
+
await (0, import_promises7.mkdir)((0, import_path4.dirname)(dest), { recursive: true });
|
|
59304
|
+
await (0, import_promises7.rename)(failure.path, dest);
|
|
59305
|
+
moved.push(failure);
|
|
59306
|
+
} catch (error51) {
|
|
59307
|
+
console.warn(
|
|
59308
|
+
`[trajectories] failed to quarantine ${failure.path}: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
59309
|
+
);
|
|
59310
|
+
}
|
|
59311
|
+
}
|
|
59312
|
+
return { moved, targetDir };
|
|
59313
|
+
}
|
|
59314
|
+
/**
|
|
59315
|
+
* Pick a destination path under `targetDir` for a quarantined file.
|
|
59316
|
+
*
|
|
59317
|
+
* Preserves the file's relative location under the trajectories root
|
|
59318
|
+
* (e.g. `completed/2026-04/foo.json` → `invalid/completed/2026-04/foo.json`)
|
|
59319
|
+
* so two invalid files that share a basename across `active/` and
|
|
59320
|
+
* `completed/` don't collapse onto each other and silently overwrite.
|
|
59321
|
+
*
|
|
59322
|
+
* Falls back to a numeric-suffix scheme for paths that live outside
|
|
59323
|
+
* the trajectories directory or that, after relative resolution, would
|
|
59324
|
+
* still collide with something already quarantined.
|
|
59325
|
+
*/
|
|
59326
|
+
async resolveQuarantineDest(sourcePath, targetDir) {
|
|
59327
|
+
const rel = (0, import_path4.relative)(this.trajectoriesDir, sourcePath);
|
|
59328
|
+
const safeRel = rel && !rel.startsWith("..") && !(0, import_path4.isAbsolute)(rel) ? rel : (0, import_path4.basename)(sourcePath);
|
|
59329
|
+
let dest = (0, import_path4.join)(targetDir, safeRel);
|
|
59330
|
+
if (!(0, import_fs5.existsSync)(dest)) return dest;
|
|
59331
|
+
const ext = safeRel.endsWith(".json") ? ".json" : "";
|
|
59332
|
+
const stem = ext ? safeRel.slice(0, -ext.length) : safeRel;
|
|
59333
|
+
for (let i = 1; i < 1e3; i += 1) {
|
|
59334
|
+
dest = (0, import_path4.join)(targetDir, `${stem}.${i}${ext}`);
|
|
59335
|
+
if (!(0, import_fs5.existsSync)(dest)) return dest;
|
|
59336
|
+
}
|
|
59337
|
+
return dest;
|
|
59338
|
+
}
|
|
57453
59339
|
/**
|
|
57454
59340
|
* Recursively collect all .json file paths under `dir` into `out`.
|
|
57455
59341
|
* Silently treats a missing directory as empty.
|
|
@@ -58765,14 +60651,14 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
58765
60651
|
if (!mount) {
|
|
58766
60652
|
return cwd;
|
|
58767
60653
|
}
|
|
58768
|
-
const
|
|
58769
|
-
if (
|
|
60654
|
+
const relative3 = import_node_path29.default.relative(this.cwd, cwd);
|
|
60655
|
+
if (relative3 === "") {
|
|
58770
60656
|
return mount.mountPoint;
|
|
58771
60657
|
}
|
|
58772
|
-
if (
|
|
60658
|
+
if (relative3 === ".." || relative3.startsWith(`..${import_node_path29.default.sep}`)) {
|
|
58773
60659
|
return cwd;
|
|
58774
60660
|
}
|
|
58775
|
-
return import_node_path29.default.resolve(mount.mountPoint,
|
|
60661
|
+
return import_node_path29.default.resolve(mount.mountPoint, relative3);
|
|
58776
60662
|
}
|
|
58777
60663
|
resolveExecutionCwd(step, agentDef) {
|
|
58778
60664
|
const cwd = this.resolveEffectiveCwd(step, agentDef);
|
|
@@ -59147,10 +61033,10 @@ ${next}` : next;
|
|
|
59147
61033
|
return changes.sort((a, b2) => a.path.localeCompare(b2.path));
|
|
59148
61034
|
}
|
|
59149
61035
|
normalizeEvidencePath(filePath) {
|
|
59150
|
-
const
|
|
59151
|
-
if (!
|
|
61036
|
+
const relative3 = import_node_path29.default.relative(this.cwd, filePath);
|
|
61037
|
+
if (!relative3 || relative3 === "")
|
|
59152
61038
|
return import_node_path29.default.basename(filePath);
|
|
59153
|
-
return
|
|
61039
|
+
return relative3.startsWith("..") ? filePath : relative3;
|
|
59154
61040
|
}
|
|
59155
61041
|
buildStepCompletionDecision(stepName, completionReason) {
|
|
59156
61042
|
let reason;
|
|
@@ -60730,7 +62616,7 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
60730
62616
|
}
|
|
60731
62617
|
async executeStep(step, state, stepStates, agentMap, errorHandling, runId, lifecycle) {
|
|
60732
62618
|
if (this.isDeterministicStep(step)) {
|
|
60733
|
-
return this.executeDeterministicStep(step, state, stepStates, runId, errorHandling, lifecycle);
|
|
62619
|
+
return this.executeDeterministicStep(step, state, stepStates, agentMap, runId, errorHandling, lifecycle);
|
|
60734
62620
|
}
|
|
60735
62621
|
if (this.isWorktreeStep(step)) {
|
|
60736
62622
|
return this.executeWorktreeStep(step, state, stepStates, runId, lifecycle);
|
|
@@ -60744,13 +62630,18 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
60744
62630
|
* Execute a deterministic step (shell command).
|
|
60745
62631
|
* Fast, reliable, $0 LLM cost.
|
|
60746
62632
|
*/
|
|
60747
|
-
async executeDeterministicStep(step, state, stepStates, runId, errorHandling, lifecycle) {
|
|
60748
|
-
const
|
|
62633
|
+
async executeDeterministicStep(step, state, stepStates, agentMap, runId, errorHandling, lifecycle) {
|
|
62634
|
+
const repairRetries = errorHandling?.strategy === "retry" ? errorHandling.repairRetries ?? 0 : 0;
|
|
62635
|
+
const repairAgent = repairRetries > 0 ? this.resolveDeterministicRepairAgent(step, stepStates, agentMap, errorHandling) : void 0;
|
|
62636
|
+
const maxRetries = step.retries ?? errorHandling?.maxRetries ?? (repairAgent ? repairRetries : 0);
|
|
60749
62637
|
const retryDelay = errorHandling?.retryDelayMs ?? 1e3;
|
|
60750
62638
|
let lastError = "Unknown error";
|
|
60751
62639
|
let lastCompletionReason;
|
|
60752
62640
|
let lastExitCode;
|
|
60753
62641
|
let lastExitSignal;
|
|
62642
|
+
let lastResolvedCommand = step.command ?? "";
|
|
62643
|
+
let lastStepCwd = this.cwd;
|
|
62644
|
+
let lastCommandOutput = "";
|
|
60754
62645
|
const result = await lifecycle.monitorStep(step, state, {
|
|
60755
62646
|
maxRetries,
|
|
60756
62647
|
retryDelayMs: retryDelay,
|
|
@@ -60763,6 +62654,20 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
60763
62654
|
detail: `Retrying attempt ${attempt + 1}/${total + 1}`,
|
|
60764
62655
|
raw: { attempt, maxRetries: total }
|
|
60765
62656
|
});
|
|
62657
|
+
if (repairAgent) {
|
|
62658
|
+
await this.runDeterministicRepairAgent({
|
|
62659
|
+
step,
|
|
62660
|
+
agentDef: repairAgent,
|
|
62661
|
+
attempt,
|
|
62662
|
+
maxRetries: total,
|
|
62663
|
+
command: lastResolvedCommand,
|
|
62664
|
+
cwd: lastStepCwd,
|
|
62665
|
+
error: lastError,
|
|
62666
|
+
output: lastCommandOutput,
|
|
62667
|
+
exitCode: lastExitCode,
|
|
62668
|
+
exitSignal: lastExitSignal
|
|
62669
|
+
});
|
|
62670
|
+
}
|
|
60766
62671
|
},
|
|
60767
62672
|
execute: async () => {
|
|
60768
62673
|
const stepOutputContext = this.buildStepOutputContext(stepStates, runId);
|
|
@@ -60774,12 +62679,15 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
60774
62679
|
return value !== void 0 ? String(value) : _match;
|
|
60775
62680
|
});
|
|
60776
62681
|
const stepCwd = this.resolveEffectiveCwd(step);
|
|
62682
|
+
lastResolvedCommand = resolvedCommand;
|
|
62683
|
+
lastStepCwd = stepCwd;
|
|
60777
62684
|
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
60778
62685
|
this.log(`[${step.name}] Running: ${resolvedCommand.slice(0, 200)}${resolvedCommand.length > 200 ? "..." : ""}`);
|
|
60779
62686
|
if (this.executor?.executeDeterministicStep) {
|
|
60780
62687
|
const executorResult = await this.executor.executeDeterministicStep(step, resolvedCommand, stepCwd);
|
|
60781
62688
|
lastExitCode = executorResult.exitCode;
|
|
60782
62689
|
lastExitSignal = void 0;
|
|
62690
|
+
lastCommandOutput = executorResult.output;
|
|
60783
62691
|
const failOnError = step.failOnError !== false;
|
|
60784
62692
|
if (failOnError && executorResult.exitCode !== 0) {
|
|
60785
62693
|
this.log(`[${step.name}] Command failed (exit code ${executorResult.exitCode})`);
|
|
@@ -60851,6 +62759,7 @@ ${executorResult.output}`);
|
|
|
60851
62759
|
commandStderr = stderr;
|
|
60852
62760
|
lastExitCode = code ?? void 0;
|
|
60853
62761
|
lastExitSignal = signal ?? void 0;
|
|
62762
|
+
lastCommandOutput = [stdout, stderr].filter(Boolean).join("\n");
|
|
60854
62763
|
const failOnError = step.failOnError !== false;
|
|
60855
62764
|
if (failOnError && code !== 0 && code !== null) {
|
|
60856
62765
|
this.log(`[${step.name}] Command failed (exit code ${code})`);
|
|
@@ -60882,6 +62791,7 @@ ${stderr}`);
|
|
|
60882
62791
|
combined: [commandStdout || output, commandStderr].filter(Boolean).join("\n")
|
|
60883
62792
|
}, { exitCode: lastExitCode, exitSignal: lastExitSignal });
|
|
60884
62793
|
const verificationResult = step.verification ? this.runVerification(step.verification, output, step.name) : void 0;
|
|
62794
|
+
lastCommandOutput = [commandStdout || output, commandStderr].filter(Boolean).join("\n");
|
|
60885
62795
|
return {
|
|
60886
62796
|
output,
|
|
60887
62797
|
completionReason: verificationResult?.completionReason
|
|
@@ -60914,6 +62824,131 @@ ${stderr}`);
|
|
|
60914
62824
|
throw new Error(`Step "${step.name}" failed: ${result.error ?? "Unknown error"}`);
|
|
60915
62825
|
}
|
|
60916
62826
|
}
|
|
62827
|
+
resolveDeterministicRepairAgent(step, stepStates, agentMap, errorHandling) {
|
|
62828
|
+
const explicitName = errorHandling?.repairAgent?.trim();
|
|
62829
|
+
if (explicitName) {
|
|
62830
|
+
const explicitAgent = agentMap.get(explicitName);
|
|
62831
|
+
if (explicitAgent)
|
|
62832
|
+
return _WorkflowRunner.resolveAgentDef(explicitAgent);
|
|
62833
|
+
this.log(`[${step.name}] repairAgent "${explicitName}" not found; falling back to workflow agents`);
|
|
62834
|
+
}
|
|
62835
|
+
if (step.agent) {
|
|
62836
|
+
const stepAgent = agentMap.get(step.agent);
|
|
62837
|
+
if (stepAgent)
|
|
62838
|
+
return _WorkflowRunner.resolveAgentDef(stepAgent);
|
|
62839
|
+
}
|
|
62840
|
+
for (const dependency of [...step.dependsOn ?? []].reverse()) {
|
|
62841
|
+
const dependencyAgent = stepStates.get(dependency)?.row.agentName;
|
|
62842
|
+
if (!dependencyAgent)
|
|
62843
|
+
continue;
|
|
62844
|
+
const agent = agentMap.get(dependencyAgent);
|
|
62845
|
+
if (agent)
|
|
62846
|
+
return _WorkflowRunner.resolveAgentDef(agent);
|
|
62847
|
+
}
|
|
62848
|
+
const candidates = [...agentMap.values()].map((agent) => _WorkflowRunner.resolveAgentDef(agent));
|
|
62849
|
+
candidates.sort((a, b2) => this.scoreRepairAgent(b2) - this.scoreRepairAgent(a));
|
|
62850
|
+
return candidates[0];
|
|
62851
|
+
}
|
|
62852
|
+
scoreRepairAgent(agent) {
|
|
62853
|
+
const text = `${agent.name} ${agent.role ?? ""} ${agent.preset ?? ""}`.toLowerCase();
|
|
62854
|
+
let score = 0;
|
|
62855
|
+
if (/\b(repair|fix|implement|implementation|engineer|developer|coder|worker|owner|lead|coordinator)\b/.test(text)) {
|
|
62856
|
+
score += 10;
|
|
62857
|
+
}
|
|
62858
|
+
if (agent.interactive === false || ["worker", "analyst"].includes(agent.preset ?? "")) {
|
|
62859
|
+
score += 2;
|
|
62860
|
+
}
|
|
62861
|
+
if (/\b(review|reviewer|audit|security|analyst)\b/.test(text)) {
|
|
62862
|
+
score -= 4;
|
|
62863
|
+
}
|
|
62864
|
+
if (agent.permissions?.access === "readonly") {
|
|
62865
|
+
score -= 20;
|
|
62866
|
+
}
|
|
62867
|
+
return score;
|
|
62868
|
+
}
|
|
62869
|
+
async runDeterministicRepairAgent(context) {
|
|
62870
|
+
const repairAgent = {
|
|
62871
|
+
...context.agentDef,
|
|
62872
|
+
interactive: false
|
|
62873
|
+
};
|
|
62874
|
+
const repairPrompt = this.buildDeterministicRepairPrompt(context);
|
|
62875
|
+
const repairStep = {
|
|
62876
|
+
name: `${context.step.name}-repair-${context.attempt}`,
|
|
62877
|
+
type: "agent",
|
|
62878
|
+
agent: repairAgent.name,
|
|
62879
|
+
task: repairPrompt,
|
|
62880
|
+
cwd: context.cwd,
|
|
62881
|
+
workdir: void 0,
|
|
62882
|
+
retries: 0
|
|
62883
|
+
};
|
|
62884
|
+
const timeoutMs = repairAgent.constraints?.timeoutMs ?? context.step.timeoutMs ?? this.currentConfig?.swarm?.timeoutMs;
|
|
62885
|
+
this.log(`[${context.step.name}] Deterministic gate failed; asking "${repairAgent.name}" to repair before retry ${context.attempt + 1}/${context.maxRetries + 1}`);
|
|
62886
|
+
this.postToChannel(`**[${context.step.name}]** Deterministic gate failed; assigning repair to \`${repairAgent.name}\``);
|
|
62887
|
+
this.recordStepToolSideEffect(context.step.name, {
|
|
62888
|
+
type: "custom",
|
|
62889
|
+
detail: `Assigned deterministic gate repair to ${repairAgent.name}`,
|
|
62890
|
+
raw: {
|
|
62891
|
+
repairAgent: repairAgent.name,
|
|
62892
|
+
attempt: context.attempt,
|
|
62893
|
+
maxRetries: context.maxRetries,
|
|
62894
|
+
exitCode: context.exitCode,
|
|
62895
|
+
exitSignal: context.exitSignal
|
|
62896
|
+
}
|
|
62897
|
+
});
|
|
62898
|
+
try {
|
|
62899
|
+
this.ensureBudgetAllowsSpawn(context.step.name, repairAgent.name);
|
|
62900
|
+
let repairOutput;
|
|
62901
|
+
if (this.executor) {
|
|
62902
|
+
repairOutput = await this.executor.executeAgentStep(repairStep, repairAgent, repairPrompt, timeoutMs);
|
|
62903
|
+
} else if (repairAgent.cli === "api") {
|
|
62904
|
+
repairOutput = await executeApiStep(repairAgent.constraints?.model ?? "claude-sonnet-4-20250514", repairPrompt, {
|
|
62905
|
+
envSecrets: this.envSecrets,
|
|
62906
|
+
skills: repairAgent.skills,
|
|
62907
|
+
defaultMaxTokens: repairAgent.constraints?.maxTokens
|
|
62908
|
+
});
|
|
62909
|
+
} else {
|
|
62910
|
+
const result = await this.execNonInteractive(repairAgent, repairStep, timeoutMs);
|
|
62911
|
+
repairOutput = result.output;
|
|
62912
|
+
}
|
|
62913
|
+
this.recordStepToolSideEffect(context.step.name, {
|
|
62914
|
+
type: "custom",
|
|
62915
|
+
detail: `Repair agent ${repairAgent.name} completed before deterministic retry`,
|
|
62916
|
+
raw: { repairAgent: repairAgent.name, output: repairOutput.slice(0, 1e3) }
|
|
62917
|
+
});
|
|
62918
|
+
} catch (error51) {
|
|
62919
|
+
if (error51 instanceof BudgetExceededError || this.abortController?.signal.aborted) {
|
|
62920
|
+
throw error51;
|
|
62921
|
+
}
|
|
62922
|
+
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
62923
|
+
this.log(`[${context.step.name}] Repair agent "${repairAgent.name}" failed: ${message}`);
|
|
62924
|
+
this.postToChannel(`**[${context.step.name}]** Repair agent \`${repairAgent.name}\` failed; retrying gate anyway`);
|
|
62925
|
+
this.recordStepToolSideEffect(context.step.name, {
|
|
62926
|
+
type: "custom",
|
|
62927
|
+
detail: `Repair agent ${repairAgent.name} failed before deterministic retry: ${message}`,
|
|
62928
|
+
raw: { repairAgent: repairAgent.name, error: message }
|
|
62929
|
+
});
|
|
62930
|
+
}
|
|
62931
|
+
}
|
|
62932
|
+
buildDeterministicRepairPrompt(context) {
|
|
62933
|
+
const output = context.output.trim();
|
|
62934
|
+
const clippedOutput = output.length > 4e3 ? output.slice(-4e3) : output;
|
|
62935
|
+
return `A deterministic workflow gate failed after an agent/team step. Fix the repository or workflow state so the same gate passes on the next retry.
|
|
62936
|
+
|
|
62937
|
+
Step: ${context.step.name}
|
|
62938
|
+
Working directory: ${context.cwd}
|
|
62939
|
+
Command:
|
|
62940
|
+
${context.command}
|
|
62941
|
+
|
|
62942
|
+
Failure:
|
|
62943
|
+
${context.error}
|
|
62944
|
+
Exit code: ${context.exitCode ?? "unknown"}
|
|
62945
|
+
Exit signal: ${context.exitSignal ?? "none"}
|
|
62946
|
+
|
|
62947
|
+
Command output:
|
|
62948
|
+
${clippedOutput || "(no output captured)"}
|
|
62949
|
+
|
|
62950
|
+
Repair only what is needed for this gate to pass. Preserve unrelated user changes. After making the fix, report the files changed and the reason the gate should pass.`;
|
|
62951
|
+
}
|
|
60917
62952
|
/**
|
|
60918
62953
|
* Execute a worktree step (git worktree setup).
|
|
60919
62954
|
* Fast, reliable, $0 LLM cost.
|
|
@@ -60931,7 +62966,7 @@ ${stderr}`);
|
|
|
60931
62966
|
const branch = this.interpolateStepTask(step.branch ?? "", stepOutputContext);
|
|
60932
62967
|
const baseBranch = step.baseBranch ? this.interpolateStepTask(step.baseBranch, stepOutputContext) : "HEAD";
|
|
60933
62968
|
const worktreePath = step.path ? this.interpolateStepTask(step.path, stepOutputContext) : import_node_path29.default.join(".worktrees", step.name);
|
|
60934
|
-
const
|
|
62969
|
+
const createBranch2 = step.createBranch !== false;
|
|
60935
62970
|
const stepCwd = this.resolveStepWorkdir(step) ?? this.cwd;
|
|
60936
62971
|
this.beginStepEvidence(step.name, [stepCwd], state.row.startedAt);
|
|
60937
62972
|
if (!branch) {
|
|
@@ -60954,7 +62989,7 @@ ${stderr}`);
|
|
|
60954
62989
|
let worktreeArgs;
|
|
60955
62990
|
if (branchExists) {
|
|
60956
62991
|
worktreeArgs = ["worktree", "add", absoluteWorktreePath, branch];
|
|
60957
|
-
} else if (
|
|
62992
|
+
} else if (createBranch2) {
|
|
60958
62993
|
worktreeArgs = ["worktree", "add", "-b", branch, absoluteWorktreePath, baseBranch];
|
|
60959
62994
|
} else {
|
|
60960
62995
|
throw new Error(`Branch "${branch}" does not exist and createBranch is false`);
|
|
@@ -61032,7 +63067,7 @@ ${stderr}`);
|
|
|
61032
63067
|
combined: [commandStdout || output, commandStderr].filter(Boolean).join("\n")
|
|
61033
63068
|
}, { exitCode: lastExitCode, exitSignal: lastExitSignal });
|
|
61034
63069
|
worktreeBranch = branch;
|
|
61035
|
-
createdBranch = !branchExists &&
|
|
63070
|
+
createdBranch = !branchExists && createBranch2;
|
|
61036
63071
|
return { output };
|
|
61037
63072
|
},
|
|
61038
63073
|
toCompletionResult: ({ output }, attempt) => ({
|
|
@@ -61151,18 +63186,18 @@ ${stderr}`);
|
|
|
61151
63186
|
await this.persistStepOutput(runId, step.name, output);
|
|
61152
63187
|
this.emit({ type: "step:completed", runId, stepName: step.name, output });
|
|
61153
63188
|
} catch (apiError) {
|
|
61154
|
-
const
|
|
63189
|
+
const errorMessage4 = apiError instanceof Error ? apiError.message : String(apiError);
|
|
61155
63190
|
state.row.status = "failed";
|
|
61156
|
-
state.row.error =
|
|
63191
|
+
state.row.error = errorMessage4;
|
|
61157
63192
|
state.row.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
61158
63193
|
await this.db.updateStep(state.row.id, {
|
|
61159
63194
|
status: "failed",
|
|
61160
|
-
error:
|
|
63195
|
+
error: errorMessage4,
|
|
61161
63196
|
completedAt: state.row.completedAt,
|
|
61162
63197
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
61163
63198
|
});
|
|
61164
|
-
this.emit({ type: "step:failed", runId, stepName: step.name, error:
|
|
61165
|
-
this.postToChannel(`**[${step.name}]** Failed (api): ${
|
|
63199
|
+
this.emit({ type: "step:failed", runId, stepName: step.name, error: errorMessage4 });
|
|
63200
|
+
this.postToChannel(`**[${step.name}]** Failed (api): ${errorMessage4}`);
|
|
61166
63201
|
throw apiError;
|
|
61167
63202
|
}
|
|
61168
63203
|
return;
|
|
@@ -62991,15 +65026,15 @@ DO NOT:
|
|
|
62991
65026
|
throw error51;
|
|
62992
65027
|
}
|
|
62993
65028
|
}
|
|
62994
|
-
updateCustomVerificationFailure(stepName, check2,
|
|
62995
|
-
if (check2.type !== "custom" || !check2.value || !
|
|
65029
|
+
updateCustomVerificationFailure(stepName, check2, errorMessage4) {
|
|
65030
|
+
if (check2.type !== "custom" || !check2.value || !errorMessage4) {
|
|
62996
65031
|
this.lastCustomVerificationFailure.delete(stepName);
|
|
62997
65032
|
return;
|
|
62998
65033
|
}
|
|
62999
65034
|
const marker = `custom check "${check2.value}" failed
|
|
63000
65035
|
`;
|
|
63001
|
-
const markerIndex =
|
|
63002
|
-
const output = markerIndex === -1 ?
|
|
65036
|
+
const markerIndex = errorMessage4.indexOf(marker);
|
|
65037
|
+
const output = markerIndex === -1 ? errorMessage4.trim() : errorMessage4.slice(markerIndex + marker.length).trim();
|
|
63003
65038
|
this.lastCustomVerificationFailure.set(stepName, {
|
|
63004
65039
|
command: check2.value,
|
|
63005
65040
|
output
|
|
@@ -64271,6 +66306,10 @@ var WorkflowBuilder = class {
|
|
|
64271
66306
|
this._errorHandling.retryDelayMs = options.retryDelayMs;
|
|
64272
66307
|
if (options?.notifyChannel !== void 0)
|
|
64273
66308
|
this._errorHandling.notifyChannel = options.notifyChannel;
|
|
66309
|
+
if (options?.repairAgent !== void 0)
|
|
66310
|
+
this._errorHandling.repairAgent = options.repairAgent;
|
|
66311
|
+
if (options?.repairRetries !== void 0)
|
|
66312
|
+
this._errorHandling.repairRetries = options.repairRetries;
|
|
64274
66313
|
return this;
|
|
64275
66314
|
}
|
|
64276
66315
|
validateBuilderState() {
|
|
@@ -66037,6 +68076,751 @@ Run ID: ${runId}`;
|
|
|
66037
68076
|
throw new Error(`Unsupported file type: ${ext}. Use .yaml, .yml, .ts, or .py`);
|
|
66038
68077
|
}
|
|
66039
68078
|
|
|
68079
|
+
// packages/sdk/dist/github.js
|
|
68080
|
+
var github_exports = {};
|
|
68081
|
+
__export(github_exports, {
|
|
68082
|
+
BaseGitHubAdapter: () => BaseGitHubAdapter,
|
|
68083
|
+
DEFAULT_GH_PATH: () => DEFAULT_GH_PATH,
|
|
68084
|
+
DEFAULT_MAX_RETRIES: () => DEFAULT_MAX_RETRIES,
|
|
68085
|
+
DEFAULT_NANGO_BASE_URL: () => DEFAULT_NANGO_BASE_URL,
|
|
68086
|
+
DEFAULT_NANGO_PROVIDER_CONFIG_KEY: () => DEFAULT_NANGO_PROVIDER_CONFIG_KEY,
|
|
68087
|
+
DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT: () => DEFAULT_RELAY_CLOUD_GITHUB_PROXY_ENDPOINT,
|
|
68088
|
+
DEFAULT_TIMEOUT: () => DEFAULT_TIMEOUT,
|
|
68089
|
+
DEFAULT_USER_AGENT: () => DEFAULT_USER_AGENT,
|
|
68090
|
+
GITHUB_ACTIONS: () => GITHUB_ACTIONS,
|
|
68091
|
+
GhCliClient: () => GhCliClient,
|
|
68092
|
+
GhCliError: () => GhCliError,
|
|
68093
|
+
GitHubAction: () => GitHubAction,
|
|
68094
|
+
GitHubAdapterFactory: () => GitHubAdapterFactory,
|
|
68095
|
+
GitHubApiError: () => GitHubApiError,
|
|
68096
|
+
GitHubClient: () => GitHubClient,
|
|
68097
|
+
GitHubClientFactory: () => GitHubClientFactory,
|
|
68098
|
+
GitHubClientInterface: () => GitHubClientInterface,
|
|
68099
|
+
GitHubRuntimeDetector: () => GitHubRuntimeDetector,
|
|
68100
|
+
GitHubStepExecutor: () => GitHubStepExecutor,
|
|
68101
|
+
NangoClient: () => NangoClient,
|
|
68102
|
+
createBranch: () => createBranch,
|
|
68103
|
+
createCommit: () => createCommit,
|
|
68104
|
+
createFile: () => createFile,
|
|
68105
|
+
createGitHubAdapter: () => createGitHubAdapter,
|
|
68106
|
+
createGitHubStep: () => createGitHubStep,
|
|
68107
|
+
createIssue: () => createIssue,
|
|
68108
|
+
createPR: () => createPR,
|
|
68109
|
+
deleteFile: () => deleteFile,
|
|
68110
|
+
detectGitHubRuntime: () => detectGitHubRuntime,
|
|
68111
|
+
getBranch: () => getBranch,
|
|
68112
|
+
getPR: () => getPR,
|
|
68113
|
+
getRepo: () => getRepo,
|
|
68114
|
+
getUser: () => getUser,
|
|
68115
|
+
githubStepConfigFromWorkflowStep: () => githubStepConfigFromWorkflowStep,
|
|
68116
|
+
listBranches: () => listBranches,
|
|
68117
|
+
listCommits: () => listCommits,
|
|
68118
|
+
listFiles: () => listFiles,
|
|
68119
|
+
listIssues: () => listIssues,
|
|
68120
|
+
listOrganizations: () => listOrganizations,
|
|
68121
|
+
listPRs: () => listPRs,
|
|
68122
|
+
listRepos: () => listRepos,
|
|
68123
|
+
mapBranch: () => mapBranch,
|
|
68124
|
+
mapCommit: () => mapCommit,
|
|
68125
|
+
mapFile: () => mapFile,
|
|
68126
|
+
mapIssue: () => mapIssue,
|
|
68127
|
+
mapOrganization: () => mapOrganization,
|
|
68128
|
+
mapPR: () => mapPR,
|
|
68129
|
+
mapRepo: () => mapRepo,
|
|
68130
|
+
mapUser: () => mapUser,
|
|
68131
|
+
mergePR: () => mergePR,
|
|
68132
|
+
normalizeGitHubRuntimeConfig: () => normalizeGitHubRuntimeConfig,
|
|
68133
|
+
readFile: () => readFile3,
|
|
68134
|
+
updateFile: () => updateFile,
|
|
68135
|
+
updateIssue: () => updateIssue,
|
|
68136
|
+
updatePR: () => updatePR
|
|
68137
|
+
});
|
|
68138
|
+
|
|
68139
|
+
// packages/github-primitive/src/index.ts
|
|
68140
|
+
init_constants();
|
|
68141
|
+
init_types();
|
|
68142
|
+
init_adapter();
|
|
68143
|
+
init_local_runtime();
|
|
68144
|
+
init_cloud_runtime();
|
|
68145
|
+
|
|
68146
|
+
// packages/github-primitive/src/client.ts
|
|
68147
|
+
init_adapter();
|
|
68148
|
+
var GitHubClient = class _GitHubClient {
|
|
68149
|
+
adapterPromise;
|
|
68150
|
+
constructor(config2 = {}) {
|
|
68151
|
+
this.adapterPromise = GitHubAdapterFactory.create(config2);
|
|
68152
|
+
}
|
|
68153
|
+
/**
|
|
68154
|
+
* Create a GitHub client and eagerly resolve runtime detection.
|
|
68155
|
+
*/
|
|
68156
|
+
static async create(config2 = {}) {
|
|
68157
|
+
const client = new _GitHubClient(config2);
|
|
68158
|
+
await client.getAdapter();
|
|
68159
|
+
return client;
|
|
68160
|
+
}
|
|
68161
|
+
/**
|
|
68162
|
+
* Inspect runtime availability without creating a client.
|
|
68163
|
+
*/
|
|
68164
|
+
static detect(config2 = {}) {
|
|
68165
|
+
return GitHubAdapterFactory.detect(config2);
|
|
68166
|
+
}
|
|
68167
|
+
/**
|
|
68168
|
+
* Detect the runtime that would be selected for the supplied configuration.
|
|
68169
|
+
*/
|
|
68170
|
+
static detectRuntime(config2 = {}) {
|
|
68171
|
+
return GitHubAdapterFactory.detectRuntime(config2);
|
|
68172
|
+
}
|
|
68173
|
+
/**
|
|
68174
|
+
* Return the selected low-level adapter.
|
|
68175
|
+
*/
|
|
68176
|
+
getAdapter() {
|
|
68177
|
+
return this.adapterPromise;
|
|
68178
|
+
}
|
|
68179
|
+
/**
|
|
68180
|
+
* Return the runtime selected by auto-detection or explicit configuration.
|
|
68181
|
+
*/
|
|
68182
|
+
async getRuntime() {
|
|
68183
|
+
return (await this.getAdapter()).getRuntime();
|
|
68184
|
+
}
|
|
68185
|
+
/**
|
|
68186
|
+
* Check whether the selected runtime is authenticated.
|
|
68187
|
+
*/
|
|
68188
|
+
async isAuthenticated() {
|
|
68189
|
+
return (await this.getAdapter()).isAuthenticated();
|
|
68190
|
+
}
|
|
68191
|
+
/**
|
|
68192
|
+
* Fetch the authenticated GitHub user for the selected runtime.
|
|
68193
|
+
*/
|
|
68194
|
+
async getCurrentUser() {
|
|
68195
|
+
return (await this.getAdapter()).getCurrentUser();
|
|
68196
|
+
}
|
|
68197
|
+
/**
|
|
68198
|
+
* Execute a raw GitHub API request through the selected adapter.
|
|
68199
|
+
*/
|
|
68200
|
+
async request(method, path25, options) {
|
|
68201
|
+
return (await this.getAdapter()).request(method, path25, options);
|
|
68202
|
+
}
|
|
68203
|
+
/**
|
|
68204
|
+
* Execute any registered GitHub primitive action by action name.
|
|
68205
|
+
*/
|
|
68206
|
+
async executeAction(action, params) {
|
|
68207
|
+
return (await this.getAdapter()).executeAction(action, params);
|
|
68208
|
+
}
|
|
68209
|
+
/**
|
|
68210
|
+
* List repositories visible to the authenticated GitHub identity.
|
|
68211
|
+
*/
|
|
68212
|
+
async listRepos(options = {}) {
|
|
68213
|
+
return (await this.getAdapter()).listRepositories(options);
|
|
68214
|
+
}
|
|
68215
|
+
/**
|
|
68216
|
+
* Fetch a repository by owner and name.
|
|
68217
|
+
*/
|
|
68218
|
+
async getRepo(owner, repo) {
|
|
68219
|
+
return (await this.getAdapter()).getRepository({ owner, repo });
|
|
68220
|
+
}
|
|
68221
|
+
/**
|
|
68222
|
+
* List issues for a repository.
|
|
68223
|
+
*/
|
|
68224
|
+
async listIssues(owner, repo, options = {}) {
|
|
68225
|
+
return (await this.getAdapter()).listIssues({ owner, repo, ...options });
|
|
68226
|
+
}
|
|
68227
|
+
/**
|
|
68228
|
+
* Create an issue in a repository.
|
|
68229
|
+
*/
|
|
68230
|
+
async createIssue(owner, repo, title, body, options = {}) {
|
|
68231
|
+
return (await this.getAdapter()).createIssue({ owner, repo, title, body, ...options });
|
|
68232
|
+
}
|
|
68233
|
+
/**
|
|
68234
|
+
* Update an existing issue by issue number.
|
|
68235
|
+
*/
|
|
68236
|
+
async updateIssue(owner, repo, number4, updates) {
|
|
68237
|
+
return (await this.getAdapter()).updateIssue({
|
|
68238
|
+
owner,
|
|
68239
|
+
repo,
|
|
68240
|
+
issueNumber: number4,
|
|
68241
|
+
...updates
|
|
68242
|
+
});
|
|
68243
|
+
}
|
|
68244
|
+
/**
|
|
68245
|
+
* Close an issue by issue number.
|
|
68246
|
+
*/
|
|
68247
|
+
async closeIssue(owner, repo, number4) {
|
|
68248
|
+
return (await this.getAdapter()).closeIssue({ owner, repo, issueNumber: number4 });
|
|
68249
|
+
}
|
|
68250
|
+
/**
|
|
68251
|
+
* List pull requests for a repository.
|
|
68252
|
+
*/
|
|
68253
|
+
async listPRs(owner, repo, options = {}) {
|
|
68254
|
+
return (await this.getAdapter()).listPullRequests({ owner, repo, ...options });
|
|
68255
|
+
}
|
|
68256
|
+
/**
|
|
68257
|
+
* Fetch a pull request by pull request number.
|
|
68258
|
+
*/
|
|
68259
|
+
async getPR(owner, repo, number4) {
|
|
68260
|
+
return (await this.getAdapter()).getPullRequest({ owner, repo, pullNumber: number4 });
|
|
68261
|
+
}
|
|
68262
|
+
/**
|
|
68263
|
+
* Create a pull request.
|
|
68264
|
+
*/
|
|
68265
|
+
async createPR(owner, repo, title, body, base, head, options = {}) {
|
|
68266
|
+
return (await this.getAdapter()).createPullRequest({
|
|
68267
|
+
owner,
|
|
68268
|
+
repo,
|
|
68269
|
+
title,
|
|
68270
|
+
body,
|
|
68271
|
+
base,
|
|
68272
|
+
head,
|
|
68273
|
+
...options
|
|
68274
|
+
});
|
|
68275
|
+
}
|
|
68276
|
+
/**
|
|
68277
|
+
* Update an existing pull request by pull request number.
|
|
68278
|
+
*/
|
|
68279
|
+
async updatePR(owner, repo, number4, updates) {
|
|
68280
|
+
return (await this.getAdapter()).updatePullRequest({
|
|
68281
|
+
owner,
|
|
68282
|
+
repo,
|
|
68283
|
+
pullNumber: number4,
|
|
68284
|
+
...updates
|
|
68285
|
+
});
|
|
68286
|
+
}
|
|
68287
|
+
/**
|
|
68288
|
+
* Merge a pull request and return the refreshed pull request.
|
|
68289
|
+
*/
|
|
68290
|
+
async mergePR(owner, repo, number4, options = {}) {
|
|
68291
|
+
return (await this.getAdapter()).mergePullRequest({
|
|
68292
|
+
owner,
|
|
68293
|
+
repo,
|
|
68294
|
+
pullNumber: number4,
|
|
68295
|
+
...options
|
|
68296
|
+
});
|
|
68297
|
+
}
|
|
68298
|
+
/**
|
|
68299
|
+
* List files or directories at a repository path.
|
|
68300
|
+
*/
|
|
68301
|
+
async listFiles(owner, repo, path25 = "", options = {}) {
|
|
68302
|
+
return (await this.getAdapter()).listFiles({ owner, repo, path: path25, ...options });
|
|
68303
|
+
}
|
|
68304
|
+
/**
|
|
68305
|
+
* Read a repository file and return decoded UTF-8 content.
|
|
68306
|
+
*/
|
|
68307
|
+
async readFile(owner, repo, path25, ref) {
|
|
68308
|
+
return (await this.getAdapter()).readFile({ owner, repo, path: path25, ref });
|
|
68309
|
+
}
|
|
68310
|
+
/**
|
|
68311
|
+
* Create a repository file with a commit message.
|
|
68312
|
+
*/
|
|
68313
|
+
async createFile(owner, repo, path25, content, message, options = {}) {
|
|
68314
|
+
await (await this.getAdapter()).createFile({
|
|
68315
|
+
owner,
|
|
68316
|
+
repo,
|
|
68317
|
+
path: path25,
|
|
68318
|
+
content,
|
|
68319
|
+
message,
|
|
68320
|
+
...options
|
|
68321
|
+
});
|
|
68322
|
+
}
|
|
68323
|
+
/**
|
|
68324
|
+
* Update a repository file with a commit message.
|
|
68325
|
+
*/
|
|
68326
|
+
async updateFile(owner, repo, path25, content, message, sha, options = {}) {
|
|
68327
|
+
return (await this.getAdapter()).updateFile({
|
|
68328
|
+
owner,
|
|
68329
|
+
repo,
|
|
68330
|
+
path: path25,
|
|
68331
|
+
content,
|
|
68332
|
+
message,
|
|
68333
|
+
sha,
|
|
68334
|
+
...options
|
|
68335
|
+
});
|
|
68336
|
+
}
|
|
68337
|
+
/**
|
|
68338
|
+
* Delete a repository file with a commit message.
|
|
68339
|
+
*/
|
|
68340
|
+
async deleteFile(owner, repo, path25, sha, message, options = {}) {
|
|
68341
|
+
await (await this.getAdapter()).deleteFile({
|
|
68342
|
+
owner,
|
|
68343
|
+
repo,
|
|
68344
|
+
path: path25,
|
|
68345
|
+
sha,
|
|
68346
|
+
message,
|
|
68347
|
+
...options
|
|
68348
|
+
});
|
|
68349
|
+
}
|
|
68350
|
+
/**
|
|
68351
|
+
* List repository branches.
|
|
68352
|
+
*/
|
|
68353
|
+
async listBranches(owner, repo) {
|
|
68354
|
+
return (await this.getAdapter()).listBranches({ owner, repo });
|
|
68355
|
+
}
|
|
68356
|
+
/**
|
|
68357
|
+
* Create a branch from another branch, or from the repository default branch.
|
|
68358
|
+
*/
|
|
68359
|
+
async createBranch(owner, repo, branch, options = {}) {
|
|
68360
|
+
await (await this.getAdapter()).createBranch({ owner, repo, branch, ...options });
|
|
68361
|
+
}
|
|
68362
|
+
/**
|
|
68363
|
+
* List repository commits.
|
|
68364
|
+
*/
|
|
68365
|
+
async listCommits(owner, repo, options = {}) {
|
|
68366
|
+
return (await this.getAdapter()).listCommits({ owner, repo, ...options });
|
|
68367
|
+
}
|
|
68368
|
+
/**
|
|
68369
|
+
* Create a Git commit object.
|
|
68370
|
+
*/
|
|
68371
|
+
async createCommit(owner, repo, message, tree, parents, options = {}) {
|
|
68372
|
+
return (await this.getAdapter()).createCommit({
|
|
68373
|
+
owner,
|
|
68374
|
+
repo,
|
|
68375
|
+
message,
|
|
68376
|
+
tree,
|
|
68377
|
+
parents,
|
|
68378
|
+
...options
|
|
68379
|
+
});
|
|
68380
|
+
}
|
|
68381
|
+
/**
|
|
68382
|
+
* Fetch the authenticated user, or a public user by username.
|
|
68383
|
+
*/
|
|
68384
|
+
async getUser(username) {
|
|
68385
|
+
return (await this.getAdapter()).getUser(username ? { username } : void 0);
|
|
68386
|
+
}
|
|
68387
|
+
/**
|
|
68388
|
+
* List organizations for the authenticated user, or for a public user.
|
|
68389
|
+
*/
|
|
68390
|
+
async listOrganizations(username, options = {}) {
|
|
68391
|
+
return (await this.getAdapter()).listOrganizations({ username, ...options });
|
|
68392
|
+
}
|
|
68393
|
+
};
|
|
68394
|
+
|
|
68395
|
+
// packages/github-primitive/src/workflow-step.ts
|
|
68396
|
+
init_types();
|
|
68397
|
+
var GITHUB_INTEGRATION = "github";
|
|
68398
|
+
var RESERVED_PARAM_KEYS = /* @__PURE__ */ new Set([
|
|
68399
|
+
"action",
|
|
68400
|
+
"config",
|
|
68401
|
+
"githubConfig",
|
|
68402
|
+
"output",
|
|
68403
|
+
"params",
|
|
68404
|
+
"actionParams",
|
|
68405
|
+
"repository",
|
|
68406
|
+
"runtime",
|
|
68407
|
+
"ghPath",
|
|
68408
|
+
"timeout",
|
|
68409
|
+
"retryOnRateLimit",
|
|
68410
|
+
"maxRetries"
|
|
68411
|
+
]);
|
|
68412
|
+
function createGitHubStep(config2) {
|
|
68413
|
+
validateGitHubStepConfig(config2);
|
|
68414
|
+
const params = {};
|
|
68415
|
+
if (config2.repo !== void 0) {
|
|
68416
|
+
params.repo = repoToString(config2.repo);
|
|
68417
|
+
}
|
|
68418
|
+
if (config2.params !== void 0) {
|
|
68419
|
+
params.params = JSON.stringify(config2.params);
|
|
68420
|
+
}
|
|
68421
|
+
if (config2.config !== void 0) {
|
|
68422
|
+
params.config = JSON.stringify(config2.config);
|
|
68423
|
+
}
|
|
68424
|
+
if (config2.output !== void 0) {
|
|
68425
|
+
params.output = JSON.stringify(config2.output);
|
|
68426
|
+
}
|
|
68427
|
+
const step = {
|
|
68428
|
+
name: config2.name,
|
|
68429
|
+
type: "integration",
|
|
68430
|
+
integration: GITHUB_INTEGRATION,
|
|
68431
|
+
action: config2.action,
|
|
68432
|
+
params
|
|
68433
|
+
};
|
|
68434
|
+
if (config2.dependsOn !== void 0) step.dependsOn = config2.dependsOn;
|
|
68435
|
+
if (config2.timeoutMs !== void 0) step.timeoutMs = config2.timeoutMs;
|
|
68436
|
+
if (config2.retries !== void 0) step.retries = config2.retries;
|
|
68437
|
+
return step;
|
|
68438
|
+
}
|
|
68439
|
+
var GitHubStepExecutor = class {
|
|
68440
|
+
constructor(options = {}) {
|
|
68441
|
+
this.options = options;
|
|
68442
|
+
}
|
|
68443
|
+
options;
|
|
68444
|
+
async executeAgentStep() {
|
|
68445
|
+
throw new Error("GitHubStepExecutor only executes GitHub integration steps.");
|
|
68446
|
+
}
|
|
68447
|
+
async execute(config2, context = {}) {
|
|
68448
|
+
validateGitHubStepConfig(config2);
|
|
68449
|
+
const runtimeConfig = mergeRuntimeConfig(this.options, context.config, config2.config);
|
|
68450
|
+
if (context.workspaceId && !runtimeConfig.relayCloud?.workspaceId) {
|
|
68451
|
+
runtimeConfig.relayCloud = {
|
|
68452
|
+
...runtimeConfig.relayCloud,
|
|
68453
|
+
workspaceId: context.workspaceId
|
|
68454
|
+
};
|
|
68455
|
+
}
|
|
68456
|
+
const client = context.client ?? new GitHubClient(runtimeConfig);
|
|
68457
|
+
const actionParams = buildActionParams(config2);
|
|
68458
|
+
const result = await client.executeAction(config2.action, actionParams);
|
|
68459
|
+
const runtime = result.metadata?.runtime ?? await safeGetRuntime(client);
|
|
68460
|
+
const output = formatStepOutput2(config2, result, runtime);
|
|
68461
|
+
return {
|
|
68462
|
+
success: result.success,
|
|
68463
|
+
output,
|
|
68464
|
+
result,
|
|
68465
|
+
runtime,
|
|
68466
|
+
error: result.error
|
|
68467
|
+
};
|
|
68468
|
+
}
|
|
68469
|
+
async executeIntegrationStep(step, resolvedParams, context = {}) {
|
|
68470
|
+
if (step.integration !== GITHUB_INTEGRATION) {
|
|
68471
|
+
return {
|
|
68472
|
+
success: false,
|
|
68473
|
+
output: `GitHubStepExecutor only handles "${GITHUB_INTEGRATION}" integration steps`
|
|
68474
|
+
};
|
|
68475
|
+
}
|
|
68476
|
+
try {
|
|
68477
|
+
const config2 = githubStepConfigFromWorkflowStep(step, resolvedParams);
|
|
68478
|
+
const result = await this.execute(config2, context);
|
|
68479
|
+
return {
|
|
68480
|
+
success: result.success,
|
|
68481
|
+
output: result.success ? result.output : result.output || result.error || "GitHub step failed"
|
|
68482
|
+
};
|
|
68483
|
+
} catch (error51) {
|
|
68484
|
+
return {
|
|
68485
|
+
success: false,
|
|
68486
|
+
output: error51 instanceof Error ? error51.message : String(error51)
|
|
68487
|
+
};
|
|
68488
|
+
}
|
|
68489
|
+
}
|
|
68490
|
+
};
|
|
68491
|
+
function githubStepConfigFromWorkflowStep(step, resolvedParams) {
|
|
68492
|
+
const params = normalizeResolvedParams(resolvedParams);
|
|
68493
|
+
const action = step.action;
|
|
68494
|
+
if (!action) {
|
|
68495
|
+
throw new Error(`GitHub step "${step.name}" requires an action`);
|
|
68496
|
+
}
|
|
68497
|
+
const config2 = readJsonParam(params.config ?? params.githubConfig, "config") ?? runtimeConfigFromParams(params);
|
|
68498
|
+
const output = readJsonParam(params.output, "output") ?? void 0;
|
|
68499
|
+
const repo = readRepositoryParam(params);
|
|
68500
|
+
const actionParams = readActionParams(params);
|
|
68501
|
+
return {
|
|
68502
|
+
name: step.name,
|
|
68503
|
+
dependsOn: step.dependsOn,
|
|
68504
|
+
action,
|
|
68505
|
+
repo,
|
|
68506
|
+
params: actionParams,
|
|
68507
|
+
config: config2,
|
|
68508
|
+
output,
|
|
68509
|
+
timeoutMs: step.timeoutMs,
|
|
68510
|
+
retries: step.retries
|
|
68511
|
+
};
|
|
68512
|
+
}
|
|
68513
|
+
function validateGitHubStepConfig(config2) {
|
|
68514
|
+
if (!config2.name) {
|
|
68515
|
+
throw new Error("GitHub step requires a non-empty name");
|
|
68516
|
+
}
|
|
68517
|
+
if (!config2.action || typeof config2.action !== "string") {
|
|
68518
|
+
throw new Error(`GitHub step "${config2.name}" requires an action name`);
|
|
68519
|
+
}
|
|
68520
|
+
if (!GITHUB_ACTIONS.includes(config2.action)) {
|
|
68521
|
+
throw new Error(`GitHub step "${config2.name}" uses unsupported action "${config2.action}"`);
|
|
68522
|
+
}
|
|
68523
|
+
if (config2.repo !== void 0) {
|
|
68524
|
+
parseRepositoryRef(config2.repo);
|
|
68525
|
+
}
|
|
68526
|
+
if (config2.params !== void 0 && !isRecord2(config2.params)) {
|
|
68527
|
+
throw new Error(`GitHub step "${config2.name}" params must be an object`);
|
|
68528
|
+
}
|
|
68529
|
+
}
|
|
68530
|
+
function buildActionParams(config2) {
|
|
68531
|
+
const repo = config2.repo === void 0 ? void 0 : parseRepositoryRef(config2.repo);
|
|
68532
|
+
const params = config2.params ? { ...config2.params } : {};
|
|
68533
|
+
const merged = repo ? { ...repo, ...params } : params;
|
|
68534
|
+
return Object.keys(merged).length === 0 ? void 0 : merged;
|
|
68535
|
+
}
|
|
68536
|
+
function readActionParams(params) {
|
|
68537
|
+
const serializedParams = params.params ?? params.actionParams;
|
|
68538
|
+
if (serializedParams !== void 0) {
|
|
68539
|
+
const parsed = readJsonParam(serializedParams, "params");
|
|
68540
|
+
if (parsed === void 0) return {};
|
|
68541
|
+
if (!isRecord2(parsed)) {
|
|
68542
|
+
throw new Error("GitHub step params.params must be a JSON object");
|
|
68543
|
+
}
|
|
68544
|
+
return parsed;
|
|
68545
|
+
}
|
|
68546
|
+
const actionParams = {};
|
|
68547
|
+
const repoValue = params.repo;
|
|
68548
|
+
const repoIsRepositoryRef = params.owner === void 0 && typeof repoValue === "string" && repoValue.includes("/");
|
|
68549
|
+
for (const [key, value] of Object.entries(params)) {
|
|
68550
|
+
if (RESERVED_PARAM_KEYS.has(key)) continue;
|
|
68551
|
+
if (key === "repo" && repoIsRepositoryRef) continue;
|
|
68552
|
+
actionParams[key] = value;
|
|
68553
|
+
}
|
|
68554
|
+
return actionParams;
|
|
68555
|
+
}
|
|
68556
|
+
function readRepositoryParam(params) {
|
|
68557
|
+
const value = params.repository ?? (params.owner === void 0 ? params.repo : void 0);
|
|
68558
|
+
if (value === void 0) return void 0;
|
|
68559
|
+
if (typeof value === "string" || isRecord2(value)) {
|
|
68560
|
+
return parseRepositoryRef(value);
|
|
68561
|
+
}
|
|
68562
|
+
throw new Error("GitHub step repo must be in owner/repo format");
|
|
68563
|
+
}
|
|
68564
|
+
function runtimeConfigFromParams(params) {
|
|
68565
|
+
const config2 = {};
|
|
68566
|
+
if (typeof params.runtime === "string") {
|
|
68567
|
+
config2.runtime = params.runtime;
|
|
68568
|
+
}
|
|
68569
|
+
if (typeof params.ghPath === "string") {
|
|
68570
|
+
config2.ghPath = params.ghPath;
|
|
68571
|
+
}
|
|
68572
|
+
if (typeof params.timeout === "number") {
|
|
68573
|
+
config2.timeout = params.timeout;
|
|
68574
|
+
}
|
|
68575
|
+
if (typeof params.retryOnRateLimit === "boolean") {
|
|
68576
|
+
config2.retryOnRateLimit = params.retryOnRateLimit;
|
|
68577
|
+
}
|
|
68578
|
+
if (typeof params.maxRetries === "number") {
|
|
68579
|
+
config2.maxRetries = params.maxRetries;
|
|
68580
|
+
}
|
|
68581
|
+
return Object.keys(config2).length === 0 ? void 0 : config2;
|
|
68582
|
+
}
|
|
68583
|
+
function mergeRuntimeConfig(...configs) {
|
|
68584
|
+
const merged = {};
|
|
68585
|
+
for (const config2 of configs) {
|
|
68586
|
+
if (!config2) continue;
|
|
68587
|
+
const { nango, relayCloud, env, ...flatConfig } = config2;
|
|
68588
|
+
Object.assign(merged, flatConfig);
|
|
68589
|
+
if (nango) {
|
|
68590
|
+
merged.nango = {
|
|
68591
|
+
...merged.nango,
|
|
68592
|
+
...nango
|
|
68593
|
+
};
|
|
68594
|
+
}
|
|
68595
|
+
if (relayCloud) {
|
|
68596
|
+
merged.relayCloud = {
|
|
68597
|
+
...merged.relayCloud,
|
|
68598
|
+
...relayCloud
|
|
68599
|
+
};
|
|
68600
|
+
}
|
|
68601
|
+
if (env) {
|
|
68602
|
+
merged.env = {
|
|
68603
|
+
...merged.env,
|
|
68604
|
+
...env
|
|
68605
|
+
};
|
|
68606
|
+
}
|
|
68607
|
+
}
|
|
68608
|
+
return merged;
|
|
68609
|
+
}
|
|
68610
|
+
function formatStepOutput2(config2, result, runtime) {
|
|
68611
|
+
const outputConfig = config2.output ?? {};
|
|
68612
|
+
const mode = outputConfig.mode ?? "data";
|
|
68613
|
+
const format2 = outputConfig.format ?? "json";
|
|
68614
|
+
if (mode === "none") {
|
|
68615
|
+
return "";
|
|
68616
|
+
}
|
|
68617
|
+
let projection = buildOutputProjection(mode, result, runtime, outputConfig);
|
|
68618
|
+
if (outputConfig.path) {
|
|
68619
|
+
projection = resolvePath2(projection, outputConfig.path);
|
|
68620
|
+
}
|
|
68621
|
+
if (format2 === "text") {
|
|
68622
|
+
return projectionToText(projection);
|
|
68623
|
+
}
|
|
68624
|
+
return JSON.stringify(projection, void 0, outputConfig.pretty ? 2 : void 0);
|
|
68625
|
+
}
|
|
68626
|
+
function buildOutputProjection(mode, result, runtime, outputConfig) {
|
|
68627
|
+
if (mode === "raw") {
|
|
68628
|
+
return result.output;
|
|
68629
|
+
}
|
|
68630
|
+
if (mode === "summary") {
|
|
68631
|
+
return withOptionalMetadata(summarizeResult(result, runtime), result, runtime, outputConfig);
|
|
68632
|
+
}
|
|
68633
|
+
if (mode === "result") {
|
|
68634
|
+
const projected = {
|
|
68635
|
+
success: result.success,
|
|
68636
|
+
output: result.output
|
|
68637
|
+
};
|
|
68638
|
+
if (result.data !== void 0) projected.data = result.data;
|
|
68639
|
+
if (result.error !== void 0) projected.error = result.error;
|
|
68640
|
+
return withOptionalMetadata(projected, result, runtime, outputConfig);
|
|
68641
|
+
}
|
|
68642
|
+
const data = result.data ?? (result.output ? result.output : null);
|
|
68643
|
+
return withOptionalMetadata(data, result, runtime, outputConfig);
|
|
68644
|
+
}
|
|
68645
|
+
function summarizeResult(result, runtime) {
|
|
68646
|
+
if (!result.success) {
|
|
68647
|
+
return {
|
|
68648
|
+
success: false,
|
|
68649
|
+
error: result.error ?? "GitHub action failed",
|
|
68650
|
+
runtime
|
|
68651
|
+
};
|
|
68652
|
+
}
|
|
68653
|
+
const data = result.data;
|
|
68654
|
+
if (Array.isArray(data)) {
|
|
68655
|
+
return {
|
|
68656
|
+
success: true,
|
|
68657
|
+
count: data.length,
|
|
68658
|
+
items: data.slice(0, 10).map(summarizeValue),
|
|
68659
|
+
runtime
|
|
68660
|
+
};
|
|
68661
|
+
}
|
|
68662
|
+
return {
|
|
68663
|
+
success: true,
|
|
68664
|
+
value: summarizeValue(data ?? result.output),
|
|
68665
|
+
runtime
|
|
68666
|
+
};
|
|
68667
|
+
}
|
|
68668
|
+
function summarizeValue(value) {
|
|
68669
|
+
if (!isRecord2(value)) {
|
|
68670
|
+
return value;
|
|
68671
|
+
}
|
|
68672
|
+
const summary = {};
|
|
68673
|
+
for (const key of [
|
|
68674
|
+
"fullName",
|
|
68675
|
+
"name",
|
|
68676
|
+
"number",
|
|
68677
|
+
"title",
|
|
68678
|
+
"state",
|
|
68679
|
+
"path",
|
|
68680
|
+
"sha",
|
|
68681
|
+
"type",
|
|
68682
|
+
"defaultBranch",
|
|
68683
|
+
"visibility",
|
|
68684
|
+
"private",
|
|
68685
|
+
"createdAt",
|
|
68686
|
+
"updatedAt",
|
|
68687
|
+
"htmlUrl",
|
|
68688
|
+
"url"
|
|
68689
|
+
]) {
|
|
68690
|
+
if (value[key] !== void 0) {
|
|
68691
|
+
summary[key] = value[key];
|
|
68692
|
+
}
|
|
68693
|
+
}
|
|
68694
|
+
return Object.keys(summary).length > 0 ? summary : value;
|
|
68695
|
+
}
|
|
68696
|
+
function withOptionalMetadata(value, result, runtime, outputConfig) {
|
|
68697
|
+
if (!outputConfig.includeMetadata && !outputConfig.includeRuntime) {
|
|
68698
|
+
return value;
|
|
68699
|
+
}
|
|
68700
|
+
const metadata = {};
|
|
68701
|
+
if (outputConfig.includeRuntime && runtime !== void 0) metadata.runtime = runtime;
|
|
68702
|
+
if (outputConfig.includeMetadata && result.metadata !== void 0) {
|
|
68703
|
+
Object.assign(metadata, result.metadata);
|
|
68704
|
+
}
|
|
68705
|
+
return { value, metadata };
|
|
68706
|
+
}
|
|
68707
|
+
function projectionToText(value) {
|
|
68708
|
+
if (typeof value === "string") return value;
|
|
68709
|
+
if (value === null || value === void 0) return "";
|
|
68710
|
+
if (Array.isArray(value)) {
|
|
68711
|
+
return value.map((entry) => projectionToText(entry)).join("\n");
|
|
68712
|
+
}
|
|
68713
|
+
if (isRecord2(value)) {
|
|
68714
|
+
if ("output" in value) return projectionToText(value.output);
|
|
68715
|
+
if ("value" in value) return projectionToText(value.value);
|
|
68716
|
+
if ("data" in value) return projectionToText(value.data);
|
|
68717
|
+
if ("content" in value) return projectionToText(value.content);
|
|
68718
|
+
if ("body" in value) return projectionToText(value.body);
|
|
68719
|
+
if ("title" in value) return projectionToText(value.title);
|
|
68720
|
+
if ("fullName" in value) return projectionToText(value.fullName);
|
|
68721
|
+
if ("path" in value) return projectionToText(value.path);
|
|
68722
|
+
if ("url" in value) return projectionToText(value.url);
|
|
68723
|
+
}
|
|
68724
|
+
return JSON.stringify(value);
|
|
68725
|
+
}
|
|
68726
|
+
function resolvePath2(value, path25) {
|
|
68727
|
+
if (!path25) return value;
|
|
68728
|
+
let current = value;
|
|
68729
|
+
for (const segment of path25.split(".")) {
|
|
68730
|
+
if (Array.isArray(current) && /^\d+$/.test(segment)) {
|
|
68731
|
+
current = current[Number(segment)];
|
|
68732
|
+
continue;
|
|
68733
|
+
}
|
|
68734
|
+
if (isRecord2(current)) {
|
|
68735
|
+
current = current[segment];
|
|
68736
|
+
continue;
|
|
68737
|
+
}
|
|
68738
|
+
return void 0;
|
|
68739
|
+
}
|
|
68740
|
+
return current;
|
|
68741
|
+
}
|
|
68742
|
+
function parseRepositoryRef(repo) {
|
|
68743
|
+
if (typeof repo === "string") {
|
|
68744
|
+
const [owner2, name2, ...rest] = repo.split("/");
|
|
68745
|
+
if (!owner2 || !name2 || rest.length > 0) {
|
|
68746
|
+
throw new Error(`GitHub repo must be in owner/repo format: ${repo}`);
|
|
68747
|
+
}
|
|
68748
|
+
return {
|
|
68749
|
+
owner: owner2,
|
|
68750
|
+
repo: name2,
|
|
68751
|
+
fullName: `${owner2}/${name2}`
|
|
68752
|
+
};
|
|
68753
|
+
}
|
|
68754
|
+
const owner = typeof repo.owner === "string" ? repo.owner : void 0;
|
|
68755
|
+
const name = typeof repo.repo === "string" ? repo.repo : void 0;
|
|
68756
|
+
if (!owner || !name) {
|
|
68757
|
+
throw new Error("GitHub repo object requires owner and repo");
|
|
68758
|
+
}
|
|
68759
|
+
return {
|
|
68760
|
+
owner,
|
|
68761
|
+
repo: name,
|
|
68762
|
+
fullName: typeof repo.fullName === "string" ? repo.fullName : `${owner}/${name}`
|
|
68763
|
+
};
|
|
68764
|
+
}
|
|
68765
|
+
function repoToString(repo) {
|
|
68766
|
+
return typeof repo === "string" ? repo : `${repo.owner}/${repo.repo}`;
|
|
68767
|
+
}
|
|
68768
|
+
async function safeGetRuntime(client) {
|
|
68769
|
+
try {
|
|
68770
|
+
return await client.getRuntime();
|
|
68771
|
+
} catch {
|
|
68772
|
+
return void 0;
|
|
68773
|
+
}
|
|
68774
|
+
}
|
|
68775
|
+
function normalizeResolvedParams(params) {
|
|
68776
|
+
const normalized = {};
|
|
68777
|
+
for (const [key, value] of Object.entries(params)) {
|
|
68778
|
+
normalized[key] = coerceScalar(value);
|
|
68779
|
+
}
|
|
68780
|
+
return normalized;
|
|
68781
|
+
}
|
|
68782
|
+
function coerceScalar(value) {
|
|
68783
|
+
if (typeof value !== "string") {
|
|
68784
|
+
return value;
|
|
68785
|
+
}
|
|
68786
|
+
const trimmed = value.trim();
|
|
68787
|
+
if (trimmed === "true") return true;
|
|
68788
|
+
if (trimmed === "false") return false;
|
|
68789
|
+
if (trimmed === "null") return null;
|
|
68790
|
+
if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) return Number(trimmed);
|
|
68791
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
68792
|
+
try {
|
|
68793
|
+
return JSON.parse(trimmed);
|
|
68794
|
+
} catch {
|
|
68795
|
+
return value;
|
|
68796
|
+
}
|
|
68797
|
+
}
|
|
68798
|
+
return value;
|
|
68799
|
+
}
|
|
68800
|
+
function readJsonParam(value, name) {
|
|
68801
|
+
if (value === void 0) return void 0;
|
|
68802
|
+
if (typeof value !== "string") return value;
|
|
68803
|
+
try {
|
|
68804
|
+
return JSON.parse(value);
|
|
68805
|
+
} catch (error51) {
|
|
68806
|
+
throw new Error(
|
|
68807
|
+
`GitHub step params.${name} must be valid JSON: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
68808
|
+
);
|
|
68809
|
+
}
|
|
68810
|
+
}
|
|
68811
|
+
function isRecord2(value) {
|
|
68812
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
68813
|
+
}
|
|
68814
|
+
|
|
68815
|
+
// packages/github-primitive/src/index.ts
|
|
68816
|
+
init_branches();
|
|
68817
|
+
init_commits();
|
|
68818
|
+
init_repos();
|
|
68819
|
+
init_issues();
|
|
68820
|
+
init_pulls();
|
|
68821
|
+
init_files();
|
|
68822
|
+
init_users();
|
|
68823
|
+
|
|
66040
68824
|
// packages/utils/dist/name-generator.js
|
|
66041
68825
|
var ADJECTIVES = [
|
|
66042
68826
|
"Blue",
|
|
@@ -66508,14 +69292,14 @@ function benchmarkPatterns(iterations = 1e4) {
|
|
|
66508
69292
|
}
|
|
66509
69293
|
|
|
66510
69294
|
// packages/utils/dist/command-resolver.js
|
|
66511
|
-
var
|
|
69295
|
+
var import_node_child_process12 = require("node:child_process");
|
|
66512
69296
|
var import_node_fs26 = __toESM(require("node:fs"), 1);
|
|
66513
69297
|
function resolveCommand(command) {
|
|
66514
69298
|
if (command.startsWith("/")) {
|
|
66515
69299
|
return resolveSymlinks(command);
|
|
66516
69300
|
}
|
|
66517
69301
|
try {
|
|
66518
|
-
const output = (0,
|
|
69302
|
+
const output = (0, import_node_child_process12.execSync)(`which ${command}`, {
|
|
66519
69303
|
encoding: "utf-8",
|
|
66520
69304
|
stdio: ["pipe", "pipe", "pipe"],
|
|
66521
69305
|
// Ensure we have a reasonable PATH
|
|
@@ -66549,7 +69333,7 @@ function resolveSymlinks(filePath) {
|
|
|
66549
69333
|
}
|
|
66550
69334
|
function commandExists(command) {
|
|
66551
69335
|
try {
|
|
66552
|
-
(0,
|
|
69336
|
+
(0, import_node_child_process12.execSync)(`which ${command}`, {
|
|
66553
69337
|
encoding: "utf-8",
|
|
66554
69338
|
stdio: ["pipe", "pipe", "pipe"]
|
|
66555
69339
|
});
|
|
@@ -66562,7 +69346,7 @@ function commandExists(command) {
|
|
|
66562
69346
|
// packages/utils/dist/git-remote.js
|
|
66563
69347
|
var fs9 = __toESM(require("node:fs"), 1);
|
|
66564
69348
|
var path21 = __toESM(require("node:path"), 1);
|
|
66565
|
-
var
|
|
69349
|
+
var import_node_child_process13 = require("node:child_process");
|
|
66566
69350
|
function parseGitRemoteUrl(url2) {
|
|
66567
69351
|
if (!url2)
|
|
66568
69352
|
return null;
|
|
@@ -66582,7 +69366,7 @@ function getGitRemoteUrl(workingDirectory, remoteName = "origin") {
|
|
|
66582
69366
|
if (!fs9.existsSync(gitDir)) {
|
|
66583
69367
|
return null;
|
|
66584
69368
|
}
|
|
66585
|
-
const result = (0,
|
|
69369
|
+
const result = (0, import_node_child_process13.execSync)(`git remote get-url ${remoteName}`, {
|
|
66586
69370
|
cwd: workingDirectory,
|
|
66587
69371
|
encoding: "utf-8",
|
|
66588
69372
|
timeout: 5e3,
|
|
@@ -67713,7 +70497,7 @@ var HookRegistry = class {
|
|
|
67713
70497
|
};
|
|
67714
70498
|
|
|
67715
70499
|
// packages/trajectory/dist/integration.js
|
|
67716
|
-
var
|
|
70500
|
+
var import_node_child_process14 = require("node:child_process");
|
|
67717
70501
|
|
|
67718
70502
|
// packages/config/dist/project-namespace.js
|
|
67719
70503
|
var import_node_crypto16 = __toESM(require("node:crypto"), 1);
|
|
@@ -67842,7 +70626,7 @@ function getTrajectoryEnvVars(projectRoot) {
|
|
|
67842
70626
|
async function runTrail(args) {
|
|
67843
70627
|
return new Promise((resolve4) => {
|
|
67844
70628
|
const trajectoryEnv = getTrajectoryEnvVars();
|
|
67845
|
-
const proc = (0,
|
|
70629
|
+
const proc = (0, import_node_child_process14.spawn)("trail", args, {
|
|
67846
70630
|
cwd: getProjectPaths2().projectRoot,
|
|
67847
70631
|
env: { ...process.env, ...trajectoryEnv },
|
|
67848
70632
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -68113,7 +70897,7 @@ var TrajectoryIntegration = class {
|
|
|
68113
70897
|
*/
|
|
68114
70898
|
isTrailInstalledSync() {
|
|
68115
70899
|
try {
|
|
68116
|
-
(0,
|
|
70900
|
+
(0, import_node_child_process14.execSync)("which trail", { stdio: "pipe" });
|
|
68117
70901
|
return true;
|
|
68118
70902
|
} catch {
|
|
68119
70903
|
return false;
|
|
@@ -68572,6 +71356,7 @@ init_dist2();
|
|
|
68572
71356
|
ERROR_SEARCH_HINT,
|
|
68573
71357
|
GEMINI_MODEL_OPTIONS,
|
|
68574
71358
|
GeminiModels,
|
|
71359
|
+
GitHubClient,
|
|
68575
71360
|
HARNESS_VALUES,
|
|
68576
71361
|
HOOK_ABI_VERSION,
|
|
68577
71362
|
HookEmitter,
|
|
@@ -68635,6 +71420,7 @@ init_dist2();
|
|
|
68635
71420
|
createConsensusEngine,
|
|
68636
71421
|
createContextCompactor,
|
|
68637
71422
|
createDefaultEventLogger,
|
|
71423
|
+
createGitHubStep,
|
|
68638
71424
|
createLogger,
|
|
68639
71425
|
createMemoryAdapter,
|
|
68640
71426
|
createMemoryHooks,
|
|
@@ -68694,6 +71480,7 @@ init_dist2();
|
|
|
68694
71480
|
getSupportedPlatforms,
|
|
68695
71481
|
getSupportedReasoningEfforts,
|
|
68696
71482
|
getTrajectoryHooks,
|
|
71483
|
+
github,
|
|
68697
71484
|
handleResponse,
|
|
68698
71485
|
hasRelayPtyBinary,
|
|
68699
71486
|
hasUnreadMessages,
|