@posthog/agent 2.3.643 → 2.3.655
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/adapters/claude/permissions/permission-options.js +700 -0
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/tools.js +700 -0
- package/dist/adapters/claude/tools.js.map +1 -1
- package/dist/adapters/codex/local-tools-mcp-server.d.ts +2 -0
- package/dist/adapters/codex/local-tools-mcp-server.js +1172 -0
- package/dist/adapters/codex/local-tools-mcp-server.js.map +1 -0
- package/dist/agent.js +1488 -219
- package/dist/agent.js.map +1 -1
- package/dist/execution-mode.js +700 -0
- package/dist/execution-mode.js.map +1 -1
- package/dist/handoff-checkpoint.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +1604 -339
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +1520 -258
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/claude-agent.ts +32 -2
- package/src/adapters/claude/hooks.test.ts +54 -0
- package/src/adapters/claude/hooks.ts +86 -0
- package/src/adapters/claude/mcp/local-tools.test.ts +50 -0
- package/src/adapters/claude/mcp/local-tools.ts +40 -0
- package/src/adapters/claude/session/options.ts +14 -9
- package/src/adapters/claude/types.ts +1 -0
- package/src/adapters/codex/codex-agent.ts +117 -22
- package/src/adapters/codex/local-tools-mcp-server.ts +71 -0
- package/src/adapters/local-tools/index.ts +22 -0
- package/src/adapters/local-tools/registry.test.ts +57 -0
- package/src/adapters/local-tools/registry.ts +81 -0
- package/src/adapters/local-tools/tools/signed-commit.ts +26 -0
- package/src/adapters/session-meta.ts +16 -0
- package/src/adapters/signed-commit-shared.ts +82 -0
- package/src/server/agent-server.test.ts +2 -4
- package/src/server/agent-server.ts +27 -30
- package/src/utils/common.ts +14 -0
package/dist/server/bin.cjs
CHANGED
|
@@ -509,7 +509,7 @@ var require_has_flag = __commonJS({
|
|
|
509
509
|
var require_supports_color = __commonJS({
|
|
510
510
|
"../../node_modules/supports-color/index.js"(exports2, module2) {
|
|
511
511
|
"use strict";
|
|
512
|
-
var
|
|
512
|
+
var os9 = require("os");
|
|
513
513
|
var tty = require("tty");
|
|
514
514
|
var hasFlag = require_has_flag();
|
|
515
515
|
var { env } = process;
|
|
@@ -557,7 +557,7 @@ var require_supports_color = __commonJS({
|
|
|
557
557
|
return min;
|
|
558
558
|
}
|
|
559
559
|
if (process.platform === "win32") {
|
|
560
|
-
const osRelease =
|
|
560
|
+
const osRelease = os9.release().split(".");
|
|
561
561
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
562
562
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
563
563
|
}
|
|
@@ -805,10 +805,10 @@ var require_src2 = __commonJS({
|
|
|
805
805
|
var fs_1 = require("fs");
|
|
806
806
|
var debug_1 = __importDefault(require_src());
|
|
807
807
|
var log = debug_1.default("@kwsites/file-exists");
|
|
808
|
-
function check(
|
|
809
|
-
log(`checking %s`,
|
|
808
|
+
function check(path18, isFile2, isDirectory) {
|
|
809
|
+
log(`checking %s`, path18);
|
|
810
810
|
try {
|
|
811
|
-
const stat4 = fs_1.statSync(
|
|
811
|
+
const stat4 = fs_1.statSync(path18);
|
|
812
812
|
if (stat4.isFile() && isFile2) {
|
|
813
813
|
log(`[OK] path represents a file`);
|
|
814
814
|
return true;
|
|
@@ -828,8 +828,8 @@ var require_src2 = __commonJS({
|
|
|
828
828
|
throw e;
|
|
829
829
|
}
|
|
830
830
|
}
|
|
831
|
-
function exists2(
|
|
832
|
-
return check(
|
|
831
|
+
function exists2(path18, type = exports2.READABLE) {
|
|
832
|
+
return check(path18, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
|
|
833
833
|
}
|
|
834
834
|
exports2.exists = exists2;
|
|
835
835
|
exports2.FILE = 1;
|
|
@@ -925,11 +925,11 @@ var require_tree_sitter = __commonJS({
|
|
|
925
925
|
throw toThrow;
|
|
926
926
|
};
|
|
927
927
|
var scriptDirectory = "";
|
|
928
|
-
function locateFile(
|
|
928
|
+
function locateFile(path18) {
|
|
929
929
|
if (Module["locateFile"]) {
|
|
930
|
-
return Module["locateFile"](
|
|
930
|
+
return Module["locateFile"](path18, scriptDirectory);
|
|
931
931
|
}
|
|
932
|
-
return scriptDirectory +
|
|
932
|
+
return scriptDirectory + path18;
|
|
933
933
|
}
|
|
934
934
|
var readAsync, readBinary;
|
|
935
935
|
if (ENVIRONMENT_IS_NODE) {
|
|
@@ -943,10 +943,10 @@ var require_tree_sitter = __commonJS({
|
|
|
943
943
|
};
|
|
944
944
|
readAsync = (filename, binary2 = true) => {
|
|
945
945
|
filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
|
|
946
|
-
return new Promise((
|
|
946
|
+
return new Promise((resolve8, reject) => {
|
|
947
947
|
fs.readFile(filename, binary2 ? void 0 : "utf8", (err2, data) => {
|
|
948
948
|
if (err2) reject(err2);
|
|
949
|
-
else
|
|
949
|
+
else resolve8(binary2 ? data.buffer : data);
|
|
950
950
|
});
|
|
951
951
|
});
|
|
952
952
|
};
|
|
@@ -987,13 +987,13 @@ var require_tree_sitter = __commonJS({
|
|
|
987
987
|
}
|
|
988
988
|
readAsync = (url) => {
|
|
989
989
|
if (isFileURI(url)) {
|
|
990
|
-
return new Promise((reject,
|
|
990
|
+
return new Promise((reject, resolve8) => {
|
|
991
991
|
var xhr = new XMLHttpRequest();
|
|
992
992
|
xhr.open("GET", url, true);
|
|
993
993
|
xhr.responseType = "arraybuffer";
|
|
994
994
|
xhr.onload = () => {
|
|
995
995
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
996
|
-
|
|
996
|
+
resolve8(xhr.response);
|
|
997
997
|
}
|
|
998
998
|
reject(xhr.status);
|
|
999
999
|
};
|
|
@@ -1953,8 +1953,8 @@ var require_tree_sitter = __commonJS({
|
|
|
1953
1953
|
}
|
|
1954
1954
|
var libFile = locateFile(libName2);
|
|
1955
1955
|
if (flags2.loadAsync) {
|
|
1956
|
-
return new Promise(function(
|
|
1957
|
-
asyncLoad(libFile,
|
|
1956
|
+
return new Promise(function(resolve8, reject) {
|
|
1957
|
+
asyncLoad(libFile, resolve8, reject);
|
|
1958
1958
|
});
|
|
1959
1959
|
}
|
|
1960
1960
|
if (!readBinary) {
|
|
@@ -3450,8 +3450,8 @@ var require_tree_sitter = __commonJS({
|
|
|
3450
3450
|
} else {
|
|
3451
3451
|
const url = input;
|
|
3452
3452
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
3453
|
-
const
|
|
3454
|
-
bytes = Promise.resolve(
|
|
3453
|
+
const fs15 = require("fs");
|
|
3454
|
+
bytes = Promise.resolve(fs15.readFileSync(url));
|
|
3455
3455
|
} else {
|
|
3456
3456
|
bytes = fetch(url).then((response) => response.arrayBuffer().then((buffer) => {
|
|
3457
3457
|
if (response.ok) {
|
|
@@ -3779,6 +3779,650 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
3779
3779
|
}
|
|
3780
3780
|
});
|
|
3781
3781
|
|
|
3782
|
+
// ../../node_modules/protocols/lib/index.js
|
|
3783
|
+
var require_lib = __commonJS({
|
|
3784
|
+
"../../node_modules/protocols/lib/index.js"(exports2, module2) {
|
|
3785
|
+
"use strict";
|
|
3786
|
+
module2.exports = function protocols(input, first2) {
|
|
3787
|
+
if (first2 === true) {
|
|
3788
|
+
first2 = 0;
|
|
3789
|
+
}
|
|
3790
|
+
var prots = "";
|
|
3791
|
+
if (typeof input === "string") {
|
|
3792
|
+
try {
|
|
3793
|
+
prots = new URL(input).protocol;
|
|
3794
|
+
} catch (e) {
|
|
3795
|
+
}
|
|
3796
|
+
} else if (input && input.constructor === URL) {
|
|
3797
|
+
prots = input.protocol;
|
|
3798
|
+
}
|
|
3799
|
+
var splits = prots.split(/\:|\+/).filter(Boolean);
|
|
3800
|
+
if (typeof first2 === "number") {
|
|
3801
|
+
return splits[first2];
|
|
3802
|
+
}
|
|
3803
|
+
return splits;
|
|
3804
|
+
};
|
|
3805
|
+
}
|
|
3806
|
+
});
|
|
3807
|
+
|
|
3808
|
+
// ../../node_modules/parse-path/lib/index.js
|
|
3809
|
+
var require_lib2 = __commonJS({
|
|
3810
|
+
"../../node_modules/parse-path/lib/index.js"(exports2, module2) {
|
|
3811
|
+
"use strict";
|
|
3812
|
+
var protocols = require_lib();
|
|
3813
|
+
function parsePath(url) {
|
|
3814
|
+
var output = {
|
|
3815
|
+
protocols: [],
|
|
3816
|
+
protocol: null,
|
|
3817
|
+
port: null,
|
|
3818
|
+
resource: "",
|
|
3819
|
+
host: "",
|
|
3820
|
+
user: "",
|
|
3821
|
+
password: "",
|
|
3822
|
+
pathname: "",
|
|
3823
|
+
hash: "",
|
|
3824
|
+
search: "",
|
|
3825
|
+
href: url,
|
|
3826
|
+
query: {},
|
|
3827
|
+
parse_failed: false
|
|
3828
|
+
};
|
|
3829
|
+
try {
|
|
3830
|
+
var parsed = new URL(url);
|
|
3831
|
+
output.protocols = protocols(parsed);
|
|
3832
|
+
output.protocol = output.protocols[0];
|
|
3833
|
+
output.port = parsed.port;
|
|
3834
|
+
output.resource = parsed.hostname;
|
|
3835
|
+
output.host = parsed.host;
|
|
3836
|
+
output.user = parsed.username || "";
|
|
3837
|
+
output.password = parsed.password || "";
|
|
3838
|
+
output.pathname = parsed.pathname;
|
|
3839
|
+
output.hash = parsed.hash.slice(1);
|
|
3840
|
+
output.search = parsed.search.slice(1);
|
|
3841
|
+
output.href = parsed.href;
|
|
3842
|
+
output.query = Object.fromEntries(parsed.searchParams);
|
|
3843
|
+
} catch (e) {
|
|
3844
|
+
output.protocols = ["file"];
|
|
3845
|
+
output.protocol = output.protocols[0];
|
|
3846
|
+
output.port = "";
|
|
3847
|
+
output.resource = "";
|
|
3848
|
+
output.user = "";
|
|
3849
|
+
output.pathname = "";
|
|
3850
|
+
output.hash = "";
|
|
3851
|
+
output.search = "";
|
|
3852
|
+
output.href = url;
|
|
3853
|
+
output.query = {};
|
|
3854
|
+
output.parse_failed = true;
|
|
3855
|
+
}
|
|
3856
|
+
return output;
|
|
3857
|
+
}
|
|
3858
|
+
module2.exports = parsePath;
|
|
3859
|
+
}
|
|
3860
|
+
});
|
|
3861
|
+
|
|
3862
|
+
// ../../node_modules/parse-url/dist/index.js
|
|
3863
|
+
var require_dist3 = __commonJS({
|
|
3864
|
+
"../../node_modules/parse-url/dist/index.js"(exports2, module2) {
|
|
3865
|
+
"use strict";
|
|
3866
|
+
var require$$1 = require_lib2();
|
|
3867
|
+
function _interopDefaultLegacy(e) {
|
|
3868
|
+
return e && typeof e === "object" && "default" in e ? e : { "default": e };
|
|
3869
|
+
}
|
|
3870
|
+
var require$$1__default = /* @__PURE__ */ _interopDefaultLegacy(require$$1);
|
|
3871
|
+
function getAugmentedNamespace(n) {
|
|
3872
|
+
if (n.__esModule) return n;
|
|
3873
|
+
var f = n.default;
|
|
3874
|
+
if (typeof f == "function") {
|
|
3875
|
+
var a = function a2() {
|
|
3876
|
+
if (this instanceof a2) {
|
|
3877
|
+
var args2 = [null];
|
|
3878
|
+
args2.push.apply(args2, arguments);
|
|
3879
|
+
var Ctor = Function.bind.apply(f, args2);
|
|
3880
|
+
return new Ctor();
|
|
3881
|
+
}
|
|
3882
|
+
return f.apply(this, arguments);
|
|
3883
|
+
};
|
|
3884
|
+
a.prototype = f.prototype;
|
|
3885
|
+
} else a = {};
|
|
3886
|
+
Object.defineProperty(a, "__esModule", { value: true });
|
|
3887
|
+
Object.keys(n).forEach(function(k) {
|
|
3888
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
3889
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
3890
|
+
enumerable: true,
|
|
3891
|
+
get: function() {
|
|
3892
|
+
return n[k];
|
|
3893
|
+
}
|
|
3894
|
+
});
|
|
3895
|
+
});
|
|
3896
|
+
return a;
|
|
3897
|
+
}
|
|
3898
|
+
var src = {};
|
|
3899
|
+
var DATA_URL_DEFAULT_MIME_TYPE = "text/plain";
|
|
3900
|
+
var DATA_URL_DEFAULT_CHARSET = "us-ascii";
|
|
3901
|
+
var testParameter = (name2, filters) => filters.some((filter) => filter instanceof RegExp ? filter.test(name2) : filter === name2);
|
|
3902
|
+
var normalizeDataURL = (urlString, { stripHash }) => {
|
|
3903
|
+
const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
|
|
3904
|
+
if (!match) {
|
|
3905
|
+
throw new Error(`Invalid URL: ${urlString}`);
|
|
3906
|
+
}
|
|
3907
|
+
let { type, data, hash } = match.groups;
|
|
3908
|
+
const mediaType = type.split(";");
|
|
3909
|
+
hash = stripHash ? "" : hash;
|
|
3910
|
+
let isBase64 = false;
|
|
3911
|
+
if (mediaType[mediaType.length - 1] === "base64") {
|
|
3912
|
+
mediaType.pop();
|
|
3913
|
+
isBase64 = true;
|
|
3914
|
+
}
|
|
3915
|
+
const mimeType = (mediaType.shift() || "").toLowerCase();
|
|
3916
|
+
const attributes = mediaType.map((attribute) => {
|
|
3917
|
+
let [key, value = ""] = attribute.split("=").map((string) => string.trim());
|
|
3918
|
+
if (key === "charset") {
|
|
3919
|
+
value = value.toLowerCase();
|
|
3920
|
+
if (value === DATA_URL_DEFAULT_CHARSET) {
|
|
3921
|
+
return "";
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
return `${key}${value ? `=${value}` : ""}`;
|
|
3925
|
+
}).filter(Boolean);
|
|
3926
|
+
const normalizedMediaType = [
|
|
3927
|
+
...attributes
|
|
3928
|
+
];
|
|
3929
|
+
if (isBase64) {
|
|
3930
|
+
normalizedMediaType.push("base64");
|
|
3931
|
+
}
|
|
3932
|
+
if (normalizedMediaType.length > 0 || mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE) {
|
|
3933
|
+
normalizedMediaType.unshift(mimeType);
|
|
3934
|
+
}
|
|
3935
|
+
return `data:${normalizedMediaType.join(";")},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ""}`;
|
|
3936
|
+
};
|
|
3937
|
+
function normalizeUrl(urlString, options) {
|
|
3938
|
+
options = {
|
|
3939
|
+
defaultProtocol: "http:",
|
|
3940
|
+
normalizeProtocol: true,
|
|
3941
|
+
forceHttp: false,
|
|
3942
|
+
forceHttps: false,
|
|
3943
|
+
stripAuthentication: true,
|
|
3944
|
+
stripHash: false,
|
|
3945
|
+
stripTextFragment: true,
|
|
3946
|
+
stripWWW: true,
|
|
3947
|
+
removeQueryParameters: [/^utm_\w+/i],
|
|
3948
|
+
removeTrailingSlash: true,
|
|
3949
|
+
removeSingleSlash: true,
|
|
3950
|
+
removeDirectoryIndex: false,
|
|
3951
|
+
sortQueryParameters: true,
|
|
3952
|
+
...options
|
|
3953
|
+
};
|
|
3954
|
+
urlString = urlString.trim();
|
|
3955
|
+
if (/^data:/i.test(urlString)) {
|
|
3956
|
+
return normalizeDataURL(urlString, options);
|
|
3957
|
+
}
|
|
3958
|
+
if (/^view-source:/i.test(urlString)) {
|
|
3959
|
+
throw new Error("`view-source:` is not supported as it is a non-standard protocol");
|
|
3960
|
+
}
|
|
3961
|
+
const hasRelativeProtocol = urlString.startsWith("//");
|
|
3962
|
+
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
|
|
3963
|
+
if (!isRelativeUrl) {
|
|
3964
|
+
urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
|
|
3965
|
+
}
|
|
3966
|
+
const urlObject = new URL(urlString);
|
|
3967
|
+
if (options.forceHttp && options.forceHttps) {
|
|
3968
|
+
throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");
|
|
3969
|
+
}
|
|
3970
|
+
if (options.forceHttp && urlObject.protocol === "https:") {
|
|
3971
|
+
urlObject.protocol = "http:";
|
|
3972
|
+
}
|
|
3973
|
+
if (options.forceHttps && urlObject.protocol === "http:") {
|
|
3974
|
+
urlObject.protocol = "https:";
|
|
3975
|
+
}
|
|
3976
|
+
if (options.stripAuthentication) {
|
|
3977
|
+
urlObject.username = "";
|
|
3978
|
+
urlObject.password = "";
|
|
3979
|
+
}
|
|
3980
|
+
if (options.stripHash) {
|
|
3981
|
+
urlObject.hash = "";
|
|
3982
|
+
} else if (options.stripTextFragment) {
|
|
3983
|
+
urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, "");
|
|
3984
|
+
}
|
|
3985
|
+
if (urlObject.pathname) {
|
|
3986
|
+
const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
|
|
3987
|
+
let lastIndex = 0;
|
|
3988
|
+
let result = "";
|
|
3989
|
+
for (; ; ) {
|
|
3990
|
+
const match = protocolRegex.exec(urlObject.pathname);
|
|
3991
|
+
if (!match) {
|
|
3992
|
+
break;
|
|
3993
|
+
}
|
|
3994
|
+
const protocol = match[0];
|
|
3995
|
+
const protocolAtIndex = match.index;
|
|
3996
|
+
const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
|
|
3997
|
+
result += intermediate.replace(/\/{2,}/g, "/");
|
|
3998
|
+
result += protocol;
|
|
3999
|
+
lastIndex = protocolAtIndex + protocol.length;
|
|
4000
|
+
}
|
|
4001
|
+
const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
|
|
4002
|
+
result += remnant.replace(/\/{2,}/g, "/");
|
|
4003
|
+
urlObject.pathname = result;
|
|
4004
|
+
}
|
|
4005
|
+
if (urlObject.pathname) {
|
|
4006
|
+
try {
|
|
4007
|
+
urlObject.pathname = decodeURI(urlObject.pathname);
|
|
4008
|
+
} catch {
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
if (options.removeDirectoryIndex === true) {
|
|
4012
|
+
options.removeDirectoryIndex = [/^index\.[a-z]+$/];
|
|
4013
|
+
}
|
|
4014
|
+
if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
|
|
4015
|
+
let pathComponents = urlObject.pathname.split("/");
|
|
4016
|
+
const lastComponent = pathComponents[pathComponents.length - 1];
|
|
4017
|
+
if (testParameter(lastComponent, options.removeDirectoryIndex)) {
|
|
4018
|
+
pathComponents = pathComponents.slice(0, -1);
|
|
4019
|
+
urlObject.pathname = pathComponents.slice(1).join("/") + "/";
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
if (urlObject.hostname) {
|
|
4023
|
+
urlObject.hostname = urlObject.hostname.replace(/\.$/, "");
|
|
4024
|
+
if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) {
|
|
4025
|
+
urlObject.hostname = urlObject.hostname.replace(/^www\./, "");
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
4028
|
+
if (Array.isArray(options.removeQueryParameters)) {
|
|
4029
|
+
for (const key of [...urlObject.searchParams.keys()]) {
|
|
4030
|
+
if (testParameter(key, options.removeQueryParameters)) {
|
|
4031
|
+
urlObject.searchParams.delete(key);
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
if (options.removeQueryParameters === true) {
|
|
4036
|
+
urlObject.search = "";
|
|
4037
|
+
}
|
|
4038
|
+
if (options.sortQueryParameters) {
|
|
4039
|
+
urlObject.searchParams.sort();
|
|
4040
|
+
try {
|
|
4041
|
+
urlObject.search = decodeURIComponent(urlObject.search);
|
|
4042
|
+
} catch {
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
if (options.removeTrailingSlash) {
|
|
4046
|
+
urlObject.pathname = urlObject.pathname.replace(/\/$/, "");
|
|
4047
|
+
}
|
|
4048
|
+
const oldUrlString = urlString;
|
|
4049
|
+
urlString = urlObject.toString();
|
|
4050
|
+
if (!options.removeSingleSlash && urlObject.pathname === "/" && !oldUrlString.endsWith("/") && urlObject.hash === "") {
|
|
4051
|
+
urlString = urlString.replace(/\/$/, "");
|
|
4052
|
+
}
|
|
4053
|
+
if ((options.removeTrailingSlash || urlObject.pathname === "/") && urlObject.hash === "" && options.removeSingleSlash) {
|
|
4054
|
+
urlString = urlString.replace(/\/$/, "");
|
|
4055
|
+
}
|
|
4056
|
+
if (hasRelativeProtocol && !options.normalizeProtocol) {
|
|
4057
|
+
urlString = urlString.replace(/^http:\/\//, "//");
|
|
4058
|
+
}
|
|
4059
|
+
if (options.stripProtocol) {
|
|
4060
|
+
urlString = urlString.replace(/^(?:https?:)?\/\//, "");
|
|
4061
|
+
}
|
|
4062
|
+
return urlString;
|
|
4063
|
+
}
|
|
4064
|
+
var normalizeUrl$1 = /* @__PURE__ */ Object.freeze({
|
|
4065
|
+
__proto__: null,
|
|
4066
|
+
"default": normalizeUrl
|
|
4067
|
+
});
|
|
4068
|
+
var require$$0 = /* @__PURE__ */ getAugmentedNamespace(normalizeUrl$1);
|
|
4069
|
+
Object.defineProperty(src, "__esModule", {
|
|
4070
|
+
value: true
|
|
4071
|
+
});
|
|
4072
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
|
|
4073
|
+
return typeof obj;
|
|
4074
|
+
} : function(obj) {
|
|
4075
|
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
4076
|
+
};
|
|
4077
|
+
var _normalizeUrl = require$$0;
|
|
4078
|
+
var _normalizeUrl2 = _interopRequireDefault(_normalizeUrl);
|
|
4079
|
+
var _parsePath = require$$1__default["default"];
|
|
4080
|
+
var _parsePath2 = _interopRequireDefault(_parsePath);
|
|
4081
|
+
function _interopRequireDefault(obj) {
|
|
4082
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
4083
|
+
}
|
|
4084
|
+
var parseUrl = function parseUrl2(url) {
|
|
4085
|
+
var normalize3 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
|
|
4086
|
+
var GIT_RE = /^(?:([a-zA-Z_][a-zA-Z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/;
|
|
4087
|
+
var throwErr = function throwErr2(msg) {
|
|
4088
|
+
var err2 = new Error(msg);
|
|
4089
|
+
err2.subject_url = url;
|
|
4090
|
+
throw err2;
|
|
4091
|
+
};
|
|
4092
|
+
if (typeof url !== "string" || !url.trim()) {
|
|
4093
|
+
throwErr("Invalid url.");
|
|
4094
|
+
}
|
|
4095
|
+
if (url.length > parseUrl2.MAX_INPUT_LENGTH) {
|
|
4096
|
+
throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.");
|
|
4097
|
+
}
|
|
4098
|
+
if (normalize3) {
|
|
4099
|
+
if ((typeof normalize3 === "undefined" ? "undefined" : _typeof(normalize3)) !== "object") {
|
|
4100
|
+
normalize3 = {
|
|
4101
|
+
stripHash: false
|
|
4102
|
+
};
|
|
4103
|
+
}
|
|
4104
|
+
url = (0, _normalizeUrl2.default)(url, normalize3);
|
|
4105
|
+
}
|
|
4106
|
+
var parsed = (0, _parsePath2.default)(url);
|
|
4107
|
+
if (parsed.parse_failed) {
|
|
4108
|
+
var matched = parsed.href.match(GIT_RE);
|
|
4109
|
+
if (matched) {
|
|
4110
|
+
parsed.protocols = ["ssh"];
|
|
4111
|
+
parsed.protocol = "ssh";
|
|
4112
|
+
parsed.resource = matched[2];
|
|
4113
|
+
parsed.host = matched[2];
|
|
4114
|
+
parsed.user = matched[1];
|
|
4115
|
+
parsed.pathname = "/" + matched[3];
|
|
4116
|
+
parsed.parse_failed = false;
|
|
4117
|
+
} else {
|
|
4118
|
+
throwErr("URL parsing failed.");
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
return parsed;
|
|
4122
|
+
};
|
|
4123
|
+
parseUrl.MAX_INPUT_LENGTH = 2048;
|
|
4124
|
+
var _default = src.default = parseUrl;
|
|
4125
|
+
module2.exports = _default;
|
|
4126
|
+
}
|
|
4127
|
+
});
|
|
4128
|
+
|
|
4129
|
+
// ../../node_modules/is-ssh/lib/index.js
|
|
4130
|
+
var require_lib3 = __commonJS({
|
|
4131
|
+
"../../node_modules/is-ssh/lib/index.js"(exports2, module2) {
|
|
4132
|
+
"use strict";
|
|
4133
|
+
var protocols = require_lib();
|
|
4134
|
+
function isSsh(input) {
|
|
4135
|
+
if (Array.isArray(input)) {
|
|
4136
|
+
return input.indexOf("ssh") !== -1 || input.indexOf("rsync") !== -1;
|
|
4137
|
+
}
|
|
4138
|
+
if (typeof input !== "string") {
|
|
4139
|
+
return false;
|
|
4140
|
+
}
|
|
4141
|
+
var prots = protocols(input);
|
|
4142
|
+
input = input.substring(input.indexOf("://") + 3);
|
|
4143
|
+
if (isSsh(prots)) {
|
|
4144
|
+
return true;
|
|
4145
|
+
}
|
|
4146
|
+
var urlPortPattern = new RegExp(".([a-zA-Z\\d]+):(\\d+)/");
|
|
4147
|
+
return !input.match(urlPortPattern) && input.indexOf("@") < input.indexOf(":");
|
|
4148
|
+
}
|
|
4149
|
+
module2.exports = isSsh;
|
|
4150
|
+
}
|
|
4151
|
+
});
|
|
4152
|
+
|
|
4153
|
+
// ../../node_modules/git-up/lib/index.js
|
|
4154
|
+
var require_lib4 = __commonJS({
|
|
4155
|
+
"../../node_modules/git-up/lib/index.js"(exports2, module2) {
|
|
4156
|
+
"use strict";
|
|
4157
|
+
var parseUrl = require_dist3();
|
|
4158
|
+
var isSsh = require_lib3();
|
|
4159
|
+
function gitUp(input) {
|
|
4160
|
+
let output = parseUrl(input);
|
|
4161
|
+
output.token = "";
|
|
4162
|
+
if (output.password === "x-oauth-basic") {
|
|
4163
|
+
output.token = output.user;
|
|
4164
|
+
} else if (output.user === "x-token-auth") {
|
|
4165
|
+
output.token = output.password;
|
|
4166
|
+
}
|
|
4167
|
+
if (isSsh(output.protocols) || output.protocols.length === 0 && isSsh(input)) {
|
|
4168
|
+
output.protocol = "ssh";
|
|
4169
|
+
} else if (output.protocols.length) {
|
|
4170
|
+
output.protocol = output.protocols[0];
|
|
4171
|
+
} else {
|
|
4172
|
+
output.protocol = "file";
|
|
4173
|
+
output.protocols = ["file"];
|
|
4174
|
+
}
|
|
4175
|
+
output.href = output.href.replace(/\/$/, "");
|
|
4176
|
+
return output;
|
|
4177
|
+
}
|
|
4178
|
+
module2.exports = gitUp;
|
|
4179
|
+
}
|
|
4180
|
+
});
|
|
4181
|
+
|
|
4182
|
+
// ../../node_modules/git-url-parse/lib/index.js
|
|
4183
|
+
var require_lib5 = __commonJS({
|
|
4184
|
+
"../../node_modules/git-url-parse/lib/index.js"(exports2, module2) {
|
|
4185
|
+
"use strict";
|
|
4186
|
+
var gitUp = require_lib4();
|
|
4187
|
+
function gitUrlParse2(url, refs) {
|
|
4188
|
+
refs = refs || [];
|
|
4189
|
+
if (typeof url !== "string") {
|
|
4190
|
+
throw new Error("The url must be a string.");
|
|
4191
|
+
}
|
|
4192
|
+
if (!refs.every(function(item) {
|
|
4193
|
+
return typeof item === "string";
|
|
4194
|
+
})) {
|
|
4195
|
+
throw new Error("The refs should contain only strings");
|
|
4196
|
+
}
|
|
4197
|
+
var shorthandRe = /^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;
|
|
4198
|
+
if (shorthandRe.test(url)) {
|
|
4199
|
+
url = "https://github.com/" + url;
|
|
4200
|
+
}
|
|
4201
|
+
var urlInfo = gitUp(url), sourceParts = urlInfo.resource.split("."), splits = null;
|
|
4202
|
+
urlInfo.toString = function(type) {
|
|
4203
|
+
return gitUrlParse2.stringify(this, type);
|
|
4204
|
+
};
|
|
4205
|
+
urlInfo.source = sourceParts.length > 2 ? sourceParts.slice(1 - sourceParts.length).join(".") : urlInfo.source = urlInfo.resource;
|
|
4206
|
+
urlInfo.git_suffix = /\.git$/.test(urlInfo.pathname);
|
|
4207
|
+
urlInfo.name = decodeURIComponent((urlInfo.pathname || urlInfo.href).replace(/(^\/)|(\/$)/g, "").replace(/\.git$/, ""));
|
|
4208
|
+
urlInfo.owner = decodeURIComponent(urlInfo.user);
|
|
4209
|
+
switch (urlInfo.source) {
|
|
4210
|
+
case "git.cloudforge.com":
|
|
4211
|
+
urlInfo.owner = urlInfo.user;
|
|
4212
|
+
urlInfo.organization = sourceParts[0];
|
|
4213
|
+
urlInfo.source = "cloudforge.com";
|
|
4214
|
+
break;
|
|
4215
|
+
case "visualstudio.com":
|
|
4216
|
+
if (urlInfo.resource === "vs-ssh.visualstudio.com") {
|
|
4217
|
+
splits = urlInfo.name.split("/");
|
|
4218
|
+
if (splits.length === 4) {
|
|
4219
|
+
urlInfo.organization = splits[1];
|
|
4220
|
+
urlInfo.owner = splits[2];
|
|
4221
|
+
urlInfo.name = splits[3];
|
|
4222
|
+
urlInfo.full_name = splits[2] + "/" + splits[3];
|
|
4223
|
+
}
|
|
4224
|
+
break;
|
|
4225
|
+
} else {
|
|
4226
|
+
splits = urlInfo.name.split("/");
|
|
4227
|
+
if (splits.length === 2) {
|
|
4228
|
+
urlInfo.owner = splits[1];
|
|
4229
|
+
urlInfo.name = splits[1];
|
|
4230
|
+
urlInfo.full_name = "_git/" + urlInfo.name;
|
|
4231
|
+
} else if (splits.length === 3) {
|
|
4232
|
+
urlInfo.name = splits[2];
|
|
4233
|
+
if (splits[0] === "DefaultCollection") {
|
|
4234
|
+
urlInfo.owner = splits[2];
|
|
4235
|
+
urlInfo.organization = splits[0];
|
|
4236
|
+
urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
|
|
4237
|
+
} else {
|
|
4238
|
+
urlInfo.owner = splits[0];
|
|
4239
|
+
urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4240
|
+
}
|
|
4241
|
+
} else if (splits.length === 4) {
|
|
4242
|
+
urlInfo.organization = splits[0];
|
|
4243
|
+
urlInfo.owner = splits[1];
|
|
4244
|
+
urlInfo.name = splits[3];
|
|
4245
|
+
urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4246
|
+
}
|
|
4247
|
+
break;
|
|
4248
|
+
}
|
|
4249
|
+
// Azure DevOps (formerly Visual Studio Team Services)
|
|
4250
|
+
case "dev.azure.com":
|
|
4251
|
+
case "azure.com":
|
|
4252
|
+
if (urlInfo.resource === "ssh.dev.azure.com") {
|
|
4253
|
+
splits = urlInfo.name.split("/");
|
|
4254
|
+
if (splits.length === 4) {
|
|
4255
|
+
urlInfo.organization = splits[1];
|
|
4256
|
+
urlInfo.owner = splits[2];
|
|
4257
|
+
urlInfo.name = splits[3];
|
|
4258
|
+
}
|
|
4259
|
+
break;
|
|
4260
|
+
} else {
|
|
4261
|
+
splits = urlInfo.name.split("/");
|
|
4262
|
+
if (splits.length === 5) {
|
|
4263
|
+
urlInfo.organization = splits[0];
|
|
4264
|
+
urlInfo.owner = splits[1];
|
|
4265
|
+
urlInfo.name = splits[4];
|
|
4266
|
+
urlInfo.full_name = "_git/" + urlInfo.name;
|
|
4267
|
+
} else if (splits.length === 3) {
|
|
4268
|
+
urlInfo.name = splits[2];
|
|
4269
|
+
if (splits[0] === "DefaultCollection") {
|
|
4270
|
+
urlInfo.owner = splits[2];
|
|
4271
|
+
urlInfo.organization = splits[0];
|
|
4272
|
+
urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
|
|
4273
|
+
} else {
|
|
4274
|
+
urlInfo.owner = splits[0];
|
|
4275
|
+
urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4276
|
+
}
|
|
4277
|
+
} else if (splits.length === 4) {
|
|
4278
|
+
urlInfo.organization = splits[0];
|
|
4279
|
+
urlInfo.owner = splits[1];
|
|
4280
|
+
urlInfo.name = splits[3];
|
|
4281
|
+
urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4282
|
+
}
|
|
4283
|
+
if (urlInfo.query && urlInfo.query["path"]) {
|
|
4284
|
+
urlInfo.filepath = urlInfo.query["path"].replace(/^\/+/g, "");
|
|
4285
|
+
}
|
|
4286
|
+
if (urlInfo.query && urlInfo.query["version"]) {
|
|
4287
|
+
urlInfo.ref = urlInfo.query["version"].replace(/^GB/, "");
|
|
4288
|
+
}
|
|
4289
|
+
break;
|
|
4290
|
+
}
|
|
4291
|
+
default:
|
|
4292
|
+
splits = urlInfo.name.split("/");
|
|
4293
|
+
var nameIndex = splits.length - 1;
|
|
4294
|
+
if (splits.length >= 2) {
|
|
4295
|
+
var dashIndex = splits.indexOf("-", 2);
|
|
4296
|
+
var blobIndex = splits.indexOf("blob", 2);
|
|
4297
|
+
var treeIndex = splits.indexOf("tree", 2);
|
|
4298
|
+
var commitIndex = splits.indexOf("commit", 2);
|
|
4299
|
+
var issuesIndex = splits.indexOf("issues", 2);
|
|
4300
|
+
var srcIndex = splits.indexOf("src", 2);
|
|
4301
|
+
var rawIndex = splits.indexOf("raw", 2);
|
|
4302
|
+
var editIndex = splits.indexOf("edit", 2);
|
|
4303
|
+
nameIndex = dashIndex > 0 ? dashIndex - 1 : blobIndex > 0 && treeIndex > 0 ? Math.min(blobIndex - 1, treeIndex - 1) : blobIndex > 0 ? blobIndex - 1 : issuesIndex > 0 ? issuesIndex - 1 : treeIndex > 0 ? treeIndex - 1 : commitIndex > 0 ? commitIndex - 1 : srcIndex > 0 ? srcIndex - 1 : rawIndex > 0 ? rawIndex - 1 : editIndex > 0 ? editIndex - 1 : nameIndex;
|
|
4304
|
+
urlInfo.owner = splits.slice(0, nameIndex).join("/");
|
|
4305
|
+
urlInfo.name = splits[nameIndex];
|
|
4306
|
+
if (commitIndex && issuesIndex < 0) {
|
|
4307
|
+
urlInfo.commit = splits[nameIndex + 2];
|
|
4308
|
+
}
|
|
4309
|
+
}
|
|
4310
|
+
urlInfo.ref = "";
|
|
4311
|
+
urlInfo.filepathtype = "";
|
|
4312
|
+
urlInfo.filepath = "";
|
|
4313
|
+
var offsetNameIndex = splits.length > nameIndex && splits[nameIndex + 1] === "-" ? nameIndex + 1 : nameIndex;
|
|
4314
|
+
if (splits.length > offsetNameIndex + 2 && ["raw", "src", "blob", "tree", "edit"].indexOf(splits[offsetNameIndex + 1]) >= 0) {
|
|
4315
|
+
urlInfo.filepathtype = splits[offsetNameIndex + 1];
|
|
4316
|
+
urlInfo.ref = splits[offsetNameIndex + 2];
|
|
4317
|
+
if (splits.length > offsetNameIndex + 3) {
|
|
4318
|
+
urlInfo.filepath = splits.slice(offsetNameIndex + 3).join("/");
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
urlInfo.organization = urlInfo.owner;
|
|
4322
|
+
break;
|
|
4323
|
+
}
|
|
4324
|
+
if (!urlInfo.full_name) {
|
|
4325
|
+
urlInfo.full_name = urlInfo.owner;
|
|
4326
|
+
if (urlInfo.name) {
|
|
4327
|
+
urlInfo.full_name && (urlInfo.full_name += "/");
|
|
4328
|
+
urlInfo.full_name += urlInfo.name;
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
if (urlInfo.owner.startsWith("scm/")) {
|
|
4332
|
+
urlInfo.source = "bitbucket-server";
|
|
4333
|
+
urlInfo.owner = urlInfo.owner.replace("scm/", "");
|
|
4334
|
+
urlInfo.organization = urlInfo.owner;
|
|
4335
|
+
urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
|
|
4336
|
+
}
|
|
4337
|
+
var bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/;
|
|
4338
|
+
var matches = bitbucket.exec(urlInfo.pathname);
|
|
4339
|
+
if (matches != null) {
|
|
4340
|
+
urlInfo.source = "bitbucket-server";
|
|
4341
|
+
if (matches[1] === "users") {
|
|
4342
|
+
urlInfo.owner = "~" + matches[2];
|
|
4343
|
+
} else {
|
|
4344
|
+
urlInfo.owner = matches[2];
|
|
4345
|
+
}
|
|
4346
|
+
urlInfo.organization = urlInfo.owner;
|
|
4347
|
+
urlInfo.name = matches[3];
|
|
4348
|
+
splits = matches[4].split("/");
|
|
4349
|
+
if (splits.length > 1) {
|
|
4350
|
+
if (["raw", "browse"].indexOf(splits[1]) >= 0) {
|
|
4351
|
+
urlInfo.filepathtype = splits[1];
|
|
4352
|
+
if (splits.length > 2) {
|
|
4353
|
+
urlInfo.filepath = splits.slice(2).join("/");
|
|
4354
|
+
}
|
|
4355
|
+
} else if (splits[1] === "commits" && splits.length > 2) {
|
|
4356
|
+
urlInfo.commit = splits[2];
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
|
|
4360
|
+
if (urlInfo.query.at) {
|
|
4361
|
+
urlInfo.ref = urlInfo.query.at;
|
|
4362
|
+
} else {
|
|
4363
|
+
urlInfo.ref = "";
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
if (refs.length !== 0 && urlInfo.ref) {
|
|
4367
|
+
urlInfo.ref = findLongestMatchingSubstring(urlInfo.href, refs) || urlInfo.ref;
|
|
4368
|
+
urlInfo.filepath = urlInfo.href.split(urlInfo.ref + "/")[1];
|
|
4369
|
+
}
|
|
4370
|
+
return urlInfo;
|
|
4371
|
+
}
|
|
4372
|
+
gitUrlParse2.stringify = function(obj, type) {
|
|
4373
|
+
type = type || (obj.protocols && obj.protocols.length ? obj.protocols.join("+") : obj.protocol);
|
|
4374
|
+
var port = obj.port ? ":" + obj.port : "";
|
|
4375
|
+
var user = obj.user || "git";
|
|
4376
|
+
var maybeGitSuffix = obj.git_suffix ? ".git" : "";
|
|
4377
|
+
switch (type) {
|
|
4378
|
+
case "ssh":
|
|
4379
|
+
if (port) return "ssh://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
|
|
4380
|
+
else return user + "@" + obj.resource + ":" + obj.full_name + maybeGitSuffix;
|
|
4381
|
+
case "git+ssh":
|
|
4382
|
+
case "ssh+git":
|
|
4383
|
+
case "ftp":
|
|
4384
|
+
case "ftps":
|
|
4385
|
+
return type + "://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
|
|
4386
|
+
case "http":
|
|
4387
|
+
case "https":
|
|
4388
|
+
var auth = obj.token ? buildToken(obj) : obj.user && (obj.protocols.includes("http") || obj.protocols.includes("https")) ? obj.user + "@" : "";
|
|
4389
|
+
return type + "://" + auth + obj.resource + port + "/" + buildPath(obj) + maybeGitSuffix;
|
|
4390
|
+
default:
|
|
4391
|
+
return obj.href;
|
|
4392
|
+
}
|
|
4393
|
+
};
|
|
4394
|
+
function buildToken(obj) {
|
|
4395
|
+
switch (obj.source) {
|
|
4396
|
+
case "bitbucket.org":
|
|
4397
|
+
return "x-token-auth:" + obj.token + "@";
|
|
4398
|
+
default:
|
|
4399
|
+
return obj.token + "@";
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
function buildPath(obj) {
|
|
4403
|
+
switch (obj.source) {
|
|
4404
|
+
case "bitbucket-server":
|
|
4405
|
+
return "scm/" + obj.full_name;
|
|
4406
|
+
default:
|
|
4407
|
+
var encoded_full_name = obj.full_name.split("/").map(function(x) {
|
|
4408
|
+
return encodeURIComponent(x);
|
|
4409
|
+
}).join("/");
|
|
4410
|
+
return encoded_full_name;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
function findLongestMatchingSubstring(string, array) {
|
|
4414
|
+
var longestMatch = "";
|
|
4415
|
+
array.forEach(function(item) {
|
|
4416
|
+
if (string.includes(item) && item.length > longestMatch.length) {
|
|
4417
|
+
longestMatch = item;
|
|
4418
|
+
}
|
|
4419
|
+
});
|
|
4420
|
+
return longestMatch;
|
|
4421
|
+
}
|
|
4422
|
+
module2.exports = gitUrlParse2;
|
|
4423
|
+
}
|
|
4424
|
+
});
|
|
4425
|
+
|
|
3782
4426
|
// src/server/bin.ts
|
|
3783
4427
|
var import_commander = require("commander");
|
|
3784
4428
|
var import_v42 = require("zod/v4");
|
|
@@ -3955,6 +4599,24 @@ var import_node_fs = require("fs");
|
|
|
3955
4599
|
var fs3 = __toESM(require("fs/promises"), 1);
|
|
3956
4600
|
var path2 = __toESM(require("path"), 1);
|
|
3957
4601
|
|
|
4602
|
+
// ../git/dist/concurrency.js
|
|
4603
|
+
async function mapWithConcurrency(items, concurrency, mapper, options) {
|
|
4604
|
+
if (items.length === 0)
|
|
4605
|
+
return [];
|
|
4606
|
+
const results = new Array(items.length);
|
|
4607
|
+
let index = 0;
|
|
4608
|
+
const worker = async () => {
|
|
4609
|
+
while (index < items.length) {
|
|
4610
|
+
if (options?.signal?.aborted)
|
|
4611
|
+
return;
|
|
4612
|
+
const i2 = index++;
|
|
4613
|
+
results[i2] = await mapper(items[i2]);
|
|
4614
|
+
}
|
|
4615
|
+
};
|
|
4616
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
4617
|
+
return results;
|
|
4618
|
+
}
|
|
4619
|
+
|
|
3958
4620
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
3959
4621
|
var import_node_buffer = require("buffer");
|
|
3960
4622
|
var import_file_exists = __toESM(require_dist(), 1);
|
|
@@ -3992,8 +4654,8 @@ function pathspec(...paths) {
|
|
|
3992
4654
|
cache.set(key, paths);
|
|
3993
4655
|
return key;
|
|
3994
4656
|
}
|
|
3995
|
-
function isPathSpec(
|
|
3996
|
-
return
|
|
4657
|
+
function isPathSpec(path18) {
|
|
4658
|
+
return path18 instanceof String && cache.has(path18);
|
|
3997
4659
|
}
|
|
3998
4660
|
function toPaths(pathSpec) {
|
|
3999
4661
|
return cache.get(pathSpec) || [];
|
|
@@ -4082,8 +4744,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
4082
4744
|
function forEachLineWithContent(input, callback) {
|
|
4083
4745
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
4084
4746
|
}
|
|
4085
|
-
function folderExists(
|
|
4086
|
-
return (0, import_file_exists.exists)(
|
|
4747
|
+
function folderExists(path18) {
|
|
4748
|
+
return (0, import_file_exists.exists)(path18, import_file_exists.FOLDER);
|
|
4087
4749
|
}
|
|
4088
4750
|
function append(target, item) {
|
|
4089
4751
|
if (Array.isArray(target)) {
|
|
@@ -4487,8 +5149,8 @@ function checkIsRepoRootTask() {
|
|
|
4487
5149
|
commands,
|
|
4488
5150
|
format: "utf-8",
|
|
4489
5151
|
onError,
|
|
4490
|
-
parser(
|
|
4491
|
-
return /^\.(git)?$/.test(
|
|
5152
|
+
parser(path18) {
|
|
5153
|
+
return /^\.(git)?$/.test(path18.trim());
|
|
4492
5154
|
}
|
|
4493
5155
|
};
|
|
4494
5156
|
}
|
|
@@ -4922,11 +5584,11 @@ function parseGrep(grep) {
|
|
|
4922
5584
|
const paths = /* @__PURE__ */ new Set();
|
|
4923
5585
|
const results = {};
|
|
4924
5586
|
forEachLineWithContent(grep, (input) => {
|
|
4925
|
-
const [
|
|
4926
|
-
paths.add(
|
|
4927
|
-
(results[
|
|
5587
|
+
const [path18, line, preview] = input.split(NULL);
|
|
5588
|
+
paths.add(path18);
|
|
5589
|
+
(results[path18] = results[path18] || []).push({
|
|
4928
5590
|
line: asNumber(line),
|
|
4929
|
-
path:
|
|
5591
|
+
path: path18,
|
|
4930
5592
|
preview
|
|
4931
5593
|
});
|
|
4932
5594
|
});
|
|
@@ -5691,14 +6353,14 @@ var init_hash_object = __esm({
|
|
|
5691
6353
|
init_task();
|
|
5692
6354
|
}
|
|
5693
6355
|
});
|
|
5694
|
-
function parseInit(bare,
|
|
6356
|
+
function parseInit(bare, path18, text2) {
|
|
5695
6357
|
const response = String(text2).trim();
|
|
5696
6358
|
let result;
|
|
5697
6359
|
if (result = initResponseRegex.exec(response)) {
|
|
5698
|
-
return new InitSummary(bare,
|
|
6360
|
+
return new InitSummary(bare, path18, false, result[1]);
|
|
5699
6361
|
}
|
|
5700
6362
|
if (result = reInitResponseRegex.exec(response)) {
|
|
5701
|
-
return new InitSummary(bare,
|
|
6363
|
+
return new InitSummary(bare, path18, true, result[1]);
|
|
5702
6364
|
}
|
|
5703
6365
|
let gitDir = "";
|
|
5704
6366
|
const tokens = response.split(" ");
|
|
@@ -5709,7 +6371,7 @@ function parseInit(bare, path17, text2) {
|
|
|
5709
6371
|
break;
|
|
5710
6372
|
}
|
|
5711
6373
|
}
|
|
5712
|
-
return new InitSummary(bare,
|
|
6374
|
+
return new InitSummary(bare, path18, /^re/i.test(response), gitDir);
|
|
5713
6375
|
}
|
|
5714
6376
|
var InitSummary;
|
|
5715
6377
|
var initResponseRegex;
|
|
@@ -5718,9 +6380,9 @@ var init_InitSummary = __esm({
|
|
|
5718
6380
|
"src/lib/responses/InitSummary.ts"() {
|
|
5719
6381
|
"use strict";
|
|
5720
6382
|
InitSummary = class {
|
|
5721
|
-
constructor(bare,
|
|
6383
|
+
constructor(bare, path18, existing, gitDir) {
|
|
5722
6384
|
this.bare = bare;
|
|
5723
|
-
this.path =
|
|
6385
|
+
this.path = path18;
|
|
5724
6386
|
this.existing = existing;
|
|
5725
6387
|
this.gitDir = gitDir;
|
|
5726
6388
|
}
|
|
@@ -5732,7 +6394,7 @@ var init_InitSummary = __esm({
|
|
|
5732
6394
|
function hasBareCommand(command) {
|
|
5733
6395
|
return command.includes(bareCommand);
|
|
5734
6396
|
}
|
|
5735
|
-
function initTask(bare = false,
|
|
6397
|
+
function initTask(bare = false, path18, customArgs) {
|
|
5736
6398
|
const commands = ["init", ...customArgs];
|
|
5737
6399
|
if (bare && !hasBareCommand(commands)) {
|
|
5738
6400
|
commands.splice(1, 0, bareCommand);
|
|
@@ -5741,7 +6403,7 @@ function initTask(bare = false, path17, customArgs) {
|
|
|
5741
6403
|
commands,
|
|
5742
6404
|
format: "utf-8",
|
|
5743
6405
|
parser(text2) {
|
|
5744
|
-
return parseInit(commands.includes("--bare"),
|
|
6406
|
+
return parseInit(commands.includes("--bare"), path18, text2);
|
|
5745
6407
|
}
|
|
5746
6408
|
};
|
|
5747
6409
|
}
|
|
@@ -6557,12 +7219,12 @@ var init_FileStatusSummary = __esm({
|
|
|
6557
7219
|
"use strict";
|
|
6558
7220
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
6559
7221
|
FileStatusSummary = class {
|
|
6560
|
-
constructor(
|
|
6561
|
-
this.path =
|
|
7222
|
+
constructor(path18, index, working_dir) {
|
|
7223
|
+
this.path = path18;
|
|
6562
7224
|
this.index = index;
|
|
6563
7225
|
this.working_dir = working_dir;
|
|
6564
7226
|
if (index === "R" || working_dir === "R") {
|
|
6565
|
-
const detail = fromPathRegex.exec(
|
|
7227
|
+
const detail = fromPathRegex.exec(path18) || [null, path18, path18];
|
|
6566
7228
|
this.from = detail[2] || "";
|
|
6567
7229
|
this.path = detail[1] || "";
|
|
6568
7230
|
}
|
|
@@ -6593,14 +7255,14 @@ function splitLine(result, lineStr) {
|
|
|
6593
7255
|
default:
|
|
6594
7256
|
return;
|
|
6595
7257
|
}
|
|
6596
|
-
function data(index, workingDir,
|
|
7258
|
+
function data(index, workingDir, path18) {
|
|
6597
7259
|
const raw = `${index}${workingDir}`;
|
|
6598
7260
|
const handler = parsers6.get(raw);
|
|
6599
7261
|
if (handler) {
|
|
6600
|
-
handler(result,
|
|
7262
|
+
handler(result, path18);
|
|
6601
7263
|
}
|
|
6602
7264
|
if (raw !== "##" && raw !== "!!") {
|
|
6603
|
-
result.files.push(new FileStatusSummary(
|
|
7265
|
+
result.files.push(new FileStatusSummary(path18, index, workingDir));
|
|
6604
7266
|
}
|
|
6605
7267
|
}
|
|
6606
7268
|
}
|
|
@@ -6913,9 +7575,9 @@ var init_simple_git_api = __esm({
|
|
|
6913
7575
|
next
|
|
6914
7576
|
);
|
|
6915
7577
|
}
|
|
6916
|
-
hashObject(
|
|
7578
|
+
hashObject(path18, write) {
|
|
6917
7579
|
return this._runTask(
|
|
6918
|
-
hashObjectTask(
|
|
7580
|
+
hashObjectTask(path18, write === true),
|
|
6919
7581
|
trailingFunctionArgument(arguments)
|
|
6920
7582
|
);
|
|
6921
7583
|
}
|
|
@@ -7268,8 +7930,8 @@ var init_branch = __esm({
|
|
|
7268
7930
|
}
|
|
7269
7931
|
});
|
|
7270
7932
|
function toPath(input) {
|
|
7271
|
-
const
|
|
7272
|
-
return
|
|
7933
|
+
const path18 = input.trim().replace(/^["']|["']$/g, "");
|
|
7934
|
+
return path18 && (0, import_node_path.normalize)(path18);
|
|
7273
7935
|
}
|
|
7274
7936
|
var parseCheckIgnore;
|
|
7275
7937
|
var init_CheckIgnore = __esm({
|
|
@@ -7583,8 +8245,8 @@ __export(sub_module_exports, {
|
|
|
7583
8245
|
subModuleTask: () => subModuleTask,
|
|
7584
8246
|
updateSubModuleTask: () => updateSubModuleTask
|
|
7585
8247
|
});
|
|
7586
|
-
function addSubModuleTask(repo,
|
|
7587
|
-
return subModuleTask(["add", repo,
|
|
8248
|
+
function addSubModuleTask(repo, path18) {
|
|
8249
|
+
return subModuleTask(["add", repo, path18]);
|
|
7588
8250
|
}
|
|
7589
8251
|
function initSubModuleTask(customArgs) {
|
|
7590
8252
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -7914,8 +8576,8 @@ var require_git = __commonJS2({
|
|
|
7914
8576
|
}
|
|
7915
8577
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
7916
8578
|
};
|
|
7917
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
7918
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
8579
|
+
Git2.prototype.submoduleAdd = function(repo, path18, then) {
|
|
8580
|
+
return this._runTask(addSubModuleTask2(repo, path18), trailingFunctionArgument2(arguments));
|
|
7919
8581
|
};
|
|
7920
8582
|
Git2.prototype.submoduleUpdate = function(args2, then) {
|
|
7921
8583
|
return this._runTask(
|
|
@@ -8576,10 +9238,10 @@ var AsyncReaderWriterLock = class {
|
|
|
8576
9238
|
this.readers++;
|
|
8577
9239
|
return;
|
|
8578
9240
|
}
|
|
8579
|
-
return new Promise((
|
|
9241
|
+
return new Promise((resolve8) => {
|
|
8580
9242
|
this.readQueue.push(() => {
|
|
8581
9243
|
this.readers++;
|
|
8582
|
-
|
|
9244
|
+
resolve8();
|
|
8583
9245
|
});
|
|
8584
9246
|
});
|
|
8585
9247
|
}
|
|
@@ -8593,11 +9255,11 @@ var AsyncReaderWriterLock = class {
|
|
|
8593
9255
|
return;
|
|
8594
9256
|
}
|
|
8595
9257
|
this.writerWaiting = true;
|
|
8596
|
-
return new Promise((
|
|
9258
|
+
return new Promise((resolve8) => {
|
|
8597
9259
|
this.writeQueue.push(() => {
|
|
8598
9260
|
this.writerWaiting = this.writeQueue.length > 0;
|
|
8599
9261
|
this.writer = true;
|
|
8600
|
-
|
|
9262
|
+
resolve8();
|
|
8601
9263
|
});
|
|
8602
9264
|
});
|
|
8603
9265
|
}
|
|
@@ -8804,12 +9466,12 @@ async function inspectGitBusyState(git) {
|
|
|
8804
9466
|
|
|
8805
9467
|
// src/server/agent-server.ts
|
|
8806
9468
|
var import_hono = require("hono");
|
|
8807
|
-
var
|
|
9469
|
+
var import_zod4 = require("zod");
|
|
8808
9470
|
|
|
8809
9471
|
// package.json
|
|
8810
9472
|
var package_default = {
|
|
8811
9473
|
name: "@posthog/agent",
|
|
8812
|
-
version: "2.3.
|
|
9474
|
+
version: "2.3.655",
|
|
8813
9475
|
repository: "https://github.com/PostHog/code",
|
|
8814
9476
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8815
9477
|
exports: {
|
|
@@ -9081,17 +9743,17 @@ var Pushable = class {
|
|
|
9081
9743
|
resolvers = [];
|
|
9082
9744
|
done = false;
|
|
9083
9745
|
push(item) {
|
|
9084
|
-
const
|
|
9085
|
-
if (
|
|
9086
|
-
|
|
9746
|
+
const resolve8 = this.resolvers.shift();
|
|
9747
|
+
if (resolve8) {
|
|
9748
|
+
resolve8({ value: item, done: false });
|
|
9087
9749
|
} else {
|
|
9088
9750
|
this.queue.push(item);
|
|
9089
9751
|
}
|
|
9090
9752
|
}
|
|
9091
9753
|
end() {
|
|
9092
9754
|
this.done = true;
|
|
9093
|
-
for (const
|
|
9094
|
-
|
|
9755
|
+
for (const resolve8 of this.resolvers) {
|
|
9756
|
+
resolve8({ value: void 0, done: true });
|
|
9095
9757
|
}
|
|
9096
9758
|
this.resolvers = [];
|
|
9097
9759
|
}
|
|
@@ -9108,8 +9770,8 @@ var Pushable = class {
|
|
|
9108
9770
|
done: true
|
|
9109
9771
|
});
|
|
9110
9772
|
}
|
|
9111
|
-
return new Promise((
|
|
9112
|
-
this.resolvers.push(
|
|
9773
|
+
return new Promise((resolve8) => {
|
|
9774
|
+
this.resolvers.push(resolve8);
|
|
9113
9775
|
});
|
|
9114
9776
|
}
|
|
9115
9777
|
};
|
|
@@ -9223,20 +9885,20 @@ function nodeReadableToWebReadable(nodeStream) {
|
|
|
9223
9885
|
function nodeWritableToWebWritable(nodeStream) {
|
|
9224
9886
|
return new import_web.WritableStream({
|
|
9225
9887
|
write(chunk) {
|
|
9226
|
-
return new Promise((
|
|
9888
|
+
return new Promise((resolve8, reject) => {
|
|
9227
9889
|
const ok = nodeStream.write(Buffer.from(chunk), (err2) => {
|
|
9228
9890
|
if (err2) reject(err2);
|
|
9229
9891
|
});
|
|
9230
9892
|
if (ok) {
|
|
9231
|
-
|
|
9893
|
+
resolve8();
|
|
9232
9894
|
} else {
|
|
9233
|
-
nodeStream.once("drain",
|
|
9895
|
+
nodeStream.once("drain", resolve8);
|
|
9234
9896
|
}
|
|
9235
9897
|
});
|
|
9236
9898
|
},
|
|
9237
9899
|
close() {
|
|
9238
|
-
return new Promise((
|
|
9239
|
-
nodeStream.end(
|
|
9900
|
+
return new Promise((resolve8) => {
|
|
9901
|
+
nodeStream.end(resolve8);
|
|
9240
9902
|
});
|
|
9241
9903
|
},
|
|
9242
9904
|
abort(reason) {
|
|
@@ -9249,11 +9911,11 @@ function nodeWritableToWebWritable(nodeStream) {
|
|
|
9249
9911
|
|
|
9250
9912
|
// src/adapters/claude/claude-agent.ts
|
|
9251
9913
|
var import_node_crypto = require("crypto");
|
|
9252
|
-
var
|
|
9253
|
-
var
|
|
9254
|
-
var
|
|
9914
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
9915
|
+
var os6 = __toESM(require("os"), 1);
|
|
9916
|
+
var path12 = __toESM(require("path"), 1);
|
|
9255
9917
|
var import_sdk2 = require("@agentclientprotocol/sdk");
|
|
9256
|
-
var
|
|
9918
|
+
var import_claude_agent_sdk2 = require("@anthropic-ai/claude-agent-sdk");
|
|
9257
9919
|
var import_uuid = require("uuid");
|
|
9258
9920
|
|
|
9259
9921
|
// src/enrichment/file-enricher.ts
|
|
@@ -13389,10 +14051,360 @@ async function buildWrapperContext(deps, content, langId, absPath) {
|
|
|
13389
14051
|
return { wrappersByLocalName, namespaceWrappers };
|
|
13390
14052
|
}
|
|
13391
14053
|
|
|
14054
|
+
// ../git/dist/signed-commit.js
|
|
14055
|
+
var childProcess3 = __toESM(require("child_process"), 1);
|
|
14056
|
+
|
|
14057
|
+
// ../git/dist/gh.js
|
|
14058
|
+
var childProcess = __toESM(require("child_process"), 1);
|
|
14059
|
+
function execGh(args2, options = {}) {
|
|
14060
|
+
const env = options.env ? { ...process.env, ...options.env } : process.env;
|
|
14061
|
+
return new Promise((resolve8) => {
|
|
14062
|
+
const child = childProcess.execFile("gh", args2, { cwd: options.cwd, env, timeout: options.timeoutMs ?? 0 }, (error, stdout, stderr) => {
|
|
14063
|
+
if (!error) {
|
|
14064
|
+
resolve8({ stdout, stderr, exitCode: 0 });
|
|
14065
|
+
return;
|
|
14066
|
+
}
|
|
14067
|
+
const err2 = error;
|
|
14068
|
+
const timedOut = err2.killed === true && !!options.timeoutMs;
|
|
14069
|
+
const exitCode = typeof err2.code === "number" ? err2.code : err2.code === "ENOENT" ? 127 : 1;
|
|
14070
|
+
resolve8({
|
|
14071
|
+
stdout: stdout ?? err2.stdout ?? "",
|
|
14072
|
+
stderr: stderr ?? err2.stderr ?? "",
|
|
14073
|
+
exitCode,
|
|
14074
|
+
error: timedOut ? `gh timed out after ${options.timeoutMs}ms` : err2.message
|
|
14075
|
+
});
|
|
14076
|
+
});
|
|
14077
|
+
if (options.input !== void 0) {
|
|
14078
|
+
child.stdin?.end(options.input);
|
|
14079
|
+
}
|
|
14080
|
+
});
|
|
14081
|
+
}
|
|
14082
|
+
var TRANSIENT_GH_PATTERNS = [
|
|
14083
|
+
/HTTP 5\d\d/,
|
|
14084
|
+
/HTTP 499/,
|
|
14085
|
+
/\btimed out\b/i,
|
|
14086
|
+
/\bETIMEDOUT\b/,
|
|
14087
|
+
/\bECONNRESET\b/,
|
|
14088
|
+
/\bECONNREFUSED\b/,
|
|
14089
|
+
/\bEAI_AGAIN\b/,
|
|
14090
|
+
/connection reset/i
|
|
14091
|
+
];
|
|
14092
|
+
function isTransientGhFailure(res) {
|
|
14093
|
+
if (res.exitCode === 0) {
|
|
14094
|
+
return false;
|
|
14095
|
+
}
|
|
14096
|
+
const text2 = `${res.stderr} ${res.error ?? ""} ${res.stdout}`;
|
|
14097
|
+
return TRANSIENT_GH_PATTERNS.some((re) => re.test(text2));
|
|
14098
|
+
}
|
|
14099
|
+
var sleep = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
14100
|
+
async function execGhWithRetry(args2, options = {}, retry = {}, exec = execGh) {
|
|
14101
|
+
const maxAttempts = retry.maxAttempts ?? 3;
|
|
14102
|
+
const backoffMs = retry.backoffMs ?? 500;
|
|
14103
|
+
let res = await exec(args2, options);
|
|
14104
|
+
for (let attempt = 2; attempt <= maxAttempts && isTransientGhFailure(res); attempt++) {
|
|
14105
|
+
await sleep(backoffMs * 2 ** (attempt - 2));
|
|
14106
|
+
res = await exec(args2, options);
|
|
14107
|
+
}
|
|
14108
|
+
return res;
|
|
14109
|
+
}
|
|
14110
|
+
|
|
14111
|
+
// ../git/dist/trailers.js
|
|
14112
|
+
function buildPostHogTrailers(taskId) {
|
|
14113
|
+
const trailers = ["Generated-By: PostHog Code"];
|
|
14114
|
+
if (taskId)
|
|
14115
|
+
trailers.push(`Task-Id: ${taskId}`);
|
|
14116
|
+
return trailers;
|
|
14117
|
+
}
|
|
14118
|
+
|
|
14119
|
+
// ../git/dist/utils.js
|
|
14120
|
+
var childProcess2 = __toESM(require("child_process"), 1);
|
|
14121
|
+
var fs5 = __toESM(require("fs/promises"), 1);
|
|
14122
|
+
var os = __toESM(require("os"), 1);
|
|
14123
|
+
var path5 = __toESM(require("path"), 1);
|
|
14124
|
+
var import_git_url_parse = __toESM(require_lib5(), 1);
|
|
14125
|
+
function parseGithubUrl(url) {
|
|
14126
|
+
if (!url)
|
|
14127
|
+
return null;
|
|
14128
|
+
let parsed;
|
|
14129
|
+
try {
|
|
14130
|
+
parsed = (0, import_git_url_parse.default)(url.trim());
|
|
14131
|
+
} catch {
|
|
14132
|
+
return null;
|
|
14133
|
+
}
|
|
14134
|
+
const resource = parsed.resource.toLowerCase();
|
|
14135
|
+
if (resource !== "github.com" && resource !== "ssh.github.com")
|
|
14136
|
+
return null;
|
|
14137
|
+
const raw = parsed.pathname.split("/");
|
|
14138
|
+
if (raw[0] !== "")
|
|
14139
|
+
return null;
|
|
14140
|
+
const parts2 = raw[raw.length - 1] === "" ? raw.slice(1, -1) : raw.slice(1);
|
|
14141
|
+
if (parts2.length < 2 || parts2.some((p) => p === ""))
|
|
14142
|
+
return null;
|
|
14143
|
+
const [owner, repoRaw, segment, num] = parts2;
|
|
14144
|
+
const repo = repoRaw.replace(/\.git$/, "");
|
|
14145
|
+
if (segment === "issues" || segment === "pull") {
|
|
14146
|
+
const number = Number(num);
|
|
14147
|
+
if (!Number.isInteger(number) || number <= 0)
|
|
14148
|
+
return null;
|
|
14149
|
+
return {
|
|
14150
|
+
kind: segment === "pull" ? "pr" : "issue",
|
|
14151
|
+
owner,
|
|
14152
|
+
repo,
|
|
14153
|
+
number
|
|
14154
|
+
};
|
|
14155
|
+
}
|
|
14156
|
+
return { kind: "repo", owner, repo };
|
|
14157
|
+
}
|
|
14158
|
+
|
|
14159
|
+
// ../git/dist/signed-commit.js
|
|
14160
|
+
var DEFAULT_MAX_PAYLOAD_BYTES = 35 * 1024 * 1024;
|
|
14161
|
+
var MAX_GIT_BUFFER = 256 * 1024 * 1024;
|
|
14162
|
+
var GH_GRAPHQL_TIMEOUT_MS = 3e4;
|
|
14163
|
+
var OversizedFileError = class extends Error {
|
|
14164
|
+
path;
|
|
14165
|
+
bytes;
|
|
14166
|
+
maxBytes;
|
|
14167
|
+
constructor(path18, bytes, maxBytes) {
|
|
14168
|
+
super(`File '${path18}' (~${Math.round(bytes / 1024 / 1024)}MB once base64-encoded) exceeds the per-commit request limit (~${Math.round(maxBytes / 1024 / 1024)}MB). A single file cannot be split across createCommitOnBranch requests; use Git LFS or a local signing key for this change.`);
|
|
14169
|
+
this.path = path18;
|
|
14170
|
+
this.bytes = bytes;
|
|
14171
|
+
this.maxBytes = maxBytes;
|
|
14172
|
+
this.name = "OversizedFileError";
|
|
14173
|
+
}
|
|
14174
|
+
};
|
|
14175
|
+
function runGit(args2, cwd) {
|
|
14176
|
+
return new Promise((resolve8) => {
|
|
14177
|
+
childProcess3.execFile("git", args2, { cwd, maxBuffer: MAX_GIT_BUFFER, encoding: "buffer" }, (error, stdout, stderr) => {
|
|
14178
|
+
const err2 = error;
|
|
14179
|
+
const exitCode = err2 && typeof err2.code === "number" ? err2.code : err2 ? 1 : 0;
|
|
14180
|
+
resolve8({
|
|
14181
|
+
stdout: stdout ?? Buffer.alloc(0),
|
|
14182
|
+
stderr: (stderr ?? Buffer.alloc(0)).toString("utf8"),
|
|
14183
|
+
exitCode
|
|
14184
|
+
});
|
|
14185
|
+
});
|
|
14186
|
+
});
|
|
14187
|
+
}
|
|
14188
|
+
async function gitText(args2, cwd) {
|
|
14189
|
+
const r = await runGit(args2, cwd);
|
|
14190
|
+
if (r.exitCode !== 0) {
|
|
14191
|
+
throw new Error(`git ${args2.join(" ")} failed: ${r.stderr.trim()}`);
|
|
14192
|
+
}
|
|
14193
|
+
return r.stdout.toString("utf8").trim();
|
|
14194
|
+
}
|
|
14195
|
+
async function resolveRepoNameWithOwner(ctx) {
|
|
14196
|
+
const url = await gitText(["remote", "get-url", "origin"], ctx.cwd);
|
|
14197
|
+
const parsed = parseGithubUrl(url);
|
|
14198
|
+
if (!parsed) {
|
|
14199
|
+
throw new Error(`Could not parse owner/repo from origin remote: ${url}`);
|
|
14200
|
+
}
|
|
14201
|
+
return `${parsed.owner}/${parsed.repo}`;
|
|
14202
|
+
}
|
|
14203
|
+
async function resolveBaseBranch(ctx) {
|
|
14204
|
+
if (ctx.baseBranch)
|
|
14205
|
+
return ctx.baseBranch;
|
|
14206
|
+
const r = await runGit(["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], ctx.cwd);
|
|
14207
|
+
if (r.exitCode !== 0)
|
|
14208
|
+
return null;
|
|
14209
|
+
return r.stdout.toString("utf8").trim().replace(/^origin\//, "") || null;
|
|
14210
|
+
}
|
|
14211
|
+
async function resolveBranchName(ctx, input) {
|
|
14212
|
+
const branch = input.branch ? input.branch.replace(/^refs\/heads\//, "") : await resolveCurrentBranch(ctx);
|
|
14213
|
+
const baseBranch = await resolveBaseBranch(ctx);
|
|
14214
|
+
if (baseBranch && branch === baseBranch) {
|
|
14215
|
+
throw new Error(`Refusing to commit directly to base branch '${baseBranch}'. Pass a 'branch' name prefixed with posthog-code/.`);
|
|
14216
|
+
}
|
|
14217
|
+
return branch;
|
|
14218
|
+
}
|
|
14219
|
+
async function resolveCurrentBranch(ctx) {
|
|
14220
|
+
const current2 = await gitText(["rev-parse", "--abbrev-ref", "HEAD"], ctx.cwd);
|
|
14221
|
+
if (!current2 || current2 === "HEAD") {
|
|
14222
|
+
throw new Error("Detached HEAD \u2014 pass a `branch` to git_signed_commit (e.g. posthog-code/...).");
|
|
14223
|
+
}
|
|
14224
|
+
return current2;
|
|
14225
|
+
}
|
|
14226
|
+
async function remoteTip(ctx, branch) {
|
|
14227
|
+
const out2 = await gitText(["ls-remote", "--heads", "origin", branch], ctx.cwd);
|
|
14228
|
+
if (!out2)
|
|
14229
|
+
return null;
|
|
14230
|
+
return out2.split(" ")[0]?.trim() || null;
|
|
14231
|
+
}
|
|
14232
|
+
async function createRef(ctx, repo, branch, sha) {
|
|
14233
|
+
const res = await execGh([
|
|
14234
|
+
"api",
|
|
14235
|
+
"-X",
|
|
14236
|
+
"POST",
|
|
14237
|
+
`/repos/${repo}/git/refs`,
|
|
14238
|
+
"-f",
|
|
14239
|
+
`ref=refs/heads/${branch}`,
|
|
14240
|
+
"-f",
|
|
14241
|
+
`sha=${sha}`
|
|
14242
|
+
], { cwd: ctx.cwd, env: ghTokenEnv(ctx.token) });
|
|
14243
|
+
if (res.exitCode !== 0) {
|
|
14244
|
+
throw new Error(`Failed to create branch '${branch}': ${res.stderr || res.error}`);
|
|
14245
|
+
}
|
|
14246
|
+
}
|
|
14247
|
+
var GITHUB_TOKEN_ENV_VARS = ["GH_TOKEN", "GITHUB_TOKEN"];
|
|
14248
|
+
function readGithubTokenFromEnv(env = process.env) {
|
|
14249
|
+
for (const name2 of GITHUB_TOKEN_ENV_VARS) {
|
|
14250
|
+
if (env[name2])
|
|
14251
|
+
return env[name2];
|
|
14252
|
+
}
|
|
14253
|
+
return void 0;
|
|
14254
|
+
}
|
|
14255
|
+
function ghTokenEnv(token) {
|
|
14256
|
+
return Object.fromEntries(GITHUB_TOKEN_ENV_VARS.map((name2) => [name2, token]));
|
|
14257
|
+
}
|
|
14258
|
+
var STAGED_READ_CONCURRENCY = 16;
|
|
14259
|
+
async function buildFileChanges(ctx, baseOid) {
|
|
14260
|
+
const diff = await runGit(["diff", "--cached", "-z", "--no-renames", "--name-status", baseOid], ctx.cwd);
|
|
14261
|
+
if (diff.exitCode !== 0) {
|
|
14262
|
+
throw new Error(`git diff --cached failed: ${diff.stderr.trim()}`);
|
|
14263
|
+
}
|
|
14264
|
+
const tokens = diff.stdout.toString("utf8").split("\0").filter(Boolean);
|
|
14265
|
+
const addPaths = [];
|
|
14266
|
+
const deletions = [];
|
|
14267
|
+
for (let i2 = 0; i2 + 1 < tokens.length; i2 += 2) {
|
|
14268
|
+
const path18 = tokens[i2 + 1];
|
|
14269
|
+
if (tokens[i2].startsWith("D")) {
|
|
14270
|
+
deletions.push({ path: path18 });
|
|
14271
|
+
} else {
|
|
14272
|
+
addPaths.push(path18);
|
|
14273
|
+
}
|
|
14274
|
+
}
|
|
14275
|
+
const additions = await mapWithConcurrency(addPaths, STAGED_READ_CONCURRENCY, async (path18) => {
|
|
14276
|
+
const r = await runGit(["show", `:${path18}`], ctx.cwd);
|
|
14277
|
+
if (r.exitCode !== 0) {
|
|
14278
|
+
throw new Error(`Failed to read staged file '${path18}': ${r.stderr.trim()}`);
|
|
14279
|
+
}
|
|
14280
|
+
return { path: path18, contents: r.stdout.toString("base64") };
|
|
14281
|
+
});
|
|
14282
|
+
return { additions, deletions };
|
|
14283
|
+
}
|
|
14284
|
+
function additionBytes(a) {
|
|
14285
|
+
return a.contents.length + a.path.length + 32;
|
|
14286
|
+
}
|
|
14287
|
+
function chunkFileChanges(changes, maxBytes) {
|
|
14288
|
+
for (const a of changes.additions) {
|
|
14289
|
+
const bytes = additionBytes(a);
|
|
14290
|
+
if (bytes > maxBytes)
|
|
14291
|
+
throw new OversizedFileError(a.path, bytes, maxBytes);
|
|
14292
|
+
}
|
|
14293
|
+
if (changes.additions.length === 0) {
|
|
14294
|
+
return [{ additions: [], deletions: changes.deletions }];
|
|
14295
|
+
}
|
|
14296
|
+
const chunks = [];
|
|
14297
|
+
let cur = { additions: [], deletions: [...changes.deletions] };
|
|
14298
|
+
let curBytes = changes.deletions.reduce((n, d) => n + d.path.length + 16, 0);
|
|
14299
|
+
for (const a of changes.additions) {
|
|
14300
|
+
const bytes = additionBytes(a);
|
|
14301
|
+
if (cur.additions.length > 0 && curBytes + bytes > maxBytes) {
|
|
14302
|
+
chunks.push(cur);
|
|
14303
|
+
cur = { additions: [], deletions: [] };
|
|
14304
|
+
curBytes = 0;
|
|
14305
|
+
}
|
|
14306
|
+
cur.additions.push(a);
|
|
14307
|
+
curBytes += bytes;
|
|
14308
|
+
}
|
|
14309
|
+
chunks.push(cur);
|
|
14310
|
+
return chunks;
|
|
14311
|
+
}
|
|
14312
|
+
var CREATE_COMMIT_MUTATION = `mutation($input: CreateCommitOnBranchInput!) {
|
|
14313
|
+
createCommitOnBranch(input: $input) { commit { oid url } }
|
|
14314
|
+
}`;
|
|
14315
|
+
async function createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, changes) {
|
|
14316
|
+
const payload = JSON.stringify({
|
|
14317
|
+
query: CREATE_COMMIT_MUTATION,
|
|
14318
|
+
variables: {
|
|
14319
|
+
input: {
|
|
14320
|
+
branch: { repositoryNameWithOwner: repo, branchName: branch },
|
|
14321
|
+
expectedHeadOid,
|
|
14322
|
+
message: { headline, body: body2 },
|
|
14323
|
+
fileChanges: changes
|
|
14324
|
+
}
|
|
14325
|
+
}
|
|
14326
|
+
});
|
|
14327
|
+
const res = await execGhWithRetry(["api", "graphql", "--input", "-"], {
|
|
14328
|
+
cwd: ctx.cwd,
|
|
14329
|
+
input: payload,
|
|
14330
|
+
env: ghTokenEnv(ctx.token),
|
|
14331
|
+
// Bound each attempt so a stalled connection can't hang the tool forever.
|
|
14332
|
+
timeoutMs: GH_GRAPHQL_TIMEOUT_MS
|
|
14333
|
+
}, { maxAttempts: 3 });
|
|
14334
|
+
if (res.exitCode !== 0) {
|
|
14335
|
+
throw new Error(`createCommitOnBranch failed: ${res.stderr || res.error || res.stdout}`);
|
|
14336
|
+
}
|
|
14337
|
+
let parsed;
|
|
14338
|
+
try {
|
|
14339
|
+
parsed = JSON.parse(res.stdout);
|
|
14340
|
+
} catch {
|
|
14341
|
+
throw new Error(`createCommitOnBranch returned non-JSON: ${res.stdout.slice(0, 500)}`);
|
|
14342
|
+
}
|
|
14343
|
+
if (parsed.errors) {
|
|
14344
|
+
throw new Error(`createCommitOnBranch errors: ${JSON.stringify(parsed.errors)}`);
|
|
14345
|
+
}
|
|
14346
|
+
const commit = parsed.data?.createCommitOnBranch?.commit;
|
|
14347
|
+
if (!commit?.oid) {
|
|
14348
|
+
throw new Error(`createCommitOnBranch returned no commit: ${res.stdout}`);
|
|
14349
|
+
}
|
|
14350
|
+
return commit;
|
|
14351
|
+
}
|
|
14352
|
+
async function syncLocalCheckout(ctx, branch, newOid) {
|
|
14353
|
+
const steps = [
|
|
14354
|
+
["fetch", ["fetch", "--no-tags", "origin", branch]],
|
|
14355
|
+
["update-ref", ["update-ref", `refs/heads/${branch}`, newOid]],
|
|
14356
|
+
["symbolic-ref", ["symbolic-ref", "HEAD", `refs/heads/${branch}`]],
|
|
14357
|
+
["reset", ["reset", "-q"]]
|
|
14358
|
+
];
|
|
14359
|
+
for (const [label, args2] of steps) {
|
|
14360
|
+
const r = await runGit(args2, ctx.cwd);
|
|
14361
|
+
if (r.exitCode !== 0) {
|
|
14362
|
+
process.stderr.write(`[signed-commit] local sync step '${label}' failed after committing ${newOid}: ${r.stderr.trim()}
|
|
14363
|
+
`);
|
|
14364
|
+
}
|
|
14365
|
+
}
|
|
14366
|
+
}
|
|
14367
|
+
async function createSignedCommit(ctx, input) {
|
|
14368
|
+
const [repo, branch] = await Promise.all([
|
|
14369
|
+
resolveRepoNameWithOwner(ctx),
|
|
14370
|
+
resolveBranchName(ctx, input)
|
|
14371
|
+
]);
|
|
14372
|
+
if (input.paths && input.paths.length > 0) {
|
|
14373
|
+
const r = await runGit(["add", "--", ...input.paths], ctx.cwd);
|
|
14374
|
+
if (r.exitCode !== 0) {
|
|
14375
|
+
throw new Error(`git add failed: ${r.stderr.trim()}`);
|
|
14376
|
+
}
|
|
14377
|
+
}
|
|
14378
|
+
let tip = await remoteTip(ctx, branch);
|
|
14379
|
+
if (tip === null) {
|
|
14380
|
+
const baseSha = await gitText(["rev-parse", "HEAD"], ctx.cwd);
|
|
14381
|
+
await createRef(ctx, repo, branch, baseSha);
|
|
14382
|
+
tip = baseSha;
|
|
14383
|
+
} else {
|
|
14384
|
+
await runGit(["fetch", "--no-tags", "origin", branch], ctx.cwd);
|
|
14385
|
+
}
|
|
14386
|
+
const changes = await buildFileChanges(ctx, tip);
|
|
14387
|
+
if (changes.additions.length === 0 && changes.deletions.length === 0) {
|
|
14388
|
+
throw new Error("No staged changes to commit. Stage files with `git add` first (or pass `paths`).");
|
|
14389
|
+
}
|
|
14390
|
+
const chunks = chunkFileChanges(changes, DEFAULT_MAX_PAYLOAD_BYTES);
|
|
14391
|
+
const body2 = [input.body, buildPostHogTrailers(ctx.taskId).join("\n")].filter(Boolean).join("\n\n");
|
|
14392
|
+
const commits = [];
|
|
14393
|
+
let expectedHeadOid = tip;
|
|
14394
|
+
for (let i2 = 0; i2 < chunks.length; i2++) {
|
|
14395
|
+
const headline = chunks.length > 1 ? `${input.message} \u2014 part ${i2 + 1}/${chunks.length}` : input.message;
|
|
14396
|
+
const commit = await createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, chunks[i2]);
|
|
14397
|
+
commits.push({ sha: commit.oid, url: commit.url });
|
|
14398
|
+
expectedHeadOid = commit.oid;
|
|
14399
|
+
}
|
|
14400
|
+
await syncLocalCheckout(ctx, branch, expectedHeadOid);
|
|
14401
|
+
return { branch, commits };
|
|
14402
|
+
}
|
|
14403
|
+
|
|
13392
14404
|
// src/utils/common.ts
|
|
13393
14405
|
async function withTimeout(operation, timeoutMs) {
|
|
13394
14406
|
const timeoutPromise = new Promise(
|
|
13395
|
-
(
|
|
14407
|
+
(resolve8) => setTimeout(() => resolve8({ result: "timeout" }), timeoutMs)
|
|
13396
14408
|
);
|
|
13397
14409
|
const operationPromise = operation.then((value) => ({
|
|
13398
14410
|
result: "success",
|
|
@@ -13402,6 +14414,12 @@ async function withTimeout(operation, timeoutMs) {
|
|
|
13402
14414
|
}
|
|
13403
14415
|
var IS_ROOT = typeof process !== "undefined" && (process.geteuid?.() ?? process.getuid?.()) === 0;
|
|
13404
14416
|
var ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
|
|
14417
|
+
function isCloudRun(meta) {
|
|
14418
|
+
return !!process.env.IS_SANDBOX || !!meta?.taskRunId;
|
|
14419
|
+
}
|
|
14420
|
+
function resolveGithubToken() {
|
|
14421
|
+
return readGithubTokenFromEnv();
|
|
14422
|
+
}
|
|
13405
14423
|
function unreachable(value, logger) {
|
|
13406
14424
|
let valueAsString;
|
|
13407
14425
|
try {
|
|
@@ -13559,8 +14577,82 @@ var BaseAcpAgent = class {
|
|
|
13559
14577
|
}
|
|
13560
14578
|
};
|
|
13561
14579
|
|
|
14580
|
+
// src/adapters/signed-commit-shared.ts
|
|
14581
|
+
var import_zod = require("zod");
|
|
14582
|
+
|
|
14583
|
+
// src/adapters/local-tools/registry.ts
|
|
14584
|
+
var LOCAL_TOOLS_MCP_NAME = "posthog-local";
|
|
14585
|
+
function defineLocalTool(def) {
|
|
14586
|
+
return def;
|
|
14587
|
+
}
|
|
14588
|
+
function qualifiedLocalToolName(toolName) {
|
|
14589
|
+
return `mcp__${LOCAL_TOOLS_MCP_NAME}__${toolName}`;
|
|
14590
|
+
}
|
|
14591
|
+
|
|
14592
|
+
// src/adapters/signed-commit-shared.ts
|
|
14593
|
+
var SIGNED_COMMIT_TOOL_NAME = "git_signed_commit";
|
|
14594
|
+
var SIGNED_COMMIT_QUALIFIED_TOOL_NAME = qualifiedLocalToolName(
|
|
14595
|
+
SIGNED_COMMIT_TOOL_NAME
|
|
14596
|
+
);
|
|
14597
|
+
var SIGNED_COMMIT_TOOL_DESCRIPTION = "Create a GitHub-signed (Verified) commit on the branch. Stage files with `git add` first (or pass `paths`), then call this instead of `git commit`/`git push` \u2014 those are blocked because all commits must be signed. The commit is created via GitHub's API and your local checkout is kept in sync. For a new branch, pass `branch` (prefixed with `posthog-code/`) and the tool creates it on the remote.";
|
|
14598
|
+
var signedCommitToolSchema = {
|
|
14599
|
+
message: import_zod.z.string().describe("Commit headline (first line)."),
|
|
14600
|
+
body: import_zod.z.string().optional().describe("Optional extended commit body."),
|
|
14601
|
+
branch: import_zod.z.string().optional().describe(
|
|
14602
|
+
"Target branch; defaults to the current branch. Use a posthog-code/ prefix for new branches."
|
|
14603
|
+
),
|
|
14604
|
+
paths: import_zod.z.array(import_zod.z.string()).optional().describe(
|
|
14605
|
+
"Files to stage before committing; defaults to already-staged files."
|
|
14606
|
+
)
|
|
14607
|
+
};
|
|
14608
|
+
function formatSignedCommitResult(result) {
|
|
14609
|
+
const list = result.commits.map((c) => `- ${c.sha} ${c.url}`).join("\n");
|
|
14610
|
+
return `Created ${result.commits.length} signed commit(s) on ${result.branch}:
|
|
14611
|
+
${list}`;
|
|
14612
|
+
}
|
|
14613
|
+
async function runSignedCommitTool(ctx, args2) {
|
|
14614
|
+
try {
|
|
14615
|
+
const result = await createSignedCommit(ctx, args2);
|
|
14616
|
+
return {
|
|
14617
|
+
content: [{ type: "text", text: formatSignedCommitResult(result) }]
|
|
14618
|
+
};
|
|
14619
|
+
} catch (err2) {
|
|
14620
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
14621
|
+
return {
|
|
14622
|
+
content: [
|
|
14623
|
+
{ type: "text", text: `${SIGNED_COMMIT_TOOL_NAME} failed: ${message}` }
|
|
14624
|
+
],
|
|
14625
|
+
isError: true
|
|
14626
|
+
};
|
|
14627
|
+
}
|
|
14628
|
+
}
|
|
14629
|
+
|
|
14630
|
+
// src/adapters/local-tools/tools/signed-commit.ts
|
|
14631
|
+
var signedCommitTool = defineLocalTool({
|
|
14632
|
+
name: SIGNED_COMMIT_TOOL_NAME,
|
|
14633
|
+
description: SIGNED_COMMIT_TOOL_DESCRIPTION,
|
|
14634
|
+
schema: signedCommitToolSchema,
|
|
14635
|
+
alwaysLoad: true,
|
|
14636
|
+
isEnabled: (ctx, meta) => isCloudRun(meta) && !!ctx.token,
|
|
14637
|
+
handler: (ctx, args2) => runSignedCommitTool(
|
|
14638
|
+
{ cwd: ctx.cwd, token: ctx.token ?? "", taskId: ctx.taskId },
|
|
14639
|
+
args2
|
|
14640
|
+
)
|
|
14641
|
+
});
|
|
14642
|
+
|
|
14643
|
+
// src/adapters/local-tools/index.ts
|
|
14644
|
+
var LOCAL_TOOLS = [signedCommitTool];
|
|
14645
|
+
function enabledLocalTools(ctx, meta) {
|
|
14646
|
+
return LOCAL_TOOLS.filter((t) => t.isEnabled(ctx, meta));
|
|
14647
|
+
}
|
|
14648
|
+
|
|
14649
|
+
// src/adapters/session-meta.ts
|
|
14650
|
+
function resolveTaskId(meta) {
|
|
14651
|
+
return meta?.taskId ?? meta?.persistence?.taskId;
|
|
14652
|
+
}
|
|
14653
|
+
|
|
13562
14654
|
// src/adapters/claude/conversion/acp-to-sdk.ts
|
|
13563
|
-
var
|
|
14655
|
+
var path6 = __toESM(require("path"), 1);
|
|
13564
14656
|
var import_node_url = require("url");
|
|
13565
14657
|
var PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
|
|
13566
14658
|
var COMMON_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -13590,7 +14682,7 @@ function sdkText(value) {
|
|
|
13590
14682
|
function formatUriAsLink(uri) {
|
|
13591
14683
|
try {
|
|
13592
14684
|
if (uri.startsWith("zed://")) {
|
|
13593
|
-
const name2 =
|
|
14685
|
+
const name2 = path6.basename(uri) || uri;
|
|
13594
14686
|
return `[@${name2}](${uri})`;
|
|
13595
14687
|
}
|
|
13596
14688
|
return uri;
|
|
@@ -13599,7 +14691,7 @@ function formatUriAsLink(uri) {
|
|
|
13599
14691
|
}
|
|
13600
14692
|
}
|
|
13601
14693
|
function readToolGuidanceForPath(filePath) {
|
|
13602
|
-
const ext =
|
|
14694
|
+
const ext = path6.extname(filePath).slice(1).toLowerCase();
|
|
13603
14695
|
if (PDF_EXTENSIONS.has(ext)) {
|
|
13604
14696
|
return 'Optional `pages` string (e.g. "1-5") per Read call instead of loading the entire PDF.';
|
|
13605
14697
|
}
|
|
@@ -13611,7 +14703,7 @@ function readToolGuidanceForPath(filePath) {
|
|
|
13611
14703
|
function workspacePromptFromFileUri(uri) {
|
|
13612
14704
|
try {
|
|
13613
14705
|
const filePath = (0, import_node_url.fileURLToPath)(uri);
|
|
13614
|
-
const name2 =
|
|
14706
|
+
const name2 = path6.basename(filePath) || filePath;
|
|
13615
14707
|
return [
|
|
13616
14708
|
"Attached workspace file \u2014 use Read with required `file_path`:",
|
|
13617
14709
|
`- file_path: ${filePath}`,
|
|
@@ -13737,8 +14829,8 @@ var ToolContentBuilder = class {
|
|
|
13737
14829
|
this.items.push({ type: "content", content: image(data, mimeType, uri) });
|
|
13738
14830
|
return this;
|
|
13739
14831
|
}
|
|
13740
|
-
diff(
|
|
13741
|
-
this.items.push({ type: "diff", path:
|
|
14832
|
+
diff(path18, oldText, newText) {
|
|
14833
|
+
this.items.push({ type: "diff", path: path18, oldText, newText });
|
|
13742
14834
|
return this;
|
|
13743
14835
|
}
|
|
13744
14836
|
build() {
|
|
@@ -13957,6 +15049,60 @@ var createSubagentRewriteHook = (logger, registeredAgents) => async (input, _too
|
|
|
13957
15049
|
}
|
|
13958
15050
|
};
|
|
13959
15051
|
};
|
|
15052
|
+
var GIT_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
15053
|
+
"-C",
|
|
15054
|
+
"-c",
|
|
15055
|
+
"--git-dir",
|
|
15056
|
+
"--work-tree",
|
|
15057
|
+
"--namespace",
|
|
15058
|
+
"--exec-path"
|
|
15059
|
+
]);
|
|
15060
|
+
function gitSubcommand(segment) {
|
|
15061
|
+
const tokens = segment.trim().split(/\s+/).filter(Boolean);
|
|
15062
|
+
if (tokens.length === 0) return null;
|
|
15063
|
+
const head = tokens[0].split("/").pop();
|
|
15064
|
+
if (head !== "git") return null;
|
|
15065
|
+
let skipNext = false;
|
|
15066
|
+
for (const tok of tokens.slice(1)) {
|
|
15067
|
+
if (skipNext) {
|
|
15068
|
+
skipNext = false;
|
|
15069
|
+
continue;
|
|
15070
|
+
}
|
|
15071
|
+
if (GIT_VALUE_FLAGS.has(tok)) {
|
|
15072
|
+
skipNext = true;
|
|
15073
|
+
continue;
|
|
15074
|
+
}
|
|
15075
|
+
if (tok.startsWith("-")) continue;
|
|
15076
|
+
return tok;
|
|
15077
|
+
}
|
|
15078
|
+
return null;
|
|
15079
|
+
}
|
|
15080
|
+
function blocksUnsignedGit(command) {
|
|
15081
|
+
if (!command.includes("git")) return false;
|
|
15082
|
+
return command.split(/&&|\|\||[;\n|]/).some((segment) => {
|
|
15083
|
+
const sub = gitSubcommand(segment);
|
|
15084
|
+
return sub === "commit" || sub === "push";
|
|
15085
|
+
});
|
|
15086
|
+
}
|
|
15087
|
+
var createSignedCommitGuardHook = (logger) => async (input, _toolUseID) => {
|
|
15088
|
+
if (input.hook_event_name !== "PreToolUse") return { continue: true };
|
|
15089
|
+
if (input.tool_name !== "Bash") return { continue: true };
|
|
15090
|
+
const command = input.tool_input?.command;
|
|
15091
|
+
if (!command || !blocksUnsignedGit(command)) {
|
|
15092
|
+
return { continue: true };
|
|
15093
|
+
}
|
|
15094
|
+
logger.info(
|
|
15095
|
+
`[SignedCommitGuard] Blocking unsigned git command: ${command}`
|
|
15096
|
+
);
|
|
15097
|
+
return {
|
|
15098
|
+
continue: true,
|
|
15099
|
+
hookSpecificOutput: {
|
|
15100
|
+
hookEventName: "PreToolUse",
|
|
15101
|
+
permissionDecision: "deny",
|
|
15102
|
+
permissionDecisionReason: `Commits must be signed: \`git commit\` and \`git push\` are disabled here. Stage changes with \`git add\`, then call the \`git_signed_commit\` tool (${SIGNED_COMMIT_QUALIFIED_TOOL_NAME}) with a \`message\` to create a signed commit on the branch.`
|
|
15103
|
+
}
|
|
15104
|
+
};
|
|
15105
|
+
};
|
|
13960
15106
|
var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID) => {
|
|
13961
15107
|
if (input.hook_event_name !== "PreToolUse") {
|
|
13962
15108
|
return { continue: true };
|
|
@@ -14021,7 +15167,7 @@ function buildToolKey(serverName, toolName) {
|
|
|
14021
15167
|
return `mcp__${serverName}__${toolName}`;
|
|
14022
15168
|
}
|
|
14023
15169
|
function delay2(ms) {
|
|
14024
|
-
return new Promise((
|
|
15170
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
14025
15171
|
}
|
|
14026
15172
|
async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
|
|
14027
15173
|
let retries = 0;
|
|
@@ -14041,14 +15187,14 @@ async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefi
|
|
|
14041
15187
|
continue;
|
|
14042
15188
|
}
|
|
14043
15189
|
let readOnlyCount = 0;
|
|
14044
|
-
for (const
|
|
14045
|
-
const toolKey = buildToolKey(server.name,
|
|
14046
|
-
const readOnly =
|
|
15190
|
+
for (const tool2 of server.tools) {
|
|
15191
|
+
const toolKey = buildToolKey(server.name, tool2.name);
|
|
15192
|
+
const readOnly = tool2.annotations?.readOnly === true;
|
|
14047
15193
|
const existing = mcpToolMetadataCache.get(toolKey);
|
|
14048
15194
|
mcpToolMetadataCache.set(toolKey, {
|
|
14049
15195
|
readOnly,
|
|
14050
|
-
name:
|
|
14051
|
-
description:
|
|
15196
|
+
name: tool2.name,
|
|
15197
|
+
description: tool2.description,
|
|
14052
15198
|
approvalState: existing?.approvalState
|
|
14053
15199
|
});
|
|
14054
15200
|
if (readOnly) readOnlyCount++;
|
|
@@ -15311,20 +16457,42 @@ async function handleUserAssistantMessage(message, context) {
|
|
|
15311
16457
|
return {};
|
|
15312
16458
|
}
|
|
15313
16459
|
|
|
16460
|
+
// src/adapters/claude/mcp/local-tools.ts
|
|
16461
|
+
var import_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
|
|
16462
|
+
function createLocalToolsMcpServer(ctx, meta) {
|
|
16463
|
+
const tools = enabledLocalTools(ctx, meta);
|
|
16464
|
+
if (tools.length === 0) {
|
|
16465
|
+
return void 0;
|
|
16466
|
+
}
|
|
16467
|
+
return (0, import_claude_agent_sdk.createSdkMcpServer)({
|
|
16468
|
+
name: LOCAL_TOOLS_MCP_NAME,
|
|
16469
|
+
version: "1.0.0",
|
|
16470
|
+
tools: tools.map(
|
|
16471
|
+
(t) => (0, import_claude_agent_sdk.tool)(
|
|
16472
|
+
t.name,
|
|
16473
|
+
t.description,
|
|
16474
|
+
t.schema,
|
|
16475
|
+
async (args2) => t.handler(ctx, args2),
|
|
16476
|
+
{ alwaysLoad: t.alwaysLoad ?? false }
|
|
16477
|
+
)
|
|
16478
|
+
)
|
|
16479
|
+
});
|
|
16480
|
+
}
|
|
16481
|
+
|
|
15314
16482
|
// src/adapters/claude/plan/utils.ts
|
|
15315
|
-
var
|
|
15316
|
-
var
|
|
16483
|
+
var os2 = __toESM(require("os"), 1);
|
|
16484
|
+
var path8 = __toESM(require("path"), 1);
|
|
15317
16485
|
function getClaudeConfigDir() {
|
|
15318
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
16486
|
+
return process.env.CLAUDE_CONFIG_DIR || path8.join(os2.homedir(), ".claude");
|
|
15319
16487
|
}
|
|
15320
16488
|
function getClaudePlansDir() {
|
|
15321
|
-
return
|
|
16489
|
+
return path8.join(getClaudeConfigDir(), "plans");
|
|
15322
16490
|
}
|
|
15323
16491
|
function isClaudePlanFilePath(filePath) {
|
|
15324
16492
|
if (!filePath) return false;
|
|
15325
|
-
const resolved =
|
|
15326
|
-
const plansDir =
|
|
15327
|
-
return resolved === plansDir || resolved.startsWith(plansDir +
|
|
16493
|
+
const resolved = path8.resolve(filePath);
|
|
16494
|
+
const plansDir = path8.resolve(getClaudePlansDir());
|
|
16495
|
+
return resolved === plansDir || resolved.startsWith(plansDir + path8.sep);
|
|
15328
16496
|
}
|
|
15329
16497
|
function isPlanReady(plan) {
|
|
15330
16498
|
if (!plan) return false;
|
|
@@ -15355,21 +16523,21 @@ function getLatestAssistantText(notifications) {
|
|
|
15355
16523
|
}
|
|
15356
16524
|
|
|
15357
16525
|
// src/adapters/claude/questions/utils.ts
|
|
15358
|
-
var
|
|
16526
|
+
var import_zod2 = require("zod");
|
|
15359
16527
|
var OPTION_PREFIX = "option_";
|
|
15360
|
-
var QuestionOptionSchema =
|
|
15361
|
-
label:
|
|
15362
|
-
description:
|
|
16528
|
+
var QuestionOptionSchema = import_zod2.z.object({
|
|
16529
|
+
label: import_zod2.z.string(),
|
|
16530
|
+
description: import_zod2.z.string().optional()
|
|
15363
16531
|
});
|
|
15364
|
-
var QuestionItemSchema =
|
|
15365
|
-
question:
|
|
15366
|
-
header:
|
|
15367
|
-
options:
|
|
15368
|
-
multiSelect:
|
|
15369
|
-
completed:
|
|
16532
|
+
var QuestionItemSchema = import_zod2.z.object({
|
|
16533
|
+
question: import_zod2.z.string(),
|
|
16534
|
+
header: import_zod2.z.string().optional(),
|
|
16535
|
+
options: import_zod2.z.array(QuestionOptionSchema),
|
|
16536
|
+
multiSelect: import_zod2.z.boolean().optional(),
|
|
16537
|
+
completed: import_zod2.z.boolean().optional()
|
|
15370
16538
|
});
|
|
15371
|
-
var QuestionMetaSchema =
|
|
15372
|
-
questions:
|
|
16539
|
+
var QuestionMetaSchema = import_zod2.z.object({
|
|
16540
|
+
questions: import_zod2.z.array(QuestionItemSchema)
|
|
15373
16541
|
});
|
|
15374
16542
|
function normalizeAskUserQuestionInput(input) {
|
|
15375
16543
|
if (input.questions && input.questions.length > 0) {
|
|
@@ -16141,14 +17309,14 @@ function getAvailableSlashCommands(commands) {
|
|
|
16141
17309
|
}
|
|
16142
17310
|
|
|
16143
17311
|
// src/adapters/claude/session/mcp-config.ts
|
|
16144
|
-
var
|
|
16145
|
-
var
|
|
16146
|
-
var
|
|
16147
|
-
function loadUserClaudeJsonMcpServers(cwd, logger, homeDir =
|
|
16148
|
-
const claudeJsonPath =
|
|
17312
|
+
var fs7 = __toESM(require("fs"), 1);
|
|
17313
|
+
var os3 = __toESM(require("os"), 1);
|
|
17314
|
+
var path9 = __toESM(require("path"), 1);
|
|
17315
|
+
function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os3.homedir()) {
|
|
17316
|
+
const claudeJsonPath = path9.join(homeDir, ".claude.json");
|
|
16149
17317
|
let raw;
|
|
16150
17318
|
try {
|
|
16151
|
-
raw =
|
|
17319
|
+
raw = fs7.readFileSync(claudeJsonPath, "utf8");
|
|
16152
17320
|
} catch {
|
|
16153
17321
|
return {};
|
|
16154
17322
|
}
|
|
@@ -16192,9 +17360,9 @@ function parseMcpServers(params) {
|
|
|
16192
17360
|
|
|
16193
17361
|
// src/adapters/claude/session/options.ts
|
|
16194
17362
|
var import_node_child_process3 = require("child_process");
|
|
16195
|
-
var
|
|
16196
|
-
var
|
|
16197
|
-
var
|
|
17363
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
17364
|
+
var os4 = __toESM(require("os"), 1);
|
|
17365
|
+
var path10 = __toESM(require("path"), 1);
|
|
16198
17366
|
|
|
16199
17367
|
// src/adapters/claude/session/instructions.ts
|
|
16200
17368
|
var BRANCH_NAMING = `
|
|
@@ -16269,28 +17437,27 @@ ${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
|
16269
17437
|
ANTHROPIC_CUSTOM_HEADERS: customHeaders
|
|
16270
17438
|
};
|
|
16271
17439
|
}
|
|
16272
|
-
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents) {
|
|
17440
|
+
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode) {
|
|
16273
17441
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange })];
|
|
16274
17442
|
if (enrichmentDeps && enrichedReadCache) {
|
|
16275
17443
|
postToolUseHooks.push(
|
|
16276
17444
|
createReadEnrichmentHook(enrichmentDeps, enrichedReadCache)
|
|
16277
17445
|
);
|
|
16278
17446
|
}
|
|
17447
|
+
const preToolUseHooks = [
|
|
17448
|
+
createPreToolUseHook(settingsManager, logger),
|
|
17449
|
+
createSubagentRewriteHook(logger, registeredAgents)
|
|
17450
|
+
];
|
|
17451
|
+
if (cloudMode) {
|
|
17452
|
+
preToolUseHooks.push(createSignedCommitGuardHook(logger));
|
|
17453
|
+
}
|
|
16279
17454
|
return {
|
|
16280
17455
|
...userHooks,
|
|
16281
17456
|
PostToolUse: [
|
|
16282
17457
|
...userHooks?.PostToolUse || [],
|
|
16283
17458
|
{ hooks: postToolUseHooks }
|
|
16284
17459
|
],
|
|
16285
|
-
PreToolUse: [
|
|
16286
|
-
...userHooks?.PreToolUse || [],
|
|
16287
|
-
{
|
|
16288
|
-
hooks: [
|
|
16289
|
-
createPreToolUseHook(settingsManager, logger),
|
|
16290
|
-
createSubagentRewriteHook(logger, registeredAgents)
|
|
16291
|
-
]
|
|
16292
|
-
}
|
|
16293
|
-
]
|
|
17460
|
+
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }]
|
|
16294
17461
|
};
|
|
16295
17462
|
}
|
|
16296
17463
|
var PH_EXPLORE_AGENT = {
|
|
@@ -16402,12 +17569,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
|
|
|
16402
17569
|
};
|
|
16403
17570
|
}
|
|
16404
17571
|
function ensureLocalSettings(cwd) {
|
|
16405
|
-
const claudeDir =
|
|
16406
|
-
const localSettingsPath =
|
|
17572
|
+
const claudeDir = path10.join(cwd, ".claude");
|
|
17573
|
+
const localSettingsPath = path10.join(claudeDir, "settings.local.json");
|
|
16407
17574
|
try {
|
|
16408
|
-
if (!
|
|
16409
|
-
|
|
16410
|
-
|
|
17575
|
+
if (!fs8.existsSync(localSettingsPath)) {
|
|
17576
|
+
fs8.mkdirSync(claudeDir, { recursive: true });
|
|
17577
|
+
fs8.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
|
|
16411
17578
|
}
|
|
16412
17579
|
} catch {
|
|
16413
17580
|
}
|
|
@@ -16448,7 +17615,8 @@ function buildSessionOptions(params) {
|
|
|
16448
17615
|
params.logger,
|
|
16449
17616
|
params.enrichmentDeps,
|
|
16450
17617
|
params.enrichedReadCache,
|
|
16451
|
-
registeredAgentNames
|
|
17618
|
+
registeredAgentNames,
|
|
17619
|
+
params.cloudMode ?? false
|
|
16452
17620
|
),
|
|
16453
17621
|
outputFormat: params.outputFormat,
|
|
16454
17622
|
abortController: getAbortController(
|
|
@@ -16483,18 +17651,18 @@ function buildSessionOptions(params) {
|
|
|
16483
17651
|
return options;
|
|
16484
17652
|
}
|
|
16485
17653
|
function clearStatsigCache() {
|
|
16486
|
-
const statsigPath =
|
|
16487
|
-
process.env.CLAUDE_CONFIG_DIR ||
|
|
17654
|
+
const statsigPath = path10.join(
|
|
17655
|
+
process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude"),
|
|
16488
17656
|
"statsig"
|
|
16489
17657
|
);
|
|
16490
|
-
|
|
17658
|
+
fs8.rm(statsigPath, { recursive: true, force: true }, () => {
|
|
16491
17659
|
});
|
|
16492
17660
|
}
|
|
16493
17661
|
|
|
16494
17662
|
// src/adapters/claude/session/settings.ts
|
|
16495
|
-
var
|
|
16496
|
-
var
|
|
16497
|
-
var
|
|
17663
|
+
var fs9 = __toESM(require("fs"), 1);
|
|
17664
|
+
var os5 = __toESM(require("os"), 1);
|
|
17665
|
+
var path11 = __toESM(require("path"), 1);
|
|
16498
17666
|
var import_minimatch = require("minimatch");
|
|
16499
17667
|
|
|
16500
17668
|
// src/utils/async-mutex.ts
|
|
@@ -16506,8 +17674,8 @@ var AsyncMutex = class {
|
|
|
16506
17674
|
this.locked = true;
|
|
16507
17675
|
return;
|
|
16508
17676
|
}
|
|
16509
|
-
return new Promise((
|
|
16510
|
-
this.queue.push(
|
|
17677
|
+
return new Promise((resolve8) => {
|
|
17678
|
+
this.queue.push(resolve8);
|
|
16511
17679
|
});
|
|
16512
17680
|
}
|
|
16513
17681
|
release() {
|
|
@@ -16575,13 +17743,13 @@ function parseRule(rule) {
|
|
|
16575
17743
|
function normalizePath(filePath, cwd) {
|
|
16576
17744
|
let resolved = filePath;
|
|
16577
17745
|
if (resolved.startsWith("~/")) {
|
|
16578
|
-
resolved =
|
|
17746
|
+
resolved = path11.join(os5.homedir(), resolved.slice(2));
|
|
16579
17747
|
} else if (resolved.startsWith("./")) {
|
|
16580
|
-
resolved =
|
|
16581
|
-
} else if (!
|
|
16582
|
-
resolved =
|
|
17748
|
+
resolved = path11.join(cwd, resolved.slice(2));
|
|
17749
|
+
} else if (!path11.isAbsolute(resolved)) {
|
|
17750
|
+
resolved = path11.join(cwd, resolved);
|
|
16583
17751
|
}
|
|
16584
|
-
return
|
|
17752
|
+
return path11.normalize(resolved).replace(/\\/g, "/");
|
|
16585
17753
|
}
|
|
16586
17754
|
function matchesGlob(pattern, filePath, cwd) {
|
|
16587
17755
|
const normalizedPattern = normalizePath(pattern, cwd);
|
|
@@ -16628,11 +17796,11 @@ function formatRule(rule) {
|
|
|
16628
17796
|
}
|
|
16629
17797
|
async function writeFileAtomic(filePath, data) {
|
|
16630
17798
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
16631
|
-
await
|
|
17799
|
+
await fs9.promises.writeFile(tmpPath, data);
|
|
16632
17800
|
try {
|
|
16633
|
-
await
|
|
17801
|
+
await fs9.promises.rename(tmpPath, filePath);
|
|
16634
17802
|
} catch (error) {
|
|
16635
|
-
await
|
|
17803
|
+
await fs9.promises.rm(tmpPath, { force: true });
|
|
16636
17804
|
throw error;
|
|
16637
17805
|
}
|
|
16638
17806
|
}
|
|
@@ -16641,7 +17809,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16641
17809
|
return {};
|
|
16642
17810
|
}
|
|
16643
17811
|
try {
|
|
16644
|
-
const content = await
|
|
17812
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
16645
17813
|
return JSON.parse(content);
|
|
16646
17814
|
} catch (error) {
|
|
16647
17815
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16656,7 +17824,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16656
17824
|
}
|
|
16657
17825
|
async function readSettingsFileForUpdate(filePath) {
|
|
16658
17826
|
try {
|
|
16659
|
-
const content = await
|
|
17827
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
16660
17828
|
return JSON.parse(content);
|
|
16661
17829
|
} catch (error) {
|
|
16662
17830
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16702,11 +17870,11 @@ var SettingsManager = class {
|
|
|
16702
17870
|
return this.initPromise;
|
|
16703
17871
|
}
|
|
16704
17872
|
getUserSettingsPath() {
|
|
16705
|
-
const configDir = process.env.CLAUDE_CONFIG_DIR ||
|
|
16706
|
-
return
|
|
17873
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR || path11.join(os5.homedir(), ".claude");
|
|
17874
|
+
return path11.join(configDir, "settings.json");
|
|
16707
17875
|
}
|
|
16708
17876
|
getProjectSettingsPath() {
|
|
16709
|
-
return
|
|
17877
|
+
return path11.join(this.cwd, ".claude", "settings.json");
|
|
16710
17878
|
}
|
|
16711
17879
|
/**
|
|
16712
17880
|
* Local settings are anchored to the primary worktree so every worktree of
|
|
@@ -16714,7 +17882,7 @@ var SettingsManager = class {
|
|
|
16714
17882
|
* avoids re-prompting for the same permission in every worktree.
|
|
16715
17883
|
*/
|
|
16716
17884
|
getLocalSettingsPath() {
|
|
16717
|
-
return
|
|
17885
|
+
return path11.join(this.repoRoot, ".claude", "settings.local.json");
|
|
16718
17886
|
}
|
|
16719
17887
|
async loadAllSettings() {
|
|
16720
17888
|
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
@@ -16772,8 +17940,8 @@ var SettingsManager = class {
|
|
|
16772
17940
|
merged.model = settings.model;
|
|
16773
17941
|
}
|
|
16774
17942
|
if (settings.posthogApprovedExecTools) {
|
|
16775
|
-
for (const
|
|
16776
|
-
posthogApprovedExecTools.add(
|
|
17943
|
+
for (const tool2 of settings.posthogApprovedExecTools) {
|
|
17944
|
+
posthogApprovedExecTools.add(tool2);
|
|
16777
17945
|
}
|
|
16778
17946
|
}
|
|
16779
17947
|
}
|
|
@@ -16841,7 +18009,7 @@ var SettingsManager = class {
|
|
|
16841
18009
|
}
|
|
16842
18010
|
permissions.allow = Array.from(current2);
|
|
16843
18011
|
const next = { ...existing, permissions };
|
|
16844
|
-
await
|
|
18012
|
+
await fs9.promises.mkdir(path11.dirname(filePath), { recursive: true });
|
|
16845
18013
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16846
18014
|
`);
|
|
16847
18015
|
this.localSettings = next;
|
|
@@ -16874,7 +18042,7 @@ var SettingsManager = class {
|
|
|
16874
18042
|
...existing,
|
|
16875
18043
|
posthogApprovedExecTools: Array.from(current2)
|
|
16876
18044
|
};
|
|
16877
|
-
await
|
|
18045
|
+
await fs9.promises.mkdir(path11.dirname(filePath), { recursive: true });
|
|
16878
18046
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16879
18047
|
`);
|
|
16880
18048
|
this.localSettings = next;
|
|
@@ -16980,7 +18148,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16980
18148
|
};
|
|
16981
18149
|
}
|
|
16982
18150
|
async newSession(params) {
|
|
16983
|
-
if (
|
|
18151
|
+
if (fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json.backup")) && !fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json"))) {
|
|
16984
18152
|
throw import_sdk2.RequestError.authRequired();
|
|
16985
18153
|
}
|
|
16986
18154
|
const response = await this.createSession(params, {
|
|
@@ -17034,7 +18202,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17034
18202
|
};
|
|
17035
18203
|
}
|
|
17036
18204
|
async listSessions(params) {
|
|
17037
|
-
const sdkSessions = await (0,
|
|
18205
|
+
const sdkSessions = await (0, import_claude_agent_sdk2.listSessions)({ dir: params.cwd ?? void 0 });
|
|
17038
18206
|
const sessions = [];
|
|
17039
18207
|
for (const session of sdkSessions) {
|
|
17040
18208
|
if (!session.cwd) continue;
|
|
@@ -17078,8 +18246,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17078
18246
|
if (this.session.promptRunning) {
|
|
17079
18247
|
this.session.input.push(userMessage);
|
|
17080
18248
|
const order = this.session.nextPendingOrder++;
|
|
17081
|
-
const cancelled = await new Promise((
|
|
17082
|
-
this.session.pendingMessages.set(promptUuid, { resolve:
|
|
18249
|
+
const cancelled = await new Promise((resolve8) => {
|
|
18250
|
+
this.session.pendingMessages.set(promptUuid, { resolve: resolve8, order });
|
|
17083
18251
|
});
|
|
17084
18252
|
if (cancelled) {
|
|
17085
18253
|
return { stopReason: "cancelled" };
|
|
@@ -17467,7 +18635,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17467
18635
|
abortController: newAbortController
|
|
17468
18636
|
};
|
|
17469
18637
|
const newInput = new Pushable();
|
|
17470
|
-
const newQuery = (0,
|
|
18638
|
+
const newQuery = (0, import_claude_agent_sdk2.query)({ prompt: newInput, options: newOptions });
|
|
17471
18639
|
prev.query = newQuery;
|
|
17472
18640
|
prev.input = newInput;
|
|
17473
18641
|
prev.queryOptions = newOptions;
|
|
@@ -17601,7 +18769,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17601
18769
|
const { resume, forkSession } = creationOpts;
|
|
17602
18770
|
const isResume = !!resume;
|
|
17603
18771
|
const meta = params._meta;
|
|
17604
|
-
const taskId = meta
|
|
18772
|
+
const taskId = resolveTaskId(meta);
|
|
18773
|
+
const cloudRun = isCloudRun(meta);
|
|
17605
18774
|
const effort = meta?.claudeCode?.options?.effort;
|
|
17606
18775
|
let sessionId;
|
|
17607
18776
|
if (forkSession) {
|
|
@@ -17616,6 +18785,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17616
18785
|
await settingsManager.initialize();
|
|
17617
18786
|
const earlyModelId = settingsManager.getSettings().model || meta?.model || "";
|
|
17618
18787
|
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params) : {};
|
|
18788
|
+
const localToolsServer = createLocalToolsMcpServer(
|
|
18789
|
+
{ cwd, token: resolveGithubToken(), taskId },
|
|
18790
|
+
meta
|
|
18791
|
+
);
|
|
18792
|
+
if (localToolsServer) {
|
|
18793
|
+
mcpServers[LOCAL_TOOLS_MCP_NAME] = localToolsServer;
|
|
18794
|
+
} else if (cloudRun) {
|
|
18795
|
+
this.logger.warn(
|
|
18796
|
+
"Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
|
|
18797
|
+
);
|
|
18798
|
+
}
|
|
17619
18799
|
const systemPrompt = buildSystemPrompt(meta?.systemPrompt);
|
|
17620
18800
|
if (meta?.mcpToolApprovals) {
|
|
17621
18801
|
setMcpToolApprovalStates(meta.mcpToolApprovals);
|
|
@@ -17651,10 +18831,11 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17651
18831
|
onProcessExited: this.options?.onProcessExited,
|
|
17652
18832
|
effort,
|
|
17653
18833
|
enrichmentDeps: this.enrichment?.deps,
|
|
17654
|
-
enrichedReadCache: this.enrichedReadCache
|
|
18834
|
+
enrichedReadCache: this.enrichedReadCache,
|
|
18835
|
+
cloudMode: cloudRun
|
|
17655
18836
|
});
|
|
17656
18837
|
const abortController = options.abortController;
|
|
17657
|
-
const q = (0,
|
|
18838
|
+
const q = (0, import_claude_agent_sdk2.query)({ prompt: input, options });
|
|
17658
18839
|
const session = {
|
|
17659
18840
|
query: q,
|
|
17660
18841
|
queryOptions: options,
|
|
@@ -17942,7 +19123,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17942
19123
|
}
|
|
17943
19124
|
async replaySessionHistory(sessionId) {
|
|
17944
19125
|
try {
|
|
17945
|
-
const messages = await (0,
|
|
19126
|
+
const messages = await (0, import_claude_agent_sdk2.getSessionMessages)(sessionId, {
|
|
17946
19127
|
dir: this.session.cwd
|
|
17947
19128
|
});
|
|
17948
19129
|
const replayContext = {
|
|
@@ -17983,7 +19164,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17983
19164
|
*/
|
|
17984
19165
|
deferBackgroundFetches(q) {
|
|
17985
19166
|
Promise.all([
|
|
17986
|
-
new Promise((
|
|
19167
|
+
new Promise((resolve8) => setTimeout(resolve8, 10)).then(
|
|
17987
19168
|
() => this.sendAvailableCommandsUpdate()
|
|
17988
19169
|
),
|
|
17989
19170
|
fetchMcpToolMetadata(q, this.logger).then(() => {
|
|
@@ -18223,9 +19404,9 @@ function resetUsage(state) {
|
|
|
18223
19404
|
}
|
|
18224
19405
|
|
|
18225
19406
|
// src/adapters/codex/settings.ts
|
|
18226
|
-
var
|
|
18227
|
-
var
|
|
18228
|
-
var
|
|
19407
|
+
var fs11 = __toESM(require("fs"), 1);
|
|
19408
|
+
var os7 = __toESM(require("os"), 1);
|
|
19409
|
+
var path13 = __toESM(require("path"), 1);
|
|
18229
19410
|
var CodexSettingsManager = class {
|
|
18230
19411
|
cwd;
|
|
18231
19412
|
settings = { mcpServerNames: [] };
|
|
@@ -18236,12 +19417,12 @@ var CodexSettingsManager = class {
|
|
|
18236
19417
|
async initialize() {
|
|
18237
19418
|
}
|
|
18238
19419
|
getConfigPath() {
|
|
18239
|
-
return
|
|
19420
|
+
return path13.join(os7.homedir(), ".codex", "config.toml");
|
|
18240
19421
|
}
|
|
18241
19422
|
loadSettings() {
|
|
18242
19423
|
const configPath = this.getConfigPath();
|
|
18243
19424
|
try {
|
|
18244
|
-
const content =
|
|
19425
|
+
const content = fs11.readFileSync(configPath, "utf-8");
|
|
18245
19426
|
this.settings = parseCodexToml(content, this.cwd);
|
|
18246
19427
|
} catch {
|
|
18247
19428
|
this.settings = { mcpServerNames: [] };
|
|
@@ -18456,8 +19637,7 @@ function getCurrentPermissionMode(currentModeId, fallbackMode) {
|
|
|
18456
19637
|
var STRUCTURED_OUTPUT_INSTRUCTIONS = `
|
|
18457
19638
|
|
|
18458
19639
|
When you have completed the task, call the \`${STRUCTURED_OUTPUT_TOOL_NAME}\` tool with the final structured result. The tool's input schema matches the required output format for this task. Do not describe the result in a plain message \u2014 submitting it via the tool is required for the task to be considered complete.`;
|
|
18459
|
-
function
|
|
18460
|
-
const rel = "adapters/codex/structured-output-mcp-server.js";
|
|
19640
|
+
function resolveBundledMcpScript(rel) {
|
|
18461
19641
|
let dir = import_meta2.dirname ?? __dirname;
|
|
18462
19642
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
18463
19643
|
const candidate = (0, import_node_path5.resolve)(dir, rel);
|
|
@@ -18469,7 +19649,9 @@ function resolveStructuredOutputMcpScript() {
|
|
|
18469
19649
|
);
|
|
18470
19650
|
}
|
|
18471
19651
|
function buildStructuredOutputMcpServer(jsonSchema) {
|
|
18472
|
-
const scriptPath =
|
|
19652
|
+
const scriptPath = resolveBundledMcpScript(
|
|
19653
|
+
"adapters/codex/structured-output-mcp-server.js"
|
|
19654
|
+
);
|
|
18473
19655
|
const schemaBase64 = Buffer.from(JSON.stringify(jsonSchema)).toString(
|
|
18474
19656
|
"base64"
|
|
18475
19657
|
);
|
|
@@ -18480,6 +19662,30 @@ function buildStructuredOutputMcpServer(jsonSchema) {
|
|
|
18480
19662
|
env: [{ name: "POSTHOG_OUTPUT_SCHEMA", value: schemaBase64 }]
|
|
18481
19663
|
};
|
|
18482
19664
|
}
|
|
19665
|
+
function buildLocalToolsMcpServer(ctx, enabledNames) {
|
|
19666
|
+
const scriptPath = resolveBundledMcpScript(
|
|
19667
|
+
"adapters/codex/local-tools-mcp-server.js"
|
|
19668
|
+
);
|
|
19669
|
+
const ctxBase64 = Buffer.from(JSON.stringify(ctx)).toString("base64");
|
|
19670
|
+
const env = [
|
|
19671
|
+
{ name: "POSTHOG_LOCAL_TOOLS_CTX", value: ctxBase64 },
|
|
19672
|
+
{ name: "POSTHOG_LOCAL_TOOLS_ENABLED", value: enabledNames.join(",") }
|
|
19673
|
+
];
|
|
19674
|
+
if (ctx.token) {
|
|
19675
|
+
env.push(
|
|
19676
|
+
...Object.entries(ghTokenEnv(ctx.token)).map(([name2, value]) => ({
|
|
19677
|
+
name: name2,
|
|
19678
|
+
value
|
|
19679
|
+
}))
|
|
19680
|
+
);
|
|
19681
|
+
}
|
|
19682
|
+
return {
|
|
19683
|
+
name: LOCAL_TOOLS_MCP_NAME,
|
|
19684
|
+
command: process.execPath,
|
|
19685
|
+
args: [scriptPath],
|
|
19686
|
+
env
|
|
19687
|
+
};
|
|
19688
|
+
}
|
|
18483
19689
|
var CodexAcpAgent = class extends BaseAcpAgent {
|
|
18484
19690
|
adapterName = "codex";
|
|
18485
19691
|
codexProcess;
|
|
@@ -18567,14 +19773,17 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18567
19773
|
async newSession(params) {
|
|
18568
19774
|
const meta = params._meta;
|
|
18569
19775
|
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
|
|
18570
|
-
const injectedParams = this.
|
|
19776
|
+
const injectedParams = this.applyLocalTools(
|
|
19777
|
+
this.applyStructuredOutput(params, meta),
|
|
19778
|
+
meta
|
|
19779
|
+
);
|
|
18571
19780
|
const response = await this.codexConnection.newSession(injectedParams);
|
|
18572
19781
|
response.configOptions = normalizeCodexConfigOptions(
|
|
18573
19782
|
response.configOptions
|
|
18574
19783
|
);
|
|
18575
19784
|
this.sessionState = createSessionState(response.sessionId, params.cwd, {
|
|
18576
19785
|
taskRunId: meta?.taskRunId,
|
|
18577
|
-
taskId: meta
|
|
19786
|
+
taskId: resolveTaskId(meta),
|
|
18578
19787
|
modeId: response.modes?.currentModeId ?? "auto",
|
|
18579
19788
|
modelId: response.models?.currentModelId,
|
|
18580
19789
|
permissionMode: requestedPermissionMode
|
|
@@ -18601,7 +19810,10 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18601
19810
|
}
|
|
18602
19811
|
async loadSession(params) {
|
|
18603
19812
|
const meta = params._meta;
|
|
18604
|
-
const injectedParams = this.
|
|
19813
|
+
const injectedParams = this.applyLocalTools(
|
|
19814
|
+
this.applyStructuredOutput(params, meta),
|
|
19815
|
+
meta
|
|
19816
|
+
);
|
|
18605
19817
|
const response = await this.codexConnection.loadSession(injectedParams);
|
|
18606
19818
|
response.configOptions = normalizeCodexConfigOptions(
|
|
18607
19819
|
response.configOptions
|
|
@@ -18612,7 +19824,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18612
19824
|
);
|
|
18613
19825
|
this.sessionState = createSessionState(params.sessionId, params.cwd, {
|
|
18614
19826
|
taskRunId: meta?.taskRunId,
|
|
18615
|
-
taskId: meta
|
|
19827
|
+
taskId: resolveTaskId(meta),
|
|
18616
19828
|
modeId: response.modes?.currentModeId ?? "auto",
|
|
18617
19829
|
permissionMode: currentPermissionMode
|
|
18618
19830
|
});
|
|
@@ -18629,13 +19841,16 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18629
19841
|
}
|
|
18630
19842
|
async unstable_resumeSession(params) {
|
|
18631
19843
|
const meta = params._meta;
|
|
18632
|
-
const injectedParams = this.
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
19844
|
+
const injectedParams = this.applyLocalTools(
|
|
19845
|
+
this.applyStructuredOutput(
|
|
19846
|
+
{
|
|
19847
|
+
sessionId: params.sessionId,
|
|
19848
|
+
cwd: params.cwd,
|
|
19849
|
+
mcpServers: params.mcpServers ?? [],
|
|
19850
|
+
_meta: params._meta
|
|
19851
|
+
},
|
|
19852
|
+
meta
|
|
19853
|
+
),
|
|
18639
19854
|
meta
|
|
18640
19855
|
);
|
|
18641
19856
|
const loadResponse = await this.codexConnection.loadSession(injectedParams);
|
|
@@ -18648,7 +19863,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18648
19863
|
);
|
|
18649
19864
|
this.sessionState = createSessionState(params.sessionId, params.cwd, {
|
|
18650
19865
|
taskRunId: meta?.taskRunId,
|
|
18651
|
-
taskId: meta
|
|
19866
|
+
taskId: resolveTaskId(meta),
|
|
18652
19867
|
modeId: loadResponse.modes?.currentModeId ?? "auto",
|
|
18653
19868
|
permissionMode: currentPermissionMode
|
|
18654
19869
|
});
|
|
@@ -18669,12 +19884,15 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18669
19884
|
}
|
|
18670
19885
|
async unstable_forkSession(params) {
|
|
18671
19886
|
const meta = params._meta;
|
|
18672
|
-
const injectedParams = this.
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
19887
|
+
const injectedParams = this.applyLocalTools(
|
|
19888
|
+
this.applyStructuredOutput(
|
|
19889
|
+
{
|
|
19890
|
+
cwd: params.cwd,
|
|
19891
|
+
mcpServers: params.mcpServers ?? [],
|
|
19892
|
+
_meta: params._meta
|
|
19893
|
+
},
|
|
19894
|
+
meta
|
|
19895
|
+
),
|
|
18678
19896
|
meta
|
|
18679
19897
|
);
|
|
18680
19898
|
const newResponse = await this.codexConnection.newSession(injectedParams);
|
|
@@ -18684,7 +19902,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18684
19902
|
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
|
|
18685
19903
|
this.sessionState = createSessionState(newResponse.sessionId, params.cwd, {
|
|
18686
19904
|
taskRunId: meta?.taskRunId,
|
|
18687
|
-
taskId: meta
|
|
19905
|
+
taskId: resolveTaskId(meta),
|
|
18688
19906
|
modeId: newResponse.modes?.currentModeId ?? "auto",
|
|
18689
19907
|
permissionMode: requestedPermissionMode
|
|
18690
19908
|
});
|
|
@@ -18721,6 +19939,41 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18721
19939
|
}
|
|
18722
19940
|
};
|
|
18723
19941
|
}
|
|
19942
|
+
/**
|
|
19943
|
+
* Injects the stdio general local-tools MCP server. Tools self-gate via the
|
|
19944
|
+
* registry (e.g. signed-commit is cloud-only and needs a GH token), so the
|
|
19945
|
+
* server is only injected when at least one tool's gate passes. Their
|
|
19946
|
+
* instructions already live in the shared cloud system prompt, so only the
|
|
19947
|
+
* server needs injecting here.
|
|
19948
|
+
*/
|
|
19949
|
+
applyLocalTools(request, meta) {
|
|
19950
|
+
const cwd = request.cwd;
|
|
19951
|
+
if (!cwd) {
|
|
19952
|
+
return request;
|
|
19953
|
+
}
|
|
19954
|
+
const ctx = {
|
|
19955
|
+
cwd,
|
|
19956
|
+
token: resolveGithubToken(),
|
|
19957
|
+
taskId: resolveTaskId(meta)
|
|
19958
|
+
};
|
|
19959
|
+
const tools = enabledLocalTools(ctx, meta);
|
|
19960
|
+
if (tools.length === 0) {
|
|
19961
|
+
if (isCloudRun(meta)) {
|
|
19962
|
+
this.logger.warn(
|
|
19963
|
+
"Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
|
|
19964
|
+
);
|
|
19965
|
+
}
|
|
19966
|
+
return request;
|
|
19967
|
+
}
|
|
19968
|
+
const mcpServer = buildLocalToolsMcpServer(
|
|
19969
|
+
ctx,
|
|
19970
|
+
tools.map((t) => t.name)
|
|
19971
|
+
);
|
|
19972
|
+
return {
|
|
19973
|
+
...request,
|
|
19974
|
+
mcpServers: [...request.mcpServers ?? [], mcpServer]
|
|
19975
|
+
};
|
|
19976
|
+
}
|
|
18724
19977
|
async applyInitialPermissionMode(sessionId, permissionMode, currentModeId) {
|
|
18725
19978
|
if (!permissionMode) {
|
|
18726
19979
|
return;
|
|
@@ -19104,8 +20357,8 @@ var import_node_path6 = __toESM(require("path"), 1);
|
|
|
19104
20357
|
|
|
19105
20358
|
// ../git/dist/sagas/checkpoint.js
|
|
19106
20359
|
var import_node_crypto2 = require("crypto");
|
|
19107
|
-
var
|
|
19108
|
-
var
|
|
20360
|
+
var fs12 = __toESM(require("fs/promises"), 1);
|
|
20361
|
+
var path14 = __toESM(require("path"), 1);
|
|
19109
20362
|
|
|
19110
20363
|
// ../shared/dist/index.js
|
|
19111
20364
|
var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
|
|
@@ -19391,7 +20644,7 @@ async function createWorktreeTree(git, baseDir, head) {
|
|
|
19391
20644
|
const treeHash = await tempGit.raw(["write-tree"]);
|
|
19392
20645
|
return treeHash.trim();
|
|
19393
20646
|
} finally {
|
|
19394
|
-
await
|
|
20647
|
+
await fs12.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19395
20648
|
});
|
|
19396
20649
|
}
|
|
19397
20650
|
}
|
|
@@ -19489,7 +20742,7 @@ async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
|
19489
20742
|
const metaTree = await tempGit.raw(["write-tree"]);
|
|
19490
20743
|
return metaTree.trim();
|
|
19491
20744
|
} finally {
|
|
19492
|
-
await
|
|
20745
|
+
await fs12.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19493
20746
|
});
|
|
19494
20747
|
}
|
|
19495
20748
|
}
|
|
@@ -19506,12 +20759,12 @@ function formatCheckpointMessage(meta) {
|
|
|
19506
20759
|
async function getGitCommonDir(git, baseDir) {
|
|
19507
20760
|
const raw = await git.raw(["rev-parse", "--git-common-dir"]);
|
|
19508
20761
|
const dir = raw.trim() || ".git";
|
|
19509
|
-
return
|
|
20762
|
+
return path14.isAbsolute(dir) ? dir : path14.resolve(baseDir, dir);
|
|
19510
20763
|
}
|
|
19511
20764
|
async function createTempIndexGit(git, baseDir, label) {
|
|
19512
|
-
const tmpDir =
|
|
19513
|
-
await
|
|
19514
|
-
const tempIndexPath =
|
|
20765
|
+
const tmpDir = path14.join(await getGitCommonDir(git, baseDir), "posthog-code-tmp");
|
|
20766
|
+
await fs12.mkdir(tmpDir, { recursive: true });
|
|
20767
|
+
const tempIndexPath = path14.join(tmpDir, `${label}-${Date.now()}-${(0, import_node_crypto2.randomUUID)()}`);
|
|
19515
20768
|
const tempGit = createGitClient(baseDir).env({
|
|
19516
20769
|
...process.env,
|
|
19517
20770
|
GIT_INDEX_FILE: tempIndexPath
|
|
@@ -19876,7 +21129,7 @@ var GitHandoffTracker = class {
|
|
|
19876
21129
|
await this.runGitProcess(args2, input);
|
|
19877
21130
|
}
|
|
19878
21131
|
async runGitProcessAllowingFailure(args2) {
|
|
19879
|
-
return new Promise((
|
|
21132
|
+
return new Promise((resolve8, reject) => {
|
|
19880
21133
|
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19881
21134
|
cwd: this.repositoryPath,
|
|
19882
21135
|
stdio: ["ignore", "ignore", "pipe"]
|
|
@@ -19895,12 +21148,12 @@ var GitHandoffTracker = class {
|
|
|
19895
21148
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
19896
21149
|
return;
|
|
19897
21150
|
}
|
|
19898
|
-
|
|
21151
|
+
resolve8(code);
|
|
19899
21152
|
});
|
|
19900
21153
|
});
|
|
19901
21154
|
}
|
|
19902
21155
|
async runGitWithEnv(env, args2) {
|
|
19903
|
-
return new Promise((
|
|
21156
|
+
return new Promise((resolve8, reject) => {
|
|
19904
21157
|
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19905
21158
|
cwd: this.repositoryPath,
|
|
19906
21159
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -19917,7 +21170,7 @@ var GitHandoffTracker = class {
|
|
|
19917
21170
|
child.on("error", reject);
|
|
19918
21171
|
child.on("close", (code) => {
|
|
19919
21172
|
if (code === 0) {
|
|
19920
|
-
|
|
21173
|
+
resolve8(stdout);
|
|
19921
21174
|
return;
|
|
19922
21175
|
}
|
|
19923
21176
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
@@ -19925,7 +21178,7 @@ var GitHandoffTracker = class {
|
|
|
19925
21178
|
});
|
|
19926
21179
|
}
|
|
19927
21180
|
runGitProcess(args2, input) {
|
|
19928
|
-
return new Promise((
|
|
21181
|
+
return new Promise((resolve8, reject) => {
|
|
19929
21182
|
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19930
21183
|
cwd: this.repositoryPath,
|
|
19931
21184
|
stdio: "pipe"
|
|
@@ -19941,7 +21194,7 @@ var GitHandoffTracker = class {
|
|
|
19941
21194
|
child.on("error", reject);
|
|
19942
21195
|
child.on("close", (code) => {
|
|
19943
21196
|
if (code === 0) {
|
|
19944
|
-
|
|
21197
|
+
resolve8({ stdout, stderr });
|
|
19945
21198
|
return;
|
|
19946
21199
|
}
|
|
19947
21200
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
@@ -20469,9 +21722,9 @@ function extractCreatedPrUrl(input) {
|
|
|
20469
21722
|
|
|
20470
21723
|
// src/adapters/claude/session/jsonl-hydration.ts
|
|
20471
21724
|
var import_node_crypto3 = require("crypto");
|
|
20472
|
-
var
|
|
20473
|
-
var
|
|
20474
|
-
var
|
|
21725
|
+
var fs13 = __toESM(require("fs/promises"), 1);
|
|
21726
|
+
var os8 = __toESM(require("os"), 1);
|
|
21727
|
+
var path16 = __toESM(require("path"), 1);
|
|
20475
21728
|
var CHARS_PER_TOKEN = 4;
|
|
20476
21729
|
var DEFAULT_MAX_TOKENS = 15e4;
|
|
20477
21730
|
function estimateTurnTokens(turn) {
|
|
@@ -21137,7 +22390,7 @@ async function getAgentshVersion() {
|
|
|
21137
22390
|
}
|
|
21138
22391
|
async function resolveAgentshRuntimeInfo({
|
|
21139
22392
|
sessionIdPath = AGENTSH_SESSION_ID_FILE,
|
|
21140
|
-
readSessionId = async (
|
|
22393
|
+
readSessionId = async (path18) => (0, import_promises5.readFile)(path18, "utf8"),
|
|
21141
22394
|
getVersion = getAgentshVersion
|
|
21142
22395
|
} = {}) {
|
|
21143
22396
|
let sessionId;
|
|
@@ -21191,20 +22444,20 @@ function normalizeCloudPromptContent(content) {
|
|
|
21191
22444
|
|
|
21192
22445
|
// src/server/jwt.ts
|
|
21193
22446
|
var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
|
|
21194
|
-
var
|
|
22447
|
+
var import_zod3 = require("zod");
|
|
21195
22448
|
var SANDBOX_CONNECTION_AUDIENCE = "posthog:sandbox_connection";
|
|
21196
|
-
var userDataSchema =
|
|
21197
|
-
run_id:
|
|
21198
|
-
task_id:
|
|
21199
|
-
team_id:
|
|
21200
|
-
user_id:
|
|
21201
|
-
distinct_id:
|
|
21202
|
-
mode:
|
|
22449
|
+
var userDataSchema = import_zod3.z.object({
|
|
22450
|
+
run_id: import_zod3.z.string(),
|
|
22451
|
+
task_id: import_zod3.z.string(),
|
|
22452
|
+
team_id: import_zod3.z.number(),
|
|
22453
|
+
user_id: import_zod3.z.number(),
|
|
22454
|
+
distinct_id: import_zod3.z.string(),
|
|
22455
|
+
mode: import_zod3.z.enum(["interactive", "background"]).optional().default("interactive")
|
|
21203
22456
|
});
|
|
21204
22457
|
var jwtPayloadSchema = userDataSchema.extend({
|
|
21205
|
-
exp:
|
|
21206
|
-
iat:
|
|
21207
|
-
aud:
|
|
22458
|
+
exp: import_zod3.z.number(),
|
|
22459
|
+
iat: import_zod3.z.number().optional(),
|
|
22460
|
+
aud: import_zod3.z.string().optional()
|
|
21208
22461
|
});
|
|
21209
22462
|
var JwtValidationError = class extends Error {
|
|
21210
22463
|
constructor(message, code) {
|
|
@@ -21337,7 +22590,7 @@ function validateCommandParams(method, params) {
|
|
|
21337
22590
|
}
|
|
21338
22591
|
|
|
21339
22592
|
// src/server/agent-server.ts
|
|
21340
|
-
var agentErrorClassificationSchema =
|
|
22593
|
+
var agentErrorClassificationSchema = import_zod4.z.enum([
|
|
21341
22594
|
"upstream_stream_terminated",
|
|
21342
22595
|
"upstream_connection_error",
|
|
21343
22596
|
"upstream_provider_failure",
|
|
@@ -21349,8 +22602,8 @@ var upstreamProviderFailureClassifications = /* @__PURE__ */ new Set([
|
|
|
21349
22602
|
"upstream_connection_error",
|
|
21350
22603
|
"upstream_provider_failure"
|
|
21351
22604
|
]);
|
|
21352
|
-
var errorWithClassificationSchema =
|
|
21353
|
-
data:
|
|
22605
|
+
var errorWithClassificationSchema = import_zod4.z.object({
|
|
22606
|
+
data: import_zod4.z.object({ classification: agentErrorClassificationSchema })
|
|
21354
22607
|
});
|
|
21355
22608
|
var SSE_KEEPALIVE_INTERVAL_MS = 25e3;
|
|
21356
22609
|
var NdJsonTap = class {
|
|
@@ -21671,7 +22924,7 @@ var AgentServer = class {
|
|
|
21671
22924
|
return app;
|
|
21672
22925
|
}
|
|
21673
22926
|
async start() {
|
|
21674
|
-
await new Promise((
|
|
22927
|
+
await new Promise((resolve8) => {
|
|
21675
22928
|
this.server = (0, import_node_server.serve)(
|
|
21676
22929
|
{
|
|
21677
22930
|
fetch: this.app.fetch,
|
|
@@ -21681,7 +22934,7 @@ var AgentServer = class {
|
|
|
21681
22934
|
this.logger.debug(
|
|
21682
22935
|
`HTTP server listening on port ${this.config.port}`
|
|
21683
22936
|
);
|
|
21684
|
-
|
|
22937
|
+
resolve8();
|
|
21685
22938
|
}
|
|
21686
22939
|
);
|
|
21687
22940
|
});
|
|
@@ -22007,6 +23260,7 @@ var AgentServer = class {
|
|
|
22007
23260
|
_meta: {
|
|
22008
23261
|
sessionId: payload.run_id,
|
|
22009
23262
|
taskRunId: payload.run_id,
|
|
23263
|
+
taskId: payload.task_id,
|
|
22010
23264
|
systemPrompt: sessionSystemPrompt,
|
|
22011
23265
|
...this.config.model && { model: this.config.model },
|
|
22012
23266
|
allowedDomains: this.config.allowedDomains,
|
|
@@ -22490,24 +23744,21 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`;
|
|
|
22490
23744
|
buildCloudSystemPrompt(prUrl) {
|
|
22491
23745
|
const taskId = this.config.taskId;
|
|
22492
23746
|
const shouldAutoCreatePr = this.shouldAutoPublishCloudChanges();
|
|
22493
|
-
const
|
|
22494
|
-
##
|
|
22495
|
-
|
|
23747
|
+
const signedCommitInstructions = `
|
|
23748
|
+
## Committing (signed commits required)
|
|
23749
|
+
Commits MUST be signed. \`git commit\` and \`git push\` are blocked in this environment.
|
|
23750
|
+
To commit: stage your changes with \`git add\`, then call the \`git_signed_commit\` tool (full
|
|
23751
|
+
name \`${SIGNED_COMMIT_QUALIFIED_TOOL_NAME}\`) with a \`message\` (and optional \`body\`/\`paths\`).
|
|
23752
|
+
It creates a GitHub-signed ("Verified") commit on the branch and keeps your local checkout in
|
|
23753
|
+
sync. To start a new branch, pass \`branch\` (prefixed with \`posthog-code/\`) \u2014 the tool creates
|
|
23754
|
+
it on the remote for you.
|
|
22496
23755
|
|
|
22497
|
-
|
|
23756
|
+
## Attribution
|
|
23757
|
+
Do NOT add "Co-Authored-By" trailers or "Generated with [Claude Code]" lines to your
|
|
23758
|
+
commit messages. The \`git_signed_commit\` tool automatically appends the only trailers
|
|
23759
|
+
we want:
|
|
22498
23760
|
Generated-By: PostHog Code
|
|
22499
|
-
Task-Id: ${taskId}
|
|
22500
|
-
|
|
22501
|
-
Example:
|
|
22502
|
-
\`\`\`
|
|
22503
|
-
git commit -m "$(cat <<'EOF'
|
|
22504
|
-
fix: resolve login redirect loop
|
|
22505
|
-
|
|
22506
|
-
Generated-By: PostHog Code
|
|
22507
|
-
Task-Id: ${taskId}
|
|
22508
|
-
EOF
|
|
22509
|
-
)"
|
|
22510
|
-
\`\`\``;
|
|
23761
|
+
Task-Id: ${taskId}`;
|
|
22511
23762
|
if (prUrl) {
|
|
22512
23763
|
if (!shouldAutoCreatePr) {
|
|
22513
23764
|
return `
|
|
@@ -22520,7 +23771,7 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22520
23771
|
Important:
|
|
22521
23772
|
- Do NOT create new commits, push to the branch, or update the pull request unless the user explicitly asks.
|
|
22522
23773
|
- Do NOT create a new branch or a new pull request.
|
|
22523
|
-
${
|
|
23774
|
+
${signedCommitInstructions}
|
|
22524
23775
|
`;
|
|
22525
23776
|
}
|
|
22526
23777
|
return `
|
|
@@ -22530,9 +23781,8 @@ This task already has an open pull request: ${prUrl}
|
|
|
22530
23781
|
|
|
22531
23782
|
After completing the requested changes:
|
|
22532
23783
|
1. Check out the existing PR branch with \`gh pr checkout ${prUrl}\`
|
|
22533
|
-
2. Stage
|
|
22534
|
-
3.
|
|
22535
|
-
4. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
23784
|
+
2. Stage your changes with \`git add\`, then call the \`git_signed_commit\` tool with a clear \`message\` (do NOT use \`git commit\`/\`git push\` \u2014 they are blocked). This commits to the existing PR branch.
|
|
23785
|
+
3. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
22536
23786
|
- Reply on the thread with a short note describing what changed (reference the commit SHA when useful) using \`gh api -X POST /repos/{owner}/{repo}/pulls/{n}/comments/{id}/replies -f body='...'\`.
|
|
22537
23787
|
- Resolve the thread via the \`resolveReviewThread\` GraphQL mutation: \`gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -f id="<thread-node-id>"\`.
|
|
22538
23788
|
List unresolved threads first with \`gh api graphql -f query='{repository(owner:"<owner>",name:"<repo>"){pullRequest(number:<n>){reviewThreads(first:100){nodes{id isResolved comments(first:1){nodes{body}}}}}}}'\` so you can resolve each one you fixed.
|
|
@@ -22540,7 +23790,7 @@ After completing the requested changes:
|
|
|
22540
23790
|
Important:
|
|
22541
23791
|
- Do NOT create a new branch or a new pull request.
|
|
22542
23792
|
- Do NOT push fixes for review comments without replying to and resolving each related thread.
|
|
22543
|
-
${
|
|
23793
|
+
${signedCommitInstructions}
|
|
22544
23794
|
`;
|
|
22545
23795
|
}
|
|
22546
23796
|
if (!this.config.repositoryPath) {
|
|
@@ -22551,7 +23801,7 @@ When the user asks for code changes:
|
|
|
22551
23801
|
When the user explicitly asks to clone or work in a GitHub repository:
|
|
22552
23802
|
- Clone the repository into /tmp/workspace/repos/<owner>/<repo> using \`gh repo clone <owner>/<repo> /tmp/workspace/repos/<owner>/<repo>\`
|
|
22553
23803
|
- Work from inside that cloned repository for follow-up code changes
|
|
22554
|
-
- If the user explicitly asks you to open or update a pull request, create a branch, commit the
|
|
23804
|
+
- If the user explicitly asks you to open or update a pull request, create a branch, stage your changes with \`git add\` and commit them with the \`git_signed_commit\` tool (do NOT use \`git commit\`/\`git push\` \u2014 they are blocked), and open a draft pull request from inside the clone. Before opening the PR, check the cloned repo for a PR template at \`.github/pull_request_template.md\` (or variants; fall back to the org's \`.github\` repo via \`gh api\`) and use it as the body structure, and search for matching open issues with \`gh issue list --search\` to include \`Closes #<n>\` / \`Refs #<n>\` links.
|
|
22555
23805
|
- Do NOT create branches, commits, push changes, or open pull requests unless the user explicitly asks for that`;
|
|
22556
23806
|
return `
|
|
22557
23807
|
# Cloud Task Execution \u2014 No Repository Mode
|
|
@@ -22570,7 +23820,7 @@ ${publishInstructions}
|
|
|
22570
23820
|
|
|
22571
23821
|
Important:
|
|
22572
23822
|
- Prefer using MCP tools to answer questions with real data over giving generic advice.
|
|
22573
|
-
${
|
|
23823
|
+
${signedCommitInstructions}
|
|
22574
23824
|
`;
|
|
22575
23825
|
}
|
|
22576
23826
|
if (!shouldAutoCreatePr) {
|
|
@@ -22581,21 +23831,20 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22581
23831
|
|
|
22582
23832
|
Important:
|
|
22583
23833
|
- Do NOT create a branch, commit, push, or open a pull request unless the user explicitly asks.
|
|
22584
|
-
${
|
|
23834
|
+
${signedCommitInstructions}
|
|
22585
23835
|
`;
|
|
22586
23836
|
}
|
|
22587
23837
|
return `
|
|
22588
23838
|
# Cloud Task Execution
|
|
22589
23839
|
|
|
22590
23840
|
After completing the requested changes:
|
|
22591
|
-
1.
|
|
22592
|
-
2. Stage
|
|
22593
|
-
3.
|
|
22594
|
-
4. Before opening the PR, prepare the body:
|
|
23841
|
+
1. Pick a new branch name prefixed with \`posthog-code/\` (e.g. \`posthog-code/fix-login-redirect\`)
|
|
23842
|
+
2. Stage your changes with \`git add\`, then call the \`git_signed_commit\` tool with \`branch\` set to that name and a clear \`message\` (do NOT use \`git commit\`/\`git push\` \u2014 they are blocked). The tool creates the branch on the remote and a signed commit on it.
|
|
23843
|
+
3. Before opening the PR, prepare the body:
|
|
22595
23844
|
- Check the repo for a PR template at \`.github/pull_request_template.md\` (also try \`.github/PULL_REQUEST_TEMPLATE.md\`, \`docs/pull_request_template.md\`, and root variants). If one exists, use its exact section headings as the PR body \u2014 do NOT fall back to a generic Summary/Test plan format.
|
|
22596
23845
|
- If no repo-level template exists, check the org's \`.github\` repo via \`gh api /repos/<owner>/.github/contents/.github/pull_request_template.md\` (and other common paths) and use that as a fallback.
|
|
22597
23846
|
- Search for matching open issues with \`gh issue list --state open --search '<keywords>'\` (derive keywords from the branch name, commits, and changed files; \`gh issue view <n>\` to confirm relevance). For every issue this PR would resolve, include a \`Closes #<n>\` line in the body so GitHub auto-links and auto-closes it on merge. For issues that are related but not fully resolved, use \`Refs #<n>\` instead.
|
|
22598
|
-
|
|
23847
|
+
4. Create a draft pull request using \`gh pr create --draft${this.config.baseBranch ? ` --base ${this.config.baseBranch}` : ""}\` with a descriptive title and the body prepared above. Add the following footer at the end of the PR description:
|
|
22599
23848
|
\`\`\`
|
|
22600
23849
|
---
|
|
22601
23850
|
*Created with [PostHog Code](https://posthog.com/code?ref=pr)*
|
|
@@ -22603,7 +23852,7 @@ After completing the requested changes:
|
|
|
22603
23852
|
|
|
22604
23853
|
Important:
|
|
22605
23854
|
- Always create the PR as a draft. Do not ask for confirmation.
|
|
22606
|
-
${
|
|
23855
|
+
${signedCommitInstructions}
|
|
22607
23856
|
`;
|
|
22608
23857
|
}
|
|
22609
23858
|
async getCurrentGitBranch() {
|
|
@@ -23059,8 +24308,8 @@ ${attributionInstructions}
|
|
|
23059
24308
|
options: params.options,
|
|
23060
24309
|
toolCall: params.toolCall
|
|
23061
24310
|
});
|
|
23062
|
-
return new Promise((
|
|
23063
|
-
this.pendingPermissions.set(requestId, { resolve:
|
|
24311
|
+
return new Promise((resolve8) => {
|
|
24312
|
+
this.pendingPermissions.set(requestId, { resolve: resolve8 });
|
|
23064
24313
|
});
|
|
23065
24314
|
}
|
|
23066
24315
|
resolvePermission(requestId, optionId, customInput, answers) {
|
|
@@ -23193,4 +24442,17 @@ ${errors}`);
|
|
|
23193
24442
|
await server.start();
|
|
23194
24443
|
});
|
|
23195
24444
|
program.parse();
|
|
24445
|
+
/*! Bundled license information:
|
|
24446
|
+
|
|
24447
|
+
git-url-parse/lib/index.js:
|
|
24448
|
+
(*!
|
|
24449
|
+
* buildToken
|
|
24450
|
+
* Builds OAuth token prefix (helper function)
|
|
24451
|
+
*
|
|
24452
|
+
* @name buildToken
|
|
24453
|
+
* @function
|
|
24454
|
+
* @param {GitUrl} obj The parsed Git url object.
|
|
24455
|
+
* @return {String} token prefix
|
|
24456
|
+
*)
|
|
24457
|
+
*/
|
|
23196
24458
|
//# sourceMappingURL=bin.cjs.map
|