@posthog/agent 2.3.647 → 2.3.656
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.d.ts +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +1637 -342
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +1553 -261
- package/dist/server/bin.cjs.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- 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.configure-environment.test.ts +64 -1
- package/src/server/agent-server.test.ts +2 -4
- package/src/server/agent-server.ts +60 -35
- package/src/types.ts +2 -1
- package/src/utils/common.ts +14 -0
- package/src/utils/gateway.test.ts +70 -0
- package/src/utils/gateway.ts +31 -1
|
@@ -513,7 +513,7 @@ var require_has_flag = __commonJS({
|
|
|
513
513
|
var require_supports_color = __commonJS({
|
|
514
514
|
"../../node_modules/supports-color/index.js"(exports2, module2) {
|
|
515
515
|
"use strict";
|
|
516
|
-
var
|
|
516
|
+
var os9 = __require("os");
|
|
517
517
|
var tty = __require("tty");
|
|
518
518
|
var hasFlag = require_has_flag();
|
|
519
519
|
var { env } = process;
|
|
@@ -561,7 +561,7 @@ var require_supports_color = __commonJS({
|
|
|
561
561
|
return min;
|
|
562
562
|
}
|
|
563
563
|
if (process.platform === "win32") {
|
|
564
|
-
const osRelease =
|
|
564
|
+
const osRelease = os9.release().split(".");
|
|
565
565
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
566
566
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
567
567
|
}
|
|
@@ -809,10 +809,10 @@ var require_src2 = __commonJS({
|
|
|
809
809
|
var fs_1 = __require("fs");
|
|
810
810
|
var debug_1 = __importDefault(require_src());
|
|
811
811
|
var log = debug_1.default("@kwsites/file-exists");
|
|
812
|
-
function check(
|
|
813
|
-
log(`checking %s`,
|
|
812
|
+
function check(path18, isFile2, isDirectory) {
|
|
813
|
+
log(`checking %s`, path18);
|
|
814
814
|
try {
|
|
815
|
-
const stat4 = fs_1.statSync(
|
|
815
|
+
const stat4 = fs_1.statSync(path18);
|
|
816
816
|
if (stat4.isFile() && isFile2) {
|
|
817
817
|
log(`[OK] path represents a file`);
|
|
818
818
|
return true;
|
|
@@ -832,8 +832,8 @@ var require_src2 = __commonJS({
|
|
|
832
832
|
throw e;
|
|
833
833
|
}
|
|
834
834
|
}
|
|
835
|
-
function exists2(
|
|
836
|
-
return check(
|
|
835
|
+
function exists2(path18, type = exports2.READABLE) {
|
|
836
|
+
return check(path18, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
|
|
837
837
|
}
|
|
838
838
|
exports2.exists = exists2;
|
|
839
839
|
exports2.FILE = 1;
|
|
@@ -929,11 +929,11 @@ var require_tree_sitter = __commonJS({
|
|
|
929
929
|
throw toThrow;
|
|
930
930
|
};
|
|
931
931
|
var scriptDirectory = "";
|
|
932
|
-
function locateFile(
|
|
932
|
+
function locateFile(path18) {
|
|
933
933
|
if (Module["locateFile"]) {
|
|
934
|
-
return Module["locateFile"](
|
|
934
|
+
return Module["locateFile"](path18, scriptDirectory);
|
|
935
935
|
}
|
|
936
|
-
return scriptDirectory +
|
|
936
|
+
return scriptDirectory + path18;
|
|
937
937
|
}
|
|
938
938
|
var readAsync, readBinary;
|
|
939
939
|
if (ENVIRONMENT_IS_NODE) {
|
|
@@ -947,10 +947,10 @@ var require_tree_sitter = __commonJS({
|
|
|
947
947
|
};
|
|
948
948
|
readAsync = (filename, binary2 = true) => {
|
|
949
949
|
filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
|
|
950
|
-
return new Promise((
|
|
950
|
+
return new Promise((resolve8, reject) => {
|
|
951
951
|
fs.readFile(filename, binary2 ? void 0 : "utf8", (err2, data) => {
|
|
952
952
|
if (err2) reject(err2);
|
|
953
|
-
else
|
|
953
|
+
else resolve8(binary2 ? data.buffer : data);
|
|
954
954
|
});
|
|
955
955
|
});
|
|
956
956
|
};
|
|
@@ -991,13 +991,13 @@ var require_tree_sitter = __commonJS({
|
|
|
991
991
|
}
|
|
992
992
|
readAsync = (url) => {
|
|
993
993
|
if (isFileURI(url)) {
|
|
994
|
-
return new Promise((reject,
|
|
994
|
+
return new Promise((reject, resolve8) => {
|
|
995
995
|
var xhr = new XMLHttpRequest();
|
|
996
996
|
xhr.open("GET", url, true);
|
|
997
997
|
xhr.responseType = "arraybuffer";
|
|
998
998
|
xhr.onload = () => {
|
|
999
999
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
1000
|
-
|
|
1000
|
+
resolve8(xhr.response);
|
|
1001
1001
|
}
|
|
1002
1002
|
reject(xhr.status);
|
|
1003
1003
|
};
|
|
@@ -1957,8 +1957,8 @@ var require_tree_sitter = __commonJS({
|
|
|
1957
1957
|
}
|
|
1958
1958
|
var libFile = locateFile(libName2);
|
|
1959
1959
|
if (flags2.loadAsync) {
|
|
1960
|
-
return new Promise(function(
|
|
1961
|
-
asyncLoad(libFile,
|
|
1960
|
+
return new Promise(function(resolve8, reject) {
|
|
1961
|
+
asyncLoad(libFile, resolve8, reject);
|
|
1962
1962
|
});
|
|
1963
1963
|
}
|
|
1964
1964
|
if (!readBinary) {
|
|
@@ -3454,8 +3454,8 @@ var require_tree_sitter = __commonJS({
|
|
|
3454
3454
|
} else {
|
|
3455
3455
|
const url = input;
|
|
3456
3456
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
3457
|
-
const
|
|
3458
|
-
bytes = Promise.resolve(
|
|
3457
|
+
const fs15 = __require("fs");
|
|
3458
|
+
bytes = Promise.resolve(fs15.readFileSync(url));
|
|
3459
3459
|
} else {
|
|
3460
3460
|
bytes = fetch(url).then((response) => response.arrayBuffer().then((buffer) => {
|
|
3461
3461
|
if (response.ok) {
|
|
@@ -3783,9 +3783,653 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
3783
3783
|
}
|
|
3784
3784
|
});
|
|
3785
3785
|
|
|
3786
|
+
// ../../node_modules/protocols/lib/index.js
|
|
3787
|
+
var require_lib = __commonJS({
|
|
3788
|
+
"../../node_modules/protocols/lib/index.js"(exports2, module2) {
|
|
3789
|
+
"use strict";
|
|
3790
|
+
module2.exports = function protocols(input, first2) {
|
|
3791
|
+
if (first2 === true) {
|
|
3792
|
+
first2 = 0;
|
|
3793
|
+
}
|
|
3794
|
+
var prots = "";
|
|
3795
|
+
if (typeof input === "string") {
|
|
3796
|
+
try {
|
|
3797
|
+
prots = new URL(input).protocol;
|
|
3798
|
+
} catch (e) {
|
|
3799
|
+
}
|
|
3800
|
+
} else if (input && input.constructor === URL) {
|
|
3801
|
+
prots = input.protocol;
|
|
3802
|
+
}
|
|
3803
|
+
var splits = prots.split(/\:|\+/).filter(Boolean);
|
|
3804
|
+
if (typeof first2 === "number") {
|
|
3805
|
+
return splits[first2];
|
|
3806
|
+
}
|
|
3807
|
+
return splits;
|
|
3808
|
+
};
|
|
3809
|
+
}
|
|
3810
|
+
});
|
|
3811
|
+
|
|
3812
|
+
// ../../node_modules/parse-path/lib/index.js
|
|
3813
|
+
var require_lib2 = __commonJS({
|
|
3814
|
+
"../../node_modules/parse-path/lib/index.js"(exports2, module2) {
|
|
3815
|
+
"use strict";
|
|
3816
|
+
var protocols = require_lib();
|
|
3817
|
+
function parsePath(url) {
|
|
3818
|
+
var output = {
|
|
3819
|
+
protocols: [],
|
|
3820
|
+
protocol: null,
|
|
3821
|
+
port: null,
|
|
3822
|
+
resource: "",
|
|
3823
|
+
host: "",
|
|
3824
|
+
user: "",
|
|
3825
|
+
password: "",
|
|
3826
|
+
pathname: "",
|
|
3827
|
+
hash: "",
|
|
3828
|
+
search: "",
|
|
3829
|
+
href: url,
|
|
3830
|
+
query: {},
|
|
3831
|
+
parse_failed: false
|
|
3832
|
+
};
|
|
3833
|
+
try {
|
|
3834
|
+
var parsed = new URL(url);
|
|
3835
|
+
output.protocols = protocols(parsed);
|
|
3836
|
+
output.protocol = output.protocols[0];
|
|
3837
|
+
output.port = parsed.port;
|
|
3838
|
+
output.resource = parsed.hostname;
|
|
3839
|
+
output.host = parsed.host;
|
|
3840
|
+
output.user = parsed.username || "";
|
|
3841
|
+
output.password = parsed.password || "";
|
|
3842
|
+
output.pathname = parsed.pathname;
|
|
3843
|
+
output.hash = parsed.hash.slice(1);
|
|
3844
|
+
output.search = parsed.search.slice(1);
|
|
3845
|
+
output.href = parsed.href;
|
|
3846
|
+
output.query = Object.fromEntries(parsed.searchParams);
|
|
3847
|
+
} catch (e) {
|
|
3848
|
+
output.protocols = ["file"];
|
|
3849
|
+
output.protocol = output.protocols[0];
|
|
3850
|
+
output.port = "";
|
|
3851
|
+
output.resource = "";
|
|
3852
|
+
output.user = "";
|
|
3853
|
+
output.pathname = "";
|
|
3854
|
+
output.hash = "";
|
|
3855
|
+
output.search = "";
|
|
3856
|
+
output.href = url;
|
|
3857
|
+
output.query = {};
|
|
3858
|
+
output.parse_failed = true;
|
|
3859
|
+
}
|
|
3860
|
+
return output;
|
|
3861
|
+
}
|
|
3862
|
+
module2.exports = parsePath;
|
|
3863
|
+
}
|
|
3864
|
+
});
|
|
3865
|
+
|
|
3866
|
+
// ../../node_modules/parse-url/dist/index.js
|
|
3867
|
+
var require_dist3 = __commonJS({
|
|
3868
|
+
"../../node_modules/parse-url/dist/index.js"(exports2, module2) {
|
|
3869
|
+
"use strict";
|
|
3870
|
+
var require$$1 = require_lib2();
|
|
3871
|
+
function _interopDefaultLegacy(e) {
|
|
3872
|
+
return e && typeof e === "object" && "default" in e ? e : { "default": e };
|
|
3873
|
+
}
|
|
3874
|
+
var require$$1__default = /* @__PURE__ */ _interopDefaultLegacy(require$$1);
|
|
3875
|
+
function getAugmentedNamespace(n) {
|
|
3876
|
+
if (n.__esModule) return n;
|
|
3877
|
+
var f = n.default;
|
|
3878
|
+
if (typeof f == "function") {
|
|
3879
|
+
var a = function a2() {
|
|
3880
|
+
if (this instanceof a2) {
|
|
3881
|
+
var args2 = [null];
|
|
3882
|
+
args2.push.apply(args2, arguments);
|
|
3883
|
+
var Ctor = Function.bind.apply(f, args2);
|
|
3884
|
+
return new Ctor();
|
|
3885
|
+
}
|
|
3886
|
+
return f.apply(this, arguments);
|
|
3887
|
+
};
|
|
3888
|
+
a.prototype = f.prototype;
|
|
3889
|
+
} else a = {};
|
|
3890
|
+
Object.defineProperty(a, "__esModule", { value: true });
|
|
3891
|
+
Object.keys(n).forEach(function(k) {
|
|
3892
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
3893
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
3894
|
+
enumerable: true,
|
|
3895
|
+
get: function() {
|
|
3896
|
+
return n[k];
|
|
3897
|
+
}
|
|
3898
|
+
});
|
|
3899
|
+
});
|
|
3900
|
+
return a;
|
|
3901
|
+
}
|
|
3902
|
+
var src = {};
|
|
3903
|
+
var DATA_URL_DEFAULT_MIME_TYPE = "text/plain";
|
|
3904
|
+
var DATA_URL_DEFAULT_CHARSET = "us-ascii";
|
|
3905
|
+
var testParameter = (name2, filters) => filters.some((filter) => filter instanceof RegExp ? filter.test(name2) : filter === name2);
|
|
3906
|
+
var normalizeDataURL = (urlString, { stripHash }) => {
|
|
3907
|
+
const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
|
|
3908
|
+
if (!match) {
|
|
3909
|
+
throw new Error(`Invalid URL: ${urlString}`);
|
|
3910
|
+
}
|
|
3911
|
+
let { type, data, hash } = match.groups;
|
|
3912
|
+
const mediaType = type.split(";");
|
|
3913
|
+
hash = stripHash ? "" : hash;
|
|
3914
|
+
let isBase64 = false;
|
|
3915
|
+
if (mediaType[mediaType.length - 1] === "base64") {
|
|
3916
|
+
mediaType.pop();
|
|
3917
|
+
isBase64 = true;
|
|
3918
|
+
}
|
|
3919
|
+
const mimeType = (mediaType.shift() || "").toLowerCase();
|
|
3920
|
+
const attributes = mediaType.map((attribute) => {
|
|
3921
|
+
let [key, value = ""] = attribute.split("=").map((string) => string.trim());
|
|
3922
|
+
if (key === "charset") {
|
|
3923
|
+
value = value.toLowerCase();
|
|
3924
|
+
if (value === DATA_URL_DEFAULT_CHARSET) {
|
|
3925
|
+
return "";
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
return `${key}${value ? `=${value}` : ""}`;
|
|
3929
|
+
}).filter(Boolean);
|
|
3930
|
+
const normalizedMediaType = [
|
|
3931
|
+
...attributes
|
|
3932
|
+
];
|
|
3933
|
+
if (isBase64) {
|
|
3934
|
+
normalizedMediaType.push("base64");
|
|
3935
|
+
}
|
|
3936
|
+
if (normalizedMediaType.length > 0 || mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE) {
|
|
3937
|
+
normalizedMediaType.unshift(mimeType);
|
|
3938
|
+
}
|
|
3939
|
+
return `data:${normalizedMediaType.join(";")},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ""}`;
|
|
3940
|
+
};
|
|
3941
|
+
function normalizeUrl(urlString, options) {
|
|
3942
|
+
options = {
|
|
3943
|
+
defaultProtocol: "http:",
|
|
3944
|
+
normalizeProtocol: true,
|
|
3945
|
+
forceHttp: false,
|
|
3946
|
+
forceHttps: false,
|
|
3947
|
+
stripAuthentication: true,
|
|
3948
|
+
stripHash: false,
|
|
3949
|
+
stripTextFragment: true,
|
|
3950
|
+
stripWWW: true,
|
|
3951
|
+
removeQueryParameters: [/^utm_\w+/i],
|
|
3952
|
+
removeTrailingSlash: true,
|
|
3953
|
+
removeSingleSlash: true,
|
|
3954
|
+
removeDirectoryIndex: false,
|
|
3955
|
+
sortQueryParameters: true,
|
|
3956
|
+
...options
|
|
3957
|
+
};
|
|
3958
|
+
urlString = urlString.trim();
|
|
3959
|
+
if (/^data:/i.test(urlString)) {
|
|
3960
|
+
return normalizeDataURL(urlString, options);
|
|
3961
|
+
}
|
|
3962
|
+
if (/^view-source:/i.test(urlString)) {
|
|
3963
|
+
throw new Error("`view-source:` is not supported as it is a non-standard protocol");
|
|
3964
|
+
}
|
|
3965
|
+
const hasRelativeProtocol = urlString.startsWith("//");
|
|
3966
|
+
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
|
|
3967
|
+
if (!isRelativeUrl) {
|
|
3968
|
+
urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
|
|
3969
|
+
}
|
|
3970
|
+
const urlObject = new URL(urlString);
|
|
3971
|
+
if (options.forceHttp && options.forceHttps) {
|
|
3972
|
+
throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");
|
|
3973
|
+
}
|
|
3974
|
+
if (options.forceHttp && urlObject.protocol === "https:") {
|
|
3975
|
+
urlObject.protocol = "http:";
|
|
3976
|
+
}
|
|
3977
|
+
if (options.forceHttps && urlObject.protocol === "http:") {
|
|
3978
|
+
urlObject.protocol = "https:";
|
|
3979
|
+
}
|
|
3980
|
+
if (options.stripAuthentication) {
|
|
3981
|
+
urlObject.username = "";
|
|
3982
|
+
urlObject.password = "";
|
|
3983
|
+
}
|
|
3984
|
+
if (options.stripHash) {
|
|
3985
|
+
urlObject.hash = "";
|
|
3986
|
+
} else if (options.stripTextFragment) {
|
|
3987
|
+
urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, "");
|
|
3988
|
+
}
|
|
3989
|
+
if (urlObject.pathname) {
|
|
3990
|
+
const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
|
|
3991
|
+
let lastIndex = 0;
|
|
3992
|
+
let result = "";
|
|
3993
|
+
for (; ; ) {
|
|
3994
|
+
const match = protocolRegex.exec(urlObject.pathname);
|
|
3995
|
+
if (!match) {
|
|
3996
|
+
break;
|
|
3997
|
+
}
|
|
3998
|
+
const protocol = match[0];
|
|
3999
|
+
const protocolAtIndex = match.index;
|
|
4000
|
+
const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
|
|
4001
|
+
result += intermediate.replace(/\/{2,}/g, "/");
|
|
4002
|
+
result += protocol;
|
|
4003
|
+
lastIndex = protocolAtIndex + protocol.length;
|
|
4004
|
+
}
|
|
4005
|
+
const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
|
|
4006
|
+
result += remnant.replace(/\/{2,}/g, "/");
|
|
4007
|
+
urlObject.pathname = result;
|
|
4008
|
+
}
|
|
4009
|
+
if (urlObject.pathname) {
|
|
4010
|
+
try {
|
|
4011
|
+
urlObject.pathname = decodeURI(urlObject.pathname);
|
|
4012
|
+
} catch {
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
if (options.removeDirectoryIndex === true) {
|
|
4016
|
+
options.removeDirectoryIndex = [/^index\.[a-z]+$/];
|
|
4017
|
+
}
|
|
4018
|
+
if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
|
|
4019
|
+
let pathComponents = urlObject.pathname.split("/");
|
|
4020
|
+
const lastComponent = pathComponents[pathComponents.length - 1];
|
|
4021
|
+
if (testParameter(lastComponent, options.removeDirectoryIndex)) {
|
|
4022
|
+
pathComponents = pathComponents.slice(0, -1);
|
|
4023
|
+
urlObject.pathname = pathComponents.slice(1).join("/") + "/";
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
if (urlObject.hostname) {
|
|
4027
|
+
urlObject.hostname = urlObject.hostname.replace(/\.$/, "");
|
|
4028
|
+
if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) {
|
|
4029
|
+
urlObject.hostname = urlObject.hostname.replace(/^www\./, "");
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
if (Array.isArray(options.removeQueryParameters)) {
|
|
4033
|
+
for (const key of [...urlObject.searchParams.keys()]) {
|
|
4034
|
+
if (testParameter(key, options.removeQueryParameters)) {
|
|
4035
|
+
urlObject.searchParams.delete(key);
|
|
4036
|
+
}
|
|
4037
|
+
}
|
|
4038
|
+
}
|
|
4039
|
+
if (options.removeQueryParameters === true) {
|
|
4040
|
+
urlObject.search = "";
|
|
4041
|
+
}
|
|
4042
|
+
if (options.sortQueryParameters) {
|
|
4043
|
+
urlObject.searchParams.sort();
|
|
4044
|
+
try {
|
|
4045
|
+
urlObject.search = decodeURIComponent(urlObject.search);
|
|
4046
|
+
} catch {
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
if (options.removeTrailingSlash) {
|
|
4050
|
+
urlObject.pathname = urlObject.pathname.replace(/\/$/, "");
|
|
4051
|
+
}
|
|
4052
|
+
const oldUrlString = urlString;
|
|
4053
|
+
urlString = urlObject.toString();
|
|
4054
|
+
if (!options.removeSingleSlash && urlObject.pathname === "/" && !oldUrlString.endsWith("/") && urlObject.hash === "") {
|
|
4055
|
+
urlString = urlString.replace(/\/$/, "");
|
|
4056
|
+
}
|
|
4057
|
+
if ((options.removeTrailingSlash || urlObject.pathname === "/") && urlObject.hash === "" && options.removeSingleSlash) {
|
|
4058
|
+
urlString = urlString.replace(/\/$/, "");
|
|
4059
|
+
}
|
|
4060
|
+
if (hasRelativeProtocol && !options.normalizeProtocol) {
|
|
4061
|
+
urlString = urlString.replace(/^http:\/\//, "//");
|
|
4062
|
+
}
|
|
4063
|
+
if (options.stripProtocol) {
|
|
4064
|
+
urlString = urlString.replace(/^(?:https?:)?\/\//, "");
|
|
4065
|
+
}
|
|
4066
|
+
return urlString;
|
|
4067
|
+
}
|
|
4068
|
+
var normalizeUrl$1 = /* @__PURE__ */ Object.freeze({
|
|
4069
|
+
__proto__: null,
|
|
4070
|
+
"default": normalizeUrl
|
|
4071
|
+
});
|
|
4072
|
+
var require$$0 = /* @__PURE__ */ getAugmentedNamespace(normalizeUrl$1);
|
|
4073
|
+
Object.defineProperty(src, "__esModule", {
|
|
4074
|
+
value: true
|
|
4075
|
+
});
|
|
4076
|
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
|
|
4077
|
+
return typeof obj;
|
|
4078
|
+
} : function(obj) {
|
|
4079
|
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
4080
|
+
};
|
|
4081
|
+
var _normalizeUrl = require$$0;
|
|
4082
|
+
var _normalizeUrl2 = _interopRequireDefault(_normalizeUrl);
|
|
4083
|
+
var _parsePath = require$$1__default["default"];
|
|
4084
|
+
var _parsePath2 = _interopRequireDefault(_parsePath);
|
|
4085
|
+
function _interopRequireDefault(obj) {
|
|
4086
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
4087
|
+
}
|
|
4088
|
+
var parseUrl = function parseUrl2(url) {
|
|
4089
|
+
var normalize3 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
|
|
4090
|
+
var GIT_RE = /^(?:([a-zA-Z_][a-zA-Z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/;
|
|
4091
|
+
var throwErr = function throwErr2(msg) {
|
|
4092
|
+
var err2 = new Error(msg);
|
|
4093
|
+
err2.subject_url = url;
|
|
4094
|
+
throw err2;
|
|
4095
|
+
};
|
|
4096
|
+
if (typeof url !== "string" || !url.trim()) {
|
|
4097
|
+
throwErr("Invalid url.");
|
|
4098
|
+
}
|
|
4099
|
+
if (url.length > parseUrl2.MAX_INPUT_LENGTH) {
|
|
4100
|
+
throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.");
|
|
4101
|
+
}
|
|
4102
|
+
if (normalize3) {
|
|
4103
|
+
if ((typeof normalize3 === "undefined" ? "undefined" : _typeof(normalize3)) !== "object") {
|
|
4104
|
+
normalize3 = {
|
|
4105
|
+
stripHash: false
|
|
4106
|
+
};
|
|
4107
|
+
}
|
|
4108
|
+
url = (0, _normalizeUrl2.default)(url, normalize3);
|
|
4109
|
+
}
|
|
4110
|
+
var parsed = (0, _parsePath2.default)(url);
|
|
4111
|
+
if (parsed.parse_failed) {
|
|
4112
|
+
var matched = parsed.href.match(GIT_RE);
|
|
4113
|
+
if (matched) {
|
|
4114
|
+
parsed.protocols = ["ssh"];
|
|
4115
|
+
parsed.protocol = "ssh";
|
|
4116
|
+
parsed.resource = matched[2];
|
|
4117
|
+
parsed.host = matched[2];
|
|
4118
|
+
parsed.user = matched[1];
|
|
4119
|
+
parsed.pathname = "/" + matched[3];
|
|
4120
|
+
parsed.parse_failed = false;
|
|
4121
|
+
} else {
|
|
4122
|
+
throwErr("URL parsing failed.");
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
return parsed;
|
|
4126
|
+
};
|
|
4127
|
+
parseUrl.MAX_INPUT_LENGTH = 2048;
|
|
4128
|
+
var _default = src.default = parseUrl;
|
|
4129
|
+
module2.exports = _default;
|
|
4130
|
+
}
|
|
4131
|
+
});
|
|
4132
|
+
|
|
4133
|
+
// ../../node_modules/is-ssh/lib/index.js
|
|
4134
|
+
var require_lib3 = __commonJS({
|
|
4135
|
+
"../../node_modules/is-ssh/lib/index.js"(exports2, module2) {
|
|
4136
|
+
"use strict";
|
|
4137
|
+
var protocols = require_lib();
|
|
4138
|
+
function isSsh(input) {
|
|
4139
|
+
if (Array.isArray(input)) {
|
|
4140
|
+
return input.indexOf("ssh") !== -1 || input.indexOf("rsync") !== -1;
|
|
4141
|
+
}
|
|
4142
|
+
if (typeof input !== "string") {
|
|
4143
|
+
return false;
|
|
4144
|
+
}
|
|
4145
|
+
var prots = protocols(input);
|
|
4146
|
+
input = input.substring(input.indexOf("://") + 3);
|
|
4147
|
+
if (isSsh(prots)) {
|
|
4148
|
+
return true;
|
|
4149
|
+
}
|
|
4150
|
+
var urlPortPattern = new RegExp(".([a-zA-Z\\d]+):(\\d+)/");
|
|
4151
|
+
return !input.match(urlPortPattern) && input.indexOf("@") < input.indexOf(":");
|
|
4152
|
+
}
|
|
4153
|
+
module2.exports = isSsh;
|
|
4154
|
+
}
|
|
4155
|
+
});
|
|
4156
|
+
|
|
4157
|
+
// ../../node_modules/git-up/lib/index.js
|
|
4158
|
+
var require_lib4 = __commonJS({
|
|
4159
|
+
"../../node_modules/git-up/lib/index.js"(exports2, module2) {
|
|
4160
|
+
"use strict";
|
|
4161
|
+
var parseUrl = require_dist3();
|
|
4162
|
+
var isSsh = require_lib3();
|
|
4163
|
+
function gitUp(input) {
|
|
4164
|
+
let output = parseUrl(input);
|
|
4165
|
+
output.token = "";
|
|
4166
|
+
if (output.password === "x-oauth-basic") {
|
|
4167
|
+
output.token = output.user;
|
|
4168
|
+
} else if (output.user === "x-token-auth") {
|
|
4169
|
+
output.token = output.password;
|
|
4170
|
+
}
|
|
4171
|
+
if (isSsh(output.protocols) || output.protocols.length === 0 && isSsh(input)) {
|
|
4172
|
+
output.protocol = "ssh";
|
|
4173
|
+
} else if (output.protocols.length) {
|
|
4174
|
+
output.protocol = output.protocols[0];
|
|
4175
|
+
} else {
|
|
4176
|
+
output.protocol = "file";
|
|
4177
|
+
output.protocols = ["file"];
|
|
4178
|
+
}
|
|
4179
|
+
output.href = output.href.replace(/\/$/, "");
|
|
4180
|
+
return output;
|
|
4181
|
+
}
|
|
4182
|
+
module2.exports = gitUp;
|
|
4183
|
+
}
|
|
4184
|
+
});
|
|
4185
|
+
|
|
4186
|
+
// ../../node_modules/git-url-parse/lib/index.js
|
|
4187
|
+
var require_lib5 = __commonJS({
|
|
4188
|
+
"../../node_modules/git-url-parse/lib/index.js"(exports2, module2) {
|
|
4189
|
+
"use strict";
|
|
4190
|
+
var gitUp = require_lib4();
|
|
4191
|
+
function gitUrlParse2(url, refs) {
|
|
4192
|
+
refs = refs || [];
|
|
4193
|
+
if (typeof url !== "string") {
|
|
4194
|
+
throw new Error("The url must be a string.");
|
|
4195
|
+
}
|
|
4196
|
+
if (!refs.every(function(item) {
|
|
4197
|
+
return typeof item === "string";
|
|
4198
|
+
})) {
|
|
4199
|
+
throw new Error("The refs should contain only strings");
|
|
4200
|
+
}
|
|
4201
|
+
var shorthandRe = /^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;
|
|
4202
|
+
if (shorthandRe.test(url)) {
|
|
4203
|
+
url = "https://github.com/" + url;
|
|
4204
|
+
}
|
|
4205
|
+
var urlInfo = gitUp(url), sourceParts = urlInfo.resource.split("."), splits = null;
|
|
4206
|
+
urlInfo.toString = function(type) {
|
|
4207
|
+
return gitUrlParse2.stringify(this, type);
|
|
4208
|
+
};
|
|
4209
|
+
urlInfo.source = sourceParts.length > 2 ? sourceParts.slice(1 - sourceParts.length).join(".") : urlInfo.source = urlInfo.resource;
|
|
4210
|
+
urlInfo.git_suffix = /\.git$/.test(urlInfo.pathname);
|
|
4211
|
+
urlInfo.name = decodeURIComponent((urlInfo.pathname || urlInfo.href).replace(/(^\/)|(\/$)/g, "").replace(/\.git$/, ""));
|
|
4212
|
+
urlInfo.owner = decodeURIComponent(urlInfo.user);
|
|
4213
|
+
switch (urlInfo.source) {
|
|
4214
|
+
case "git.cloudforge.com":
|
|
4215
|
+
urlInfo.owner = urlInfo.user;
|
|
4216
|
+
urlInfo.organization = sourceParts[0];
|
|
4217
|
+
urlInfo.source = "cloudforge.com";
|
|
4218
|
+
break;
|
|
4219
|
+
case "visualstudio.com":
|
|
4220
|
+
if (urlInfo.resource === "vs-ssh.visualstudio.com") {
|
|
4221
|
+
splits = urlInfo.name.split("/");
|
|
4222
|
+
if (splits.length === 4) {
|
|
4223
|
+
urlInfo.organization = splits[1];
|
|
4224
|
+
urlInfo.owner = splits[2];
|
|
4225
|
+
urlInfo.name = splits[3];
|
|
4226
|
+
urlInfo.full_name = splits[2] + "/" + splits[3];
|
|
4227
|
+
}
|
|
4228
|
+
break;
|
|
4229
|
+
} else {
|
|
4230
|
+
splits = urlInfo.name.split("/");
|
|
4231
|
+
if (splits.length === 2) {
|
|
4232
|
+
urlInfo.owner = splits[1];
|
|
4233
|
+
urlInfo.name = splits[1];
|
|
4234
|
+
urlInfo.full_name = "_git/" + urlInfo.name;
|
|
4235
|
+
} else if (splits.length === 3) {
|
|
4236
|
+
urlInfo.name = splits[2];
|
|
4237
|
+
if (splits[0] === "DefaultCollection") {
|
|
4238
|
+
urlInfo.owner = splits[2];
|
|
4239
|
+
urlInfo.organization = splits[0];
|
|
4240
|
+
urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
|
|
4241
|
+
} else {
|
|
4242
|
+
urlInfo.owner = splits[0];
|
|
4243
|
+
urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4244
|
+
}
|
|
4245
|
+
} else if (splits.length === 4) {
|
|
4246
|
+
urlInfo.organization = splits[0];
|
|
4247
|
+
urlInfo.owner = splits[1];
|
|
4248
|
+
urlInfo.name = splits[3];
|
|
4249
|
+
urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4250
|
+
}
|
|
4251
|
+
break;
|
|
4252
|
+
}
|
|
4253
|
+
// Azure DevOps (formerly Visual Studio Team Services)
|
|
4254
|
+
case "dev.azure.com":
|
|
4255
|
+
case "azure.com":
|
|
4256
|
+
if (urlInfo.resource === "ssh.dev.azure.com") {
|
|
4257
|
+
splits = urlInfo.name.split("/");
|
|
4258
|
+
if (splits.length === 4) {
|
|
4259
|
+
urlInfo.organization = splits[1];
|
|
4260
|
+
urlInfo.owner = splits[2];
|
|
4261
|
+
urlInfo.name = splits[3];
|
|
4262
|
+
}
|
|
4263
|
+
break;
|
|
4264
|
+
} else {
|
|
4265
|
+
splits = urlInfo.name.split("/");
|
|
4266
|
+
if (splits.length === 5) {
|
|
4267
|
+
urlInfo.organization = splits[0];
|
|
4268
|
+
urlInfo.owner = splits[1];
|
|
4269
|
+
urlInfo.name = splits[4];
|
|
4270
|
+
urlInfo.full_name = "_git/" + urlInfo.name;
|
|
4271
|
+
} else if (splits.length === 3) {
|
|
4272
|
+
urlInfo.name = splits[2];
|
|
4273
|
+
if (splits[0] === "DefaultCollection") {
|
|
4274
|
+
urlInfo.owner = splits[2];
|
|
4275
|
+
urlInfo.organization = splits[0];
|
|
4276
|
+
urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
|
|
4277
|
+
} else {
|
|
4278
|
+
urlInfo.owner = splits[0];
|
|
4279
|
+
urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4280
|
+
}
|
|
4281
|
+
} else if (splits.length === 4) {
|
|
4282
|
+
urlInfo.organization = splits[0];
|
|
4283
|
+
urlInfo.owner = splits[1];
|
|
4284
|
+
urlInfo.name = splits[3];
|
|
4285
|
+
urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
|
|
4286
|
+
}
|
|
4287
|
+
if (urlInfo.query && urlInfo.query["path"]) {
|
|
4288
|
+
urlInfo.filepath = urlInfo.query["path"].replace(/^\/+/g, "");
|
|
4289
|
+
}
|
|
4290
|
+
if (urlInfo.query && urlInfo.query["version"]) {
|
|
4291
|
+
urlInfo.ref = urlInfo.query["version"].replace(/^GB/, "");
|
|
4292
|
+
}
|
|
4293
|
+
break;
|
|
4294
|
+
}
|
|
4295
|
+
default:
|
|
4296
|
+
splits = urlInfo.name.split("/");
|
|
4297
|
+
var nameIndex = splits.length - 1;
|
|
4298
|
+
if (splits.length >= 2) {
|
|
4299
|
+
var dashIndex = splits.indexOf("-", 2);
|
|
4300
|
+
var blobIndex = splits.indexOf("blob", 2);
|
|
4301
|
+
var treeIndex = splits.indexOf("tree", 2);
|
|
4302
|
+
var commitIndex = splits.indexOf("commit", 2);
|
|
4303
|
+
var issuesIndex = splits.indexOf("issues", 2);
|
|
4304
|
+
var srcIndex = splits.indexOf("src", 2);
|
|
4305
|
+
var rawIndex = splits.indexOf("raw", 2);
|
|
4306
|
+
var editIndex = splits.indexOf("edit", 2);
|
|
4307
|
+
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;
|
|
4308
|
+
urlInfo.owner = splits.slice(0, nameIndex).join("/");
|
|
4309
|
+
urlInfo.name = splits[nameIndex];
|
|
4310
|
+
if (commitIndex && issuesIndex < 0) {
|
|
4311
|
+
urlInfo.commit = splits[nameIndex + 2];
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
urlInfo.ref = "";
|
|
4315
|
+
urlInfo.filepathtype = "";
|
|
4316
|
+
urlInfo.filepath = "";
|
|
4317
|
+
var offsetNameIndex = splits.length > nameIndex && splits[nameIndex + 1] === "-" ? nameIndex + 1 : nameIndex;
|
|
4318
|
+
if (splits.length > offsetNameIndex + 2 && ["raw", "src", "blob", "tree", "edit"].indexOf(splits[offsetNameIndex + 1]) >= 0) {
|
|
4319
|
+
urlInfo.filepathtype = splits[offsetNameIndex + 1];
|
|
4320
|
+
urlInfo.ref = splits[offsetNameIndex + 2];
|
|
4321
|
+
if (splits.length > offsetNameIndex + 3) {
|
|
4322
|
+
urlInfo.filepath = splits.slice(offsetNameIndex + 3).join("/");
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
urlInfo.organization = urlInfo.owner;
|
|
4326
|
+
break;
|
|
4327
|
+
}
|
|
4328
|
+
if (!urlInfo.full_name) {
|
|
4329
|
+
urlInfo.full_name = urlInfo.owner;
|
|
4330
|
+
if (urlInfo.name) {
|
|
4331
|
+
urlInfo.full_name && (urlInfo.full_name += "/");
|
|
4332
|
+
urlInfo.full_name += urlInfo.name;
|
|
4333
|
+
}
|
|
4334
|
+
}
|
|
4335
|
+
if (urlInfo.owner.startsWith("scm/")) {
|
|
4336
|
+
urlInfo.source = "bitbucket-server";
|
|
4337
|
+
urlInfo.owner = urlInfo.owner.replace("scm/", "");
|
|
4338
|
+
urlInfo.organization = urlInfo.owner;
|
|
4339
|
+
urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
|
|
4340
|
+
}
|
|
4341
|
+
var bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/;
|
|
4342
|
+
var matches = bitbucket.exec(urlInfo.pathname);
|
|
4343
|
+
if (matches != null) {
|
|
4344
|
+
urlInfo.source = "bitbucket-server";
|
|
4345
|
+
if (matches[1] === "users") {
|
|
4346
|
+
urlInfo.owner = "~" + matches[2];
|
|
4347
|
+
} else {
|
|
4348
|
+
urlInfo.owner = matches[2];
|
|
4349
|
+
}
|
|
4350
|
+
urlInfo.organization = urlInfo.owner;
|
|
4351
|
+
urlInfo.name = matches[3];
|
|
4352
|
+
splits = matches[4].split("/");
|
|
4353
|
+
if (splits.length > 1) {
|
|
4354
|
+
if (["raw", "browse"].indexOf(splits[1]) >= 0) {
|
|
4355
|
+
urlInfo.filepathtype = splits[1];
|
|
4356
|
+
if (splits.length > 2) {
|
|
4357
|
+
urlInfo.filepath = splits.slice(2).join("/");
|
|
4358
|
+
}
|
|
4359
|
+
} else if (splits[1] === "commits" && splits.length > 2) {
|
|
4360
|
+
urlInfo.commit = splits[2];
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
|
|
4364
|
+
if (urlInfo.query.at) {
|
|
4365
|
+
urlInfo.ref = urlInfo.query.at;
|
|
4366
|
+
} else {
|
|
4367
|
+
urlInfo.ref = "";
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
if (refs.length !== 0 && urlInfo.ref) {
|
|
4371
|
+
urlInfo.ref = findLongestMatchingSubstring(urlInfo.href, refs) || urlInfo.ref;
|
|
4372
|
+
urlInfo.filepath = urlInfo.href.split(urlInfo.ref + "/")[1];
|
|
4373
|
+
}
|
|
4374
|
+
return urlInfo;
|
|
4375
|
+
}
|
|
4376
|
+
gitUrlParse2.stringify = function(obj, type) {
|
|
4377
|
+
type = type || (obj.protocols && obj.protocols.length ? obj.protocols.join("+") : obj.protocol);
|
|
4378
|
+
var port = obj.port ? ":" + obj.port : "";
|
|
4379
|
+
var user = obj.user || "git";
|
|
4380
|
+
var maybeGitSuffix = obj.git_suffix ? ".git" : "";
|
|
4381
|
+
switch (type) {
|
|
4382
|
+
case "ssh":
|
|
4383
|
+
if (port) return "ssh://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
|
|
4384
|
+
else return user + "@" + obj.resource + ":" + obj.full_name + maybeGitSuffix;
|
|
4385
|
+
case "git+ssh":
|
|
4386
|
+
case "ssh+git":
|
|
4387
|
+
case "ftp":
|
|
4388
|
+
case "ftps":
|
|
4389
|
+
return type + "://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
|
|
4390
|
+
case "http":
|
|
4391
|
+
case "https":
|
|
4392
|
+
var auth = obj.token ? buildToken(obj) : obj.user && (obj.protocols.includes("http") || obj.protocols.includes("https")) ? obj.user + "@" : "";
|
|
4393
|
+
return type + "://" + auth + obj.resource + port + "/" + buildPath(obj) + maybeGitSuffix;
|
|
4394
|
+
default:
|
|
4395
|
+
return obj.href;
|
|
4396
|
+
}
|
|
4397
|
+
};
|
|
4398
|
+
function buildToken(obj) {
|
|
4399
|
+
switch (obj.source) {
|
|
4400
|
+
case "bitbucket.org":
|
|
4401
|
+
return "x-token-auth:" + obj.token + "@";
|
|
4402
|
+
default:
|
|
4403
|
+
return obj.token + "@";
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
function buildPath(obj) {
|
|
4407
|
+
switch (obj.source) {
|
|
4408
|
+
case "bitbucket-server":
|
|
4409
|
+
return "scm/" + obj.full_name;
|
|
4410
|
+
default:
|
|
4411
|
+
var encoded_full_name = obj.full_name.split("/").map(function(x) {
|
|
4412
|
+
return encodeURIComponent(x);
|
|
4413
|
+
}).join("/");
|
|
4414
|
+
return encoded_full_name;
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
function findLongestMatchingSubstring(string, array) {
|
|
4418
|
+
var longestMatch = "";
|
|
4419
|
+
array.forEach(function(item) {
|
|
4420
|
+
if (string.includes(item) && item.length > longestMatch.length) {
|
|
4421
|
+
longestMatch = item;
|
|
4422
|
+
}
|
|
4423
|
+
});
|
|
4424
|
+
return longestMatch;
|
|
4425
|
+
}
|
|
4426
|
+
module2.exports = gitUrlParse2;
|
|
4427
|
+
}
|
|
4428
|
+
});
|
|
4429
|
+
|
|
3786
4430
|
// src/server/agent-server.ts
|
|
3787
|
-
import { mkdir as
|
|
3788
|
-
import { basename as
|
|
4431
|
+
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
4432
|
+
import { basename as basename3, join as join13 } from "path";
|
|
3789
4433
|
import { pathToFileURL } from "url";
|
|
3790
4434
|
import {
|
|
3791
4435
|
ClientSideConnection as ClientSideConnection2,
|
|
@@ -3799,6 +4443,24 @@ import { createReadStream } from "fs";
|
|
|
3799
4443
|
import * as fs3 from "fs/promises";
|
|
3800
4444
|
import * as path2 from "path";
|
|
3801
4445
|
|
|
4446
|
+
// ../git/dist/concurrency.js
|
|
4447
|
+
async function mapWithConcurrency(items, concurrency, mapper, options) {
|
|
4448
|
+
if (items.length === 0)
|
|
4449
|
+
return [];
|
|
4450
|
+
const results = new Array(items.length);
|
|
4451
|
+
let index = 0;
|
|
4452
|
+
const worker = async () => {
|
|
4453
|
+
while (index < items.length) {
|
|
4454
|
+
if (options?.signal?.aborted)
|
|
4455
|
+
return;
|
|
4456
|
+
const i2 = index++;
|
|
4457
|
+
results[i2] = await mapper(items[i2]);
|
|
4458
|
+
}
|
|
4459
|
+
};
|
|
4460
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
4461
|
+
return results;
|
|
4462
|
+
}
|
|
4463
|
+
|
|
3802
4464
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
3803
4465
|
var import_file_exists = __toESM(require_dist(), 1);
|
|
3804
4466
|
var import_debug = __toESM(require_src(), 1);
|
|
@@ -3836,8 +4498,8 @@ function pathspec(...paths) {
|
|
|
3836
4498
|
cache.set(key, paths);
|
|
3837
4499
|
return key;
|
|
3838
4500
|
}
|
|
3839
|
-
function isPathSpec(
|
|
3840
|
-
return
|
|
4501
|
+
function isPathSpec(path18) {
|
|
4502
|
+
return path18 instanceof String && cache.has(path18);
|
|
3841
4503
|
}
|
|
3842
4504
|
function toPaths(pathSpec) {
|
|
3843
4505
|
return cache.get(pathSpec) || [];
|
|
@@ -3926,8 +4588,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
3926
4588
|
function forEachLineWithContent(input, callback) {
|
|
3927
4589
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
3928
4590
|
}
|
|
3929
|
-
function folderExists(
|
|
3930
|
-
return (0, import_file_exists.exists)(
|
|
4591
|
+
function folderExists(path18) {
|
|
4592
|
+
return (0, import_file_exists.exists)(path18, import_file_exists.FOLDER);
|
|
3931
4593
|
}
|
|
3932
4594
|
function append(target, item) {
|
|
3933
4595
|
if (Array.isArray(target)) {
|
|
@@ -4331,8 +4993,8 @@ function checkIsRepoRootTask() {
|
|
|
4331
4993
|
commands,
|
|
4332
4994
|
format: "utf-8",
|
|
4333
4995
|
onError,
|
|
4334
|
-
parser(
|
|
4335
|
-
return /^\.(git)?$/.test(
|
|
4996
|
+
parser(path18) {
|
|
4997
|
+
return /^\.(git)?$/.test(path18.trim());
|
|
4336
4998
|
}
|
|
4337
4999
|
};
|
|
4338
5000
|
}
|
|
@@ -4766,11 +5428,11 @@ function parseGrep(grep) {
|
|
|
4766
5428
|
const paths = /* @__PURE__ */ new Set();
|
|
4767
5429
|
const results = {};
|
|
4768
5430
|
forEachLineWithContent(grep, (input) => {
|
|
4769
|
-
const [
|
|
4770
|
-
paths.add(
|
|
4771
|
-
(results[
|
|
5431
|
+
const [path18, line, preview] = input.split(NULL);
|
|
5432
|
+
paths.add(path18);
|
|
5433
|
+
(results[path18] = results[path18] || []).push({
|
|
4772
5434
|
line: asNumber(line),
|
|
4773
|
-
path:
|
|
5435
|
+
path: path18,
|
|
4774
5436
|
preview
|
|
4775
5437
|
});
|
|
4776
5438
|
});
|
|
@@ -5535,14 +6197,14 @@ var init_hash_object = __esm({
|
|
|
5535
6197
|
init_task();
|
|
5536
6198
|
}
|
|
5537
6199
|
});
|
|
5538
|
-
function parseInit(bare,
|
|
6200
|
+
function parseInit(bare, path18, text2) {
|
|
5539
6201
|
const response = String(text2).trim();
|
|
5540
6202
|
let result;
|
|
5541
6203
|
if (result = initResponseRegex.exec(response)) {
|
|
5542
|
-
return new InitSummary(bare,
|
|
6204
|
+
return new InitSummary(bare, path18, false, result[1]);
|
|
5543
6205
|
}
|
|
5544
6206
|
if (result = reInitResponseRegex.exec(response)) {
|
|
5545
|
-
return new InitSummary(bare,
|
|
6207
|
+
return new InitSummary(bare, path18, true, result[1]);
|
|
5546
6208
|
}
|
|
5547
6209
|
let gitDir = "";
|
|
5548
6210
|
const tokens = response.split(" ");
|
|
@@ -5553,7 +6215,7 @@ function parseInit(bare, path17, text2) {
|
|
|
5553
6215
|
break;
|
|
5554
6216
|
}
|
|
5555
6217
|
}
|
|
5556
|
-
return new InitSummary(bare,
|
|
6218
|
+
return new InitSummary(bare, path18, /^re/i.test(response), gitDir);
|
|
5557
6219
|
}
|
|
5558
6220
|
var InitSummary;
|
|
5559
6221
|
var initResponseRegex;
|
|
@@ -5562,9 +6224,9 @@ var init_InitSummary = __esm({
|
|
|
5562
6224
|
"src/lib/responses/InitSummary.ts"() {
|
|
5563
6225
|
"use strict";
|
|
5564
6226
|
InitSummary = class {
|
|
5565
|
-
constructor(bare,
|
|
6227
|
+
constructor(bare, path18, existing, gitDir) {
|
|
5566
6228
|
this.bare = bare;
|
|
5567
|
-
this.path =
|
|
6229
|
+
this.path = path18;
|
|
5568
6230
|
this.existing = existing;
|
|
5569
6231
|
this.gitDir = gitDir;
|
|
5570
6232
|
}
|
|
@@ -5576,7 +6238,7 @@ var init_InitSummary = __esm({
|
|
|
5576
6238
|
function hasBareCommand(command) {
|
|
5577
6239
|
return command.includes(bareCommand);
|
|
5578
6240
|
}
|
|
5579
|
-
function initTask(bare = false,
|
|
6241
|
+
function initTask(bare = false, path18, customArgs) {
|
|
5580
6242
|
const commands = ["init", ...customArgs];
|
|
5581
6243
|
if (bare && !hasBareCommand(commands)) {
|
|
5582
6244
|
commands.splice(1, 0, bareCommand);
|
|
@@ -5585,7 +6247,7 @@ function initTask(bare = false, path17, customArgs) {
|
|
|
5585
6247
|
commands,
|
|
5586
6248
|
format: "utf-8",
|
|
5587
6249
|
parser(text2) {
|
|
5588
|
-
return parseInit(commands.includes("--bare"),
|
|
6250
|
+
return parseInit(commands.includes("--bare"), path18, text2);
|
|
5589
6251
|
}
|
|
5590
6252
|
};
|
|
5591
6253
|
}
|
|
@@ -6401,12 +7063,12 @@ var init_FileStatusSummary = __esm({
|
|
|
6401
7063
|
"use strict";
|
|
6402
7064
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
6403
7065
|
FileStatusSummary = class {
|
|
6404
|
-
constructor(
|
|
6405
|
-
this.path =
|
|
7066
|
+
constructor(path18, index, working_dir) {
|
|
7067
|
+
this.path = path18;
|
|
6406
7068
|
this.index = index;
|
|
6407
7069
|
this.working_dir = working_dir;
|
|
6408
7070
|
if (index === "R" || working_dir === "R") {
|
|
6409
|
-
const detail = fromPathRegex.exec(
|
|
7071
|
+
const detail = fromPathRegex.exec(path18) || [null, path18, path18];
|
|
6410
7072
|
this.from = detail[2] || "";
|
|
6411
7073
|
this.path = detail[1] || "";
|
|
6412
7074
|
}
|
|
@@ -6437,14 +7099,14 @@ function splitLine(result, lineStr) {
|
|
|
6437
7099
|
default:
|
|
6438
7100
|
return;
|
|
6439
7101
|
}
|
|
6440
|
-
function data(index, workingDir,
|
|
7102
|
+
function data(index, workingDir, path18) {
|
|
6441
7103
|
const raw = `${index}${workingDir}`;
|
|
6442
7104
|
const handler = parsers6.get(raw);
|
|
6443
7105
|
if (handler) {
|
|
6444
|
-
handler(result,
|
|
7106
|
+
handler(result, path18);
|
|
6445
7107
|
}
|
|
6446
7108
|
if (raw !== "##" && raw !== "!!") {
|
|
6447
|
-
result.files.push(new FileStatusSummary(
|
|
7109
|
+
result.files.push(new FileStatusSummary(path18, index, workingDir));
|
|
6448
7110
|
}
|
|
6449
7111
|
}
|
|
6450
7112
|
}
|
|
@@ -6757,9 +7419,9 @@ var init_simple_git_api = __esm({
|
|
|
6757
7419
|
next
|
|
6758
7420
|
);
|
|
6759
7421
|
}
|
|
6760
|
-
hashObject(
|
|
7422
|
+
hashObject(path18, write) {
|
|
6761
7423
|
return this._runTask(
|
|
6762
|
-
hashObjectTask(
|
|
7424
|
+
hashObjectTask(path18, write === true),
|
|
6763
7425
|
trailingFunctionArgument(arguments)
|
|
6764
7426
|
);
|
|
6765
7427
|
}
|
|
@@ -7112,8 +7774,8 @@ var init_branch = __esm({
|
|
|
7112
7774
|
}
|
|
7113
7775
|
});
|
|
7114
7776
|
function toPath(input) {
|
|
7115
|
-
const
|
|
7116
|
-
return
|
|
7777
|
+
const path18 = input.trim().replace(/^["']|["']$/g, "");
|
|
7778
|
+
return path18 && normalize(path18);
|
|
7117
7779
|
}
|
|
7118
7780
|
var parseCheckIgnore;
|
|
7119
7781
|
var init_CheckIgnore = __esm({
|
|
@@ -7427,8 +8089,8 @@ __export(sub_module_exports, {
|
|
|
7427
8089
|
subModuleTask: () => subModuleTask,
|
|
7428
8090
|
updateSubModuleTask: () => updateSubModuleTask
|
|
7429
8091
|
});
|
|
7430
|
-
function addSubModuleTask(repo,
|
|
7431
|
-
return subModuleTask(["add", repo,
|
|
8092
|
+
function addSubModuleTask(repo, path18) {
|
|
8093
|
+
return subModuleTask(["add", repo, path18]);
|
|
7432
8094
|
}
|
|
7433
8095
|
function initSubModuleTask(customArgs) {
|
|
7434
8096
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -7758,8 +8420,8 @@ var require_git = __commonJS2({
|
|
|
7758
8420
|
}
|
|
7759
8421
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
7760
8422
|
};
|
|
7761
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
7762
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
8423
|
+
Git2.prototype.submoduleAdd = function(repo, path18, then) {
|
|
8424
|
+
return this._runTask(addSubModuleTask2(repo, path18), trailingFunctionArgument2(arguments));
|
|
7763
8425
|
};
|
|
7764
8426
|
Git2.prototype.submoduleUpdate = function(args2, then) {
|
|
7765
8427
|
return this._runTask(
|
|
@@ -8420,10 +9082,10 @@ var AsyncReaderWriterLock = class {
|
|
|
8420
9082
|
this.readers++;
|
|
8421
9083
|
return;
|
|
8422
9084
|
}
|
|
8423
|
-
return new Promise((
|
|
9085
|
+
return new Promise((resolve8) => {
|
|
8424
9086
|
this.readQueue.push(() => {
|
|
8425
9087
|
this.readers++;
|
|
8426
|
-
|
|
9088
|
+
resolve8();
|
|
8427
9089
|
});
|
|
8428
9090
|
});
|
|
8429
9091
|
}
|
|
@@ -8437,11 +9099,11 @@ var AsyncReaderWriterLock = class {
|
|
|
8437
9099
|
return;
|
|
8438
9100
|
}
|
|
8439
9101
|
this.writerWaiting = true;
|
|
8440
|
-
return new Promise((
|
|
9102
|
+
return new Promise((resolve8) => {
|
|
8441
9103
|
this.writeQueue.push(() => {
|
|
8442
9104
|
this.writerWaiting = this.writeQueue.length > 0;
|
|
8443
9105
|
this.writer = true;
|
|
8444
|
-
|
|
9106
|
+
resolve8();
|
|
8445
9107
|
});
|
|
8446
9108
|
});
|
|
8447
9109
|
}
|
|
@@ -8648,12 +9310,12 @@ async function inspectGitBusyState(git) {
|
|
|
8648
9310
|
|
|
8649
9311
|
// src/server/agent-server.ts
|
|
8650
9312
|
import { Hono } from "hono";
|
|
8651
|
-
import { z as
|
|
9313
|
+
import { z as z5 } from "zod";
|
|
8652
9314
|
|
|
8653
9315
|
// package.json
|
|
8654
9316
|
var package_default = {
|
|
8655
9317
|
name: "@posthog/agent",
|
|
8656
|
-
version: "2.3.
|
|
9318
|
+
version: "2.3.656",
|
|
8657
9319
|
repository: "https://github.com/PostHog/code",
|
|
8658
9320
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8659
9321
|
exports: {
|
|
@@ -8925,17 +9587,17 @@ var Pushable = class {
|
|
|
8925
9587
|
resolvers = [];
|
|
8926
9588
|
done = false;
|
|
8927
9589
|
push(item) {
|
|
8928
|
-
const
|
|
8929
|
-
if (
|
|
8930
|
-
|
|
9590
|
+
const resolve8 = this.resolvers.shift();
|
|
9591
|
+
if (resolve8) {
|
|
9592
|
+
resolve8({ value: item, done: false });
|
|
8931
9593
|
} else {
|
|
8932
9594
|
this.queue.push(item);
|
|
8933
9595
|
}
|
|
8934
9596
|
}
|
|
8935
9597
|
end() {
|
|
8936
9598
|
this.done = true;
|
|
8937
|
-
for (const
|
|
8938
|
-
|
|
9599
|
+
for (const resolve8 of this.resolvers) {
|
|
9600
|
+
resolve8({ value: void 0, done: true });
|
|
8939
9601
|
}
|
|
8940
9602
|
this.resolvers = [];
|
|
8941
9603
|
}
|
|
@@ -8952,8 +9614,8 @@ var Pushable = class {
|
|
|
8952
9614
|
done: true
|
|
8953
9615
|
});
|
|
8954
9616
|
}
|
|
8955
|
-
return new Promise((
|
|
8956
|
-
this.resolvers.push(
|
|
9617
|
+
return new Promise((resolve8) => {
|
|
9618
|
+
this.resolvers.push(resolve8);
|
|
8957
9619
|
});
|
|
8958
9620
|
}
|
|
8959
9621
|
};
|
|
@@ -9067,20 +9729,20 @@ function nodeReadableToWebReadable(nodeStream) {
|
|
|
9067
9729
|
function nodeWritableToWebWritable(nodeStream) {
|
|
9068
9730
|
return new WritableStream2({
|
|
9069
9731
|
write(chunk) {
|
|
9070
|
-
return new Promise((
|
|
9732
|
+
return new Promise((resolve8, reject) => {
|
|
9071
9733
|
const ok = nodeStream.write(Buffer.from(chunk), (err2) => {
|
|
9072
9734
|
if (err2) reject(err2);
|
|
9073
9735
|
});
|
|
9074
9736
|
if (ok) {
|
|
9075
|
-
|
|
9737
|
+
resolve8();
|
|
9076
9738
|
} else {
|
|
9077
|
-
nodeStream.once("drain",
|
|
9739
|
+
nodeStream.once("drain", resolve8);
|
|
9078
9740
|
}
|
|
9079
9741
|
});
|
|
9080
9742
|
},
|
|
9081
9743
|
close() {
|
|
9082
|
-
return new Promise((
|
|
9083
|
-
nodeStream.end(
|
|
9744
|
+
return new Promise((resolve8) => {
|
|
9745
|
+
nodeStream.end(resolve8);
|
|
9084
9746
|
});
|
|
9085
9747
|
},
|
|
9086
9748
|
abort(reason) {
|
|
@@ -9093,9 +9755,9 @@ function nodeWritableToWebWritable(nodeStream) {
|
|
|
9093
9755
|
|
|
9094
9756
|
// src/adapters/claude/claude-agent.ts
|
|
9095
9757
|
import { randomUUID } from "crypto";
|
|
9096
|
-
import * as
|
|
9097
|
-
import * as
|
|
9098
|
-
import * as
|
|
9758
|
+
import * as fs10 from "fs";
|
|
9759
|
+
import * as os6 from "os";
|
|
9760
|
+
import * as path12 from "path";
|
|
9099
9761
|
import {
|
|
9100
9762
|
RequestError as RequestError2
|
|
9101
9763
|
} from "@agentclientprotocol/sdk";
|
|
@@ -13238,10 +13900,360 @@ async function buildWrapperContext(deps, content, langId, absPath) {
|
|
|
13238
13900
|
return { wrappersByLocalName, namespaceWrappers };
|
|
13239
13901
|
}
|
|
13240
13902
|
|
|
13903
|
+
// ../git/dist/signed-commit.js
|
|
13904
|
+
import * as childProcess3 from "child_process";
|
|
13905
|
+
|
|
13906
|
+
// ../git/dist/gh.js
|
|
13907
|
+
import * as childProcess from "child_process";
|
|
13908
|
+
function execGh(args2, options = {}) {
|
|
13909
|
+
const env = options.env ? { ...process.env, ...options.env } : process.env;
|
|
13910
|
+
return new Promise((resolve8) => {
|
|
13911
|
+
const child = childProcess.execFile("gh", args2, { cwd: options.cwd, env, timeout: options.timeoutMs ?? 0 }, (error, stdout, stderr) => {
|
|
13912
|
+
if (!error) {
|
|
13913
|
+
resolve8({ stdout, stderr, exitCode: 0 });
|
|
13914
|
+
return;
|
|
13915
|
+
}
|
|
13916
|
+
const err2 = error;
|
|
13917
|
+
const timedOut = err2.killed === true && !!options.timeoutMs;
|
|
13918
|
+
const exitCode = typeof err2.code === "number" ? err2.code : err2.code === "ENOENT" ? 127 : 1;
|
|
13919
|
+
resolve8({
|
|
13920
|
+
stdout: stdout ?? err2.stdout ?? "",
|
|
13921
|
+
stderr: stderr ?? err2.stderr ?? "",
|
|
13922
|
+
exitCode,
|
|
13923
|
+
error: timedOut ? `gh timed out after ${options.timeoutMs}ms` : err2.message
|
|
13924
|
+
});
|
|
13925
|
+
});
|
|
13926
|
+
if (options.input !== void 0) {
|
|
13927
|
+
child.stdin?.end(options.input);
|
|
13928
|
+
}
|
|
13929
|
+
});
|
|
13930
|
+
}
|
|
13931
|
+
var TRANSIENT_GH_PATTERNS = [
|
|
13932
|
+
/HTTP 5\d\d/,
|
|
13933
|
+
/HTTP 499/,
|
|
13934
|
+
/\btimed out\b/i,
|
|
13935
|
+
/\bETIMEDOUT\b/,
|
|
13936
|
+
/\bECONNRESET\b/,
|
|
13937
|
+
/\bECONNREFUSED\b/,
|
|
13938
|
+
/\bEAI_AGAIN\b/,
|
|
13939
|
+
/connection reset/i
|
|
13940
|
+
];
|
|
13941
|
+
function isTransientGhFailure(res) {
|
|
13942
|
+
if (res.exitCode === 0) {
|
|
13943
|
+
return false;
|
|
13944
|
+
}
|
|
13945
|
+
const text2 = `${res.stderr} ${res.error ?? ""} ${res.stdout}`;
|
|
13946
|
+
return TRANSIENT_GH_PATTERNS.some((re) => re.test(text2));
|
|
13947
|
+
}
|
|
13948
|
+
var sleep = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
13949
|
+
async function execGhWithRetry(args2, options = {}, retry = {}, exec = execGh) {
|
|
13950
|
+
const maxAttempts = retry.maxAttempts ?? 3;
|
|
13951
|
+
const backoffMs = retry.backoffMs ?? 500;
|
|
13952
|
+
let res = await exec(args2, options);
|
|
13953
|
+
for (let attempt = 2; attempt <= maxAttempts && isTransientGhFailure(res); attempt++) {
|
|
13954
|
+
await sleep(backoffMs * 2 ** (attempt - 2));
|
|
13955
|
+
res = await exec(args2, options);
|
|
13956
|
+
}
|
|
13957
|
+
return res;
|
|
13958
|
+
}
|
|
13959
|
+
|
|
13960
|
+
// ../git/dist/trailers.js
|
|
13961
|
+
function buildPostHogTrailers(taskId) {
|
|
13962
|
+
const trailers = ["Generated-By: PostHog Code"];
|
|
13963
|
+
if (taskId)
|
|
13964
|
+
trailers.push(`Task-Id: ${taskId}`);
|
|
13965
|
+
return trailers;
|
|
13966
|
+
}
|
|
13967
|
+
|
|
13968
|
+
// ../git/dist/utils.js
|
|
13969
|
+
var import_git_url_parse = __toESM(require_lib5(), 1);
|
|
13970
|
+
import * as childProcess2 from "child_process";
|
|
13971
|
+
import * as fs5 from "fs/promises";
|
|
13972
|
+
import * as os from "os";
|
|
13973
|
+
import * as path5 from "path";
|
|
13974
|
+
function parseGithubUrl(url) {
|
|
13975
|
+
if (!url)
|
|
13976
|
+
return null;
|
|
13977
|
+
let parsed;
|
|
13978
|
+
try {
|
|
13979
|
+
parsed = (0, import_git_url_parse.default)(url.trim());
|
|
13980
|
+
} catch {
|
|
13981
|
+
return null;
|
|
13982
|
+
}
|
|
13983
|
+
const resource = parsed.resource.toLowerCase();
|
|
13984
|
+
if (resource !== "github.com" && resource !== "ssh.github.com")
|
|
13985
|
+
return null;
|
|
13986
|
+
const raw = parsed.pathname.split("/");
|
|
13987
|
+
if (raw[0] !== "")
|
|
13988
|
+
return null;
|
|
13989
|
+
const parts2 = raw[raw.length - 1] === "" ? raw.slice(1, -1) : raw.slice(1);
|
|
13990
|
+
if (parts2.length < 2 || parts2.some((p) => p === ""))
|
|
13991
|
+
return null;
|
|
13992
|
+
const [owner, repoRaw, segment, num] = parts2;
|
|
13993
|
+
const repo = repoRaw.replace(/\.git$/, "");
|
|
13994
|
+
if (segment === "issues" || segment === "pull") {
|
|
13995
|
+
const number = Number(num);
|
|
13996
|
+
if (!Number.isInteger(number) || number <= 0)
|
|
13997
|
+
return null;
|
|
13998
|
+
return {
|
|
13999
|
+
kind: segment === "pull" ? "pr" : "issue",
|
|
14000
|
+
owner,
|
|
14001
|
+
repo,
|
|
14002
|
+
number
|
|
14003
|
+
};
|
|
14004
|
+
}
|
|
14005
|
+
return { kind: "repo", owner, repo };
|
|
14006
|
+
}
|
|
14007
|
+
|
|
14008
|
+
// ../git/dist/signed-commit.js
|
|
14009
|
+
var DEFAULT_MAX_PAYLOAD_BYTES = 35 * 1024 * 1024;
|
|
14010
|
+
var MAX_GIT_BUFFER = 256 * 1024 * 1024;
|
|
14011
|
+
var GH_GRAPHQL_TIMEOUT_MS = 3e4;
|
|
14012
|
+
var OversizedFileError = class extends Error {
|
|
14013
|
+
path;
|
|
14014
|
+
bytes;
|
|
14015
|
+
maxBytes;
|
|
14016
|
+
constructor(path18, bytes, maxBytes) {
|
|
14017
|
+
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.`);
|
|
14018
|
+
this.path = path18;
|
|
14019
|
+
this.bytes = bytes;
|
|
14020
|
+
this.maxBytes = maxBytes;
|
|
14021
|
+
this.name = "OversizedFileError";
|
|
14022
|
+
}
|
|
14023
|
+
};
|
|
14024
|
+
function runGit(args2, cwd) {
|
|
14025
|
+
return new Promise((resolve8) => {
|
|
14026
|
+
childProcess3.execFile("git", args2, { cwd, maxBuffer: MAX_GIT_BUFFER, encoding: "buffer" }, (error, stdout, stderr) => {
|
|
14027
|
+
const err2 = error;
|
|
14028
|
+
const exitCode = err2 && typeof err2.code === "number" ? err2.code : err2 ? 1 : 0;
|
|
14029
|
+
resolve8({
|
|
14030
|
+
stdout: stdout ?? Buffer.alloc(0),
|
|
14031
|
+
stderr: (stderr ?? Buffer.alloc(0)).toString("utf8"),
|
|
14032
|
+
exitCode
|
|
14033
|
+
});
|
|
14034
|
+
});
|
|
14035
|
+
});
|
|
14036
|
+
}
|
|
14037
|
+
async function gitText(args2, cwd) {
|
|
14038
|
+
const r = await runGit(args2, cwd);
|
|
14039
|
+
if (r.exitCode !== 0) {
|
|
14040
|
+
throw new Error(`git ${args2.join(" ")} failed: ${r.stderr.trim()}`);
|
|
14041
|
+
}
|
|
14042
|
+
return r.stdout.toString("utf8").trim();
|
|
14043
|
+
}
|
|
14044
|
+
async function resolveRepoNameWithOwner(ctx) {
|
|
14045
|
+
const url = await gitText(["remote", "get-url", "origin"], ctx.cwd);
|
|
14046
|
+
const parsed = parseGithubUrl(url);
|
|
14047
|
+
if (!parsed) {
|
|
14048
|
+
throw new Error(`Could not parse owner/repo from origin remote: ${url}`);
|
|
14049
|
+
}
|
|
14050
|
+
return `${parsed.owner}/${parsed.repo}`;
|
|
14051
|
+
}
|
|
14052
|
+
async function resolveBaseBranch(ctx) {
|
|
14053
|
+
if (ctx.baseBranch)
|
|
14054
|
+
return ctx.baseBranch;
|
|
14055
|
+
const r = await runGit(["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], ctx.cwd);
|
|
14056
|
+
if (r.exitCode !== 0)
|
|
14057
|
+
return null;
|
|
14058
|
+
return r.stdout.toString("utf8").trim().replace(/^origin\//, "") || null;
|
|
14059
|
+
}
|
|
14060
|
+
async function resolveBranchName(ctx, input) {
|
|
14061
|
+
const branch = input.branch ? input.branch.replace(/^refs\/heads\//, "") : await resolveCurrentBranch(ctx);
|
|
14062
|
+
const baseBranch = await resolveBaseBranch(ctx);
|
|
14063
|
+
if (baseBranch && branch === baseBranch) {
|
|
14064
|
+
throw new Error(`Refusing to commit directly to base branch '${baseBranch}'. Pass a 'branch' name prefixed with posthog-code/.`);
|
|
14065
|
+
}
|
|
14066
|
+
return branch;
|
|
14067
|
+
}
|
|
14068
|
+
async function resolveCurrentBranch(ctx) {
|
|
14069
|
+
const current2 = await gitText(["rev-parse", "--abbrev-ref", "HEAD"], ctx.cwd);
|
|
14070
|
+
if (!current2 || current2 === "HEAD") {
|
|
14071
|
+
throw new Error("Detached HEAD \u2014 pass a `branch` to git_signed_commit (e.g. posthog-code/...).");
|
|
14072
|
+
}
|
|
14073
|
+
return current2;
|
|
14074
|
+
}
|
|
14075
|
+
async function remoteTip(ctx, branch) {
|
|
14076
|
+
const out2 = await gitText(["ls-remote", "--heads", "origin", branch], ctx.cwd);
|
|
14077
|
+
if (!out2)
|
|
14078
|
+
return null;
|
|
14079
|
+
return out2.split(" ")[0]?.trim() || null;
|
|
14080
|
+
}
|
|
14081
|
+
async function createRef(ctx, repo, branch, sha) {
|
|
14082
|
+
const res = await execGh([
|
|
14083
|
+
"api",
|
|
14084
|
+
"-X",
|
|
14085
|
+
"POST",
|
|
14086
|
+
`/repos/${repo}/git/refs`,
|
|
14087
|
+
"-f",
|
|
14088
|
+
`ref=refs/heads/${branch}`,
|
|
14089
|
+
"-f",
|
|
14090
|
+
`sha=${sha}`
|
|
14091
|
+
], { cwd: ctx.cwd, env: ghTokenEnv(ctx.token) });
|
|
14092
|
+
if (res.exitCode !== 0) {
|
|
14093
|
+
throw new Error(`Failed to create branch '${branch}': ${res.stderr || res.error}`);
|
|
14094
|
+
}
|
|
14095
|
+
}
|
|
14096
|
+
var GITHUB_TOKEN_ENV_VARS = ["GH_TOKEN", "GITHUB_TOKEN"];
|
|
14097
|
+
function readGithubTokenFromEnv(env = process.env) {
|
|
14098
|
+
for (const name2 of GITHUB_TOKEN_ENV_VARS) {
|
|
14099
|
+
if (env[name2])
|
|
14100
|
+
return env[name2];
|
|
14101
|
+
}
|
|
14102
|
+
return void 0;
|
|
14103
|
+
}
|
|
14104
|
+
function ghTokenEnv(token) {
|
|
14105
|
+
return Object.fromEntries(GITHUB_TOKEN_ENV_VARS.map((name2) => [name2, token]));
|
|
14106
|
+
}
|
|
14107
|
+
var STAGED_READ_CONCURRENCY = 16;
|
|
14108
|
+
async function buildFileChanges(ctx, baseOid) {
|
|
14109
|
+
const diff = await runGit(["diff", "--cached", "-z", "--no-renames", "--name-status", baseOid], ctx.cwd);
|
|
14110
|
+
if (diff.exitCode !== 0) {
|
|
14111
|
+
throw new Error(`git diff --cached failed: ${diff.stderr.trim()}`);
|
|
14112
|
+
}
|
|
14113
|
+
const tokens = diff.stdout.toString("utf8").split("\0").filter(Boolean);
|
|
14114
|
+
const addPaths = [];
|
|
14115
|
+
const deletions = [];
|
|
14116
|
+
for (let i2 = 0; i2 + 1 < tokens.length; i2 += 2) {
|
|
14117
|
+
const path18 = tokens[i2 + 1];
|
|
14118
|
+
if (tokens[i2].startsWith("D")) {
|
|
14119
|
+
deletions.push({ path: path18 });
|
|
14120
|
+
} else {
|
|
14121
|
+
addPaths.push(path18);
|
|
14122
|
+
}
|
|
14123
|
+
}
|
|
14124
|
+
const additions = await mapWithConcurrency(addPaths, STAGED_READ_CONCURRENCY, async (path18) => {
|
|
14125
|
+
const r = await runGit(["show", `:${path18}`], ctx.cwd);
|
|
14126
|
+
if (r.exitCode !== 0) {
|
|
14127
|
+
throw new Error(`Failed to read staged file '${path18}': ${r.stderr.trim()}`);
|
|
14128
|
+
}
|
|
14129
|
+
return { path: path18, contents: r.stdout.toString("base64") };
|
|
14130
|
+
});
|
|
14131
|
+
return { additions, deletions };
|
|
14132
|
+
}
|
|
14133
|
+
function additionBytes(a) {
|
|
14134
|
+
return a.contents.length + a.path.length + 32;
|
|
14135
|
+
}
|
|
14136
|
+
function chunkFileChanges(changes, maxBytes) {
|
|
14137
|
+
for (const a of changes.additions) {
|
|
14138
|
+
const bytes = additionBytes(a);
|
|
14139
|
+
if (bytes > maxBytes)
|
|
14140
|
+
throw new OversizedFileError(a.path, bytes, maxBytes);
|
|
14141
|
+
}
|
|
14142
|
+
if (changes.additions.length === 0) {
|
|
14143
|
+
return [{ additions: [], deletions: changes.deletions }];
|
|
14144
|
+
}
|
|
14145
|
+
const chunks = [];
|
|
14146
|
+
let cur = { additions: [], deletions: [...changes.deletions] };
|
|
14147
|
+
let curBytes = changes.deletions.reduce((n, d) => n + d.path.length + 16, 0);
|
|
14148
|
+
for (const a of changes.additions) {
|
|
14149
|
+
const bytes = additionBytes(a);
|
|
14150
|
+
if (cur.additions.length > 0 && curBytes + bytes > maxBytes) {
|
|
14151
|
+
chunks.push(cur);
|
|
14152
|
+
cur = { additions: [], deletions: [] };
|
|
14153
|
+
curBytes = 0;
|
|
14154
|
+
}
|
|
14155
|
+
cur.additions.push(a);
|
|
14156
|
+
curBytes += bytes;
|
|
14157
|
+
}
|
|
14158
|
+
chunks.push(cur);
|
|
14159
|
+
return chunks;
|
|
14160
|
+
}
|
|
14161
|
+
var CREATE_COMMIT_MUTATION = `mutation($input: CreateCommitOnBranchInput!) {
|
|
14162
|
+
createCommitOnBranch(input: $input) { commit { oid url } }
|
|
14163
|
+
}`;
|
|
14164
|
+
async function createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, changes) {
|
|
14165
|
+
const payload = JSON.stringify({
|
|
14166
|
+
query: CREATE_COMMIT_MUTATION,
|
|
14167
|
+
variables: {
|
|
14168
|
+
input: {
|
|
14169
|
+
branch: { repositoryNameWithOwner: repo, branchName: branch },
|
|
14170
|
+
expectedHeadOid,
|
|
14171
|
+
message: { headline, body: body2 },
|
|
14172
|
+
fileChanges: changes
|
|
14173
|
+
}
|
|
14174
|
+
}
|
|
14175
|
+
});
|
|
14176
|
+
const res = await execGhWithRetry(["api", "graphql", "--input", "-"], {
|
|
14177
|
+
cwd: ctx.cwd,
|
|
14178
|
+
input: payload,
|
|
14179
|
+
env: ghTokenEnv(ctx.token),
|
|
14180
|
+
// Bound each attempt so a stalled connection can't hang the tool forever.
|
|
14181
|
+
timeoutMs: GH_GRAPHQL_TIMEOUT_MS
|
|
14182
|
+
}, { maxAttempts: 3 });
|
|
14183
|
+
if (res.exitCode !== 0) {
|
|
14184
|
+
throw new Error(`createCommitOnBranch failed: ${res.stderr || res.error || res.stdout}`);
|
|
14185
|
+
}
|
|
14186
|
+
let parsed;
|
|
14187
|
+
try {
|
|
14188
|
+
parsed = JSON.parse(res.stdout);
|
|
14189
|
+
} catch {
|
|
14190
|
+
throw new Error(`createCommitOnBranch returned non-JSON: ${res.stdout.slice(0, 500)}`);
|
|
14191
|
+
}
|
|
14192
|
+
if (parsed.errors) {
|
|
14193
|
+
throw new Error(`createCommitOnBranch errors: ${JSON.stringify(parsed.errors)}`);
|
|
14194
|
+
}
|
|
14195
|
+
const commit = parsed.data?.createCommitOnBranch?.commit;
|
|
14196
|
+
if (!commit?.oid) {
|
|
14197
|
+
throw new Error(`createCommitOnBranch returned no commit: ${res.stdout}`);
|
|
14198
|
+
}
|
|
14199
|
+
return commit;
|
|
14200
|
+
}
|
|
14201
|
+
async function syncLocalCheckout(ctx, branch, newOid) {
|
|
14202
|
+
const steps = [
|
|
14203
|
+
["fetch", ["fetch", "--no-tags", "origin", branch]],
|
|
14204
|
+
["update-ref", ["update-ref", `refs/heads/${branch}`, newOid]],
|
|
14205
|
+
["symbolic-ref", ["symbolic-ref", "HEAD", `refs/heads/${branch}`]],
|
|
14206
|
+
["reset", ["reset", "-q"]]
|
|
14207
|
+
];
|
|
14208
|
+
for (const [label, args2] of steps) {
|
|
14209
|
+
const r = await runGit(args2, ctx.cwd);
|
|
14210
|
+
if (r.exitCode !== 0) {
|
|
14211
|
+
process.stderr.write(`[signed-commit] local sync step '${label}' failed after committing ${newOid}: ${r.stderr.trim()}
|
|
14212
|
+
`);
|
|
14213
|
+
}
|
|
14214
|
+
}
|
|
14215
|
+
}
|
|
14216
|
+
async function createSignedCommit(ctx, input) {
|
|
14217
|
+
const [repo, branch] = await Promise.all([
|
|
14218
|
+
resolveRepoNameWithOwner(ctx),
|
|
14219
|
+
resolveBranchName(ctx, input)
|
|
14220
|
+
]);
|
|
14221
|
+
if (input.paths && input.paths.length > 0) {
|
|
14222
|
+
const r = await runGit(["add", "--", ...input.paths], ctx.cwd);
|
|
14223
|
+
if (r.exitCode !== 0) {
|
|
14224
|
+
throw new Error(`git add failed: ${r.stderr.trim()}`);
|
|
14225
|
+
}
|
|
14226
|
+
}
|
|
14227
|
+
let tip = await remoteTip(ctx, branch);
|
|
14228
|
+
if (tip === null) {
|
|
14229
|
+
const baseSha = await gitText(["rev-parse", "HEAD"], ctx.cwd);
|
|
14230
|
+
await createRef(ctx, repo, branch, baseSha);
|
|
14231
|
+
tip = baseSha;
|
|
14232
|
+
} else {
|
|
14233
|
+
await runGit(["fetch", "--no-tags", "origin", branch], ctx.cwd);
|
|
14234
|
+
}
|
|
14235
|
+
const changes = await buildFileChanges(ctx, tip);
|
|
14236
|
+
if (changes.additions.length === 0 && changes.deletions.length === 0) {
|
|
14237
|
+
throw new Error("No staged changes to commit. Stage files with `git add` first (or pass `paths`).");
|
|
14238
|
+
}
|
|
14239
|
+
const chunks = chunkFileChanges(changes, DEFAULT_MAX_PAYLOAD_BYTES);
|
|
14240
|
+
const body2 = [input.body, buildPostHogTrailers(ctx.taskId).join("\n")].filter(Boolean).join("\n\n");
|
|
14241
|
+
const commits = [];
|
|
14242
|
+
let expectedHeadOid = tip;
|
|
14243
|
+
for (let i2 = 0; i2 < chunks.length; i2++) {
|
|
14244
|
+
const headline = chunks.length > 1 ? `${input.message} \u2014 part ${i2 + 1}/${chunks.length}` : input.message;
|
|
14245
|
+
const commit = await createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, chunks[i2]);
|
|
14246
|
+
commits.push({ sha: commit.oid, url: commit.url });
|
|
14247
|
+
expectedHeadOid = commit.oid;
|
|
14248
|
+
}
|
|
14249
|
+
await syncLocalCheckout(ctx, branch, expectedHeadOid);
|
|
14250
|
+
return { branch, commits };
|
|
14251
|
+
}
|
|
14252
|
+
|
|
13241
14253
|
// src/utils/common.ts
|
|
13242
14254
|
async function withTimeout(operation, timeoutMs) {
|
|
13243
14255
|
const timeoutPromise = new Promise(
|
|
13244
|
-
(
|
|
14256
|
+
(resolve8) => setTimeout(() => resolve8({ result: "timeout" }), timeoutMs)
|
|
13245
14257
|
);
|
|
13246
14258
|
const operationPromise = operation.then((value) => ({
|
|
13247
14259
|
result: "success",
|
|
@@ -13251,6 +14263,12 @@ async function withTimeout(operation, timeoutMs) {
|
|
|
13251
14263
|
}
|
|
13252
14264
|
var IS_ROOT = typeof process !== "undefined" && (process.geteuid?.() ?? process.getuid?.()) === 0;
|
|
13253
14265
|
var ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
|
|
14266
|
+
function isCloudRun(meta) {
|
|
14267
|
+
return !!process.env.IS_SANDBOX || !!meta?.taskRunId;
|
|
14268
|
+
}
|
|
14269
|
+
function resolveGithubToken() {
|
|
14270
|
+
return readGithubTokenFromEnv();
|
|
14271
|
+
}
|
|
13254
14272
|
function unreachable(value, logger) {
|
|
13255
14273
|
let valueAsString;
|
|
13256
14274
|
try {
|
|
@@ -13408,8 +14426,82 @@ var BaseAcpAgent = class {
|
|
|
13408
14426
|
}
|
|
13409
14427
|
};
|
|
13410
14428
|
|
|
14429
|
+
// src/adapters/signed-commit-shared.ts
|
|
14430
|
+
import { z } from "zod";
|
|
14431
|
+
|
|
14432
|
+
// src/adapters/local-tools/registry.ts
|
|
14433
|
+
var LOCAL_TOOLS_MCP_NAME = "posthog-local";
|
|
14434
|
+
function defineLocalTool(def) {
|
|
14435
|
+
return def;
|
|
14436
|
+
}
|
|
14437
|
+
function qualifiedLocalToolName(toolName) {
|
|
14438
|
+
return `mcp__${LOCAL_TOOLS_MCP_NAME}__${toolName}`;
|
|
14439
|
+
}
|
|
14440
|
+
|
|
14441
|
+
// src/adapters/signed-commit-shared.ts
|
|
14442
|
+
var SIGNED_COMMIT_TOOL_NAME = "git_signed_commit";
|
|
14443
|
+
var SIGNED_COMMIT_QUALIFIED_TOOL_NAME = qualifiedLocalToolName(
|
|
14444
|
+
SIGNED_COMMIT_TOOL_NAME
|
|
14445
|
+
);
|
|
14446
|
+
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.";
|
|
14447
|
+
var signedCommitToolSchema = {
|
|
14448
|
+
message: z.string().describe("Commit headline (first line)."),
|
|
14449
|
+
body: z.string().optional().describe("Optional extended commit body."),
|
|
14450
|
+
branch: z.string().optional().describe(
|
|
14451
|
+
"Target branch; defaults to the current branch. Use a posthog-code/ prefix for new branches."
|
|
14452
|
+
),
|
|
14453
|
+
paths: z.array(z.string()).optional().describe(
|
|
14454
|
+
"Files to stage before committing; defaults to already-staged files."
|
|
14455
|
+
)
|
|
14456
|
+
};
|
|
14457
|
+
function formatSignedCommitResult(result) {
|
|
14458
|
+
const list = result.commits.map((c) => `- ${c.sha} ${c.url}`).join("\n");
|
|
14459
|
+
return `Created ${result.commits.length} signed commit(s) on ${result.branch}:
|
|
14460
|
+
${list}`;
|
|
14461
|
+
}
|
|
14462
|
+
async function runSignedCommitTool(ctx, args2) {
|
|
14463
|
+
try {
|
|
14464
|
+
const result = await createSignedCommit(ctx, args2);
|
|
14465
|
+
return {
|
|
14466
|
+
content: [{ type: "text", text: formatSignedCommitResult(result) }]
|
|
14467
|
+
};
|
|
14468
|
+
} catch (err2) {
|
|
14469
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
14470
|
+
return {
|
|
14471
|
+
content: [
|
|
14472
|
+
{ type: "text", text: `${SIGNED_COMMIT_TOOL_NAME} failed: ${message}` }
|
|
14473
|
+
],
|
|
14474
|
+
isError: true
|
|
14475
|
+
};
|
|
14476
|
+
}
|
|
14477
|
+
}
|
|
14478
|
+
|
|
14479
|
+
// src/adapters/local-tools/tools/signed-commit.ts
|
|
14480
|
+
var signedCommitTool = defineLocalTool({
|
|
14481
|
+
name: SIGNED_COMMIT_TOOL_NAME,
|
|
14482
|
+
description: SIGNED_COMMIT_TOOL_DESCRIPTION,
|
|
14483
|
+
schema: signedCommitToolSchema,
|
|
14484
|
+
alwaysLoad: true,
|
|
14485
|
+
isEnabled: (ctx, meta) => isCloudRun(meta) && !!ctx.token,
|
|
14486
|
+
handler: (ctx, args2) => runSignedCommitTool(
|
|
14487
|
+
{ cwd: ctx.cwd, token: ctx.token ?? "", taskId: ctx.taskId },
|
|
14488
|
+
args2
|
|
14489
|
+
)
|
|
14490
|
+
});
|
|
14491
|
+
|
|
14492
|
+
// src/adapters/local-tools/index.ts
|
|
14493
|
+
var LOCAL_TOOLS = [signedCommitTool];
|
|
14494
|
+
function enabledLocalTools(ctx, meta) {
|
|
14495
|
+
return LOCAL_TOOLS.filter((t) => t.isEnabled(ctx, meta));
|
|
14496
|
+
}
|
|
14497
|
+
|
|
14498
|
+
// src/adapters/session-meta.ts
|
|
14499
|
+
function resolveTaskId(meta) {
|
|
14500
|
+
return meta?.taskId ?? meta?.persistence?.taskId;
|
|
14501
|
+
}
|
|
14502
|
+
|
|
13411
14503
|
// src/adapters/claude/conversion/acp-to-sdk.ts
|
|
13412
|
-
import * as
|
|
14504
|
+
import * as path6 from "path";
|
|
13413
14505
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13414
14506
|
var PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
|
|
13415
14507
|
var COMMON_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -13439,7 +14531,7 @@ function sdkText(value) {
|
|
|
13439
14531
|
function formatUriAsLink(uri) {
|
|
13440
14532
|
try {
|
|
13441
14533
|
if (uri.startsWith("zed://")) {
|
|
13442
|
-
const name2 =
|
|
14534
|
+
const name2 = path6.basename(uri) || uri;
|
|
13443
14535
|
return `[@${name2}](${uri})`;
|
|
13444
14536
|
}
|
|
13445
14537
|
return uri;
|
|
@@ -13448,7 +14540,7 @@ function formatUriAsLink(uri) {
|
|
|
13448
14540
|
}
|
|
13449
14541
|
}
|
|
13450
14542
|
function readToolGuidanceForPath(filePath) {
|
|
13451
|
-
const ext =
|
|
14543
|
+
const ext = path6.extname(filePath).slice(1).toLowerCase();
|
|
13452
14544
|
if (PDF_EXTENSIONS.has(ext)) {
|
|
13453
14545
|
return 'Optional `pages` string (e.g. "1-5") per Read call instead of loading the entire PDF.';
|
|
13454
14546
|
}
|
|
@@ -13460,7 +14552,7 @@ function readToolGuidanceForPath(filePath) {
|
|
|
13460
14552
|
function workspacePromptFromFileUri(uri) {
|
|
13461
14553
|
try {
|
|
13462
14554
|
const filePath = fileURLToPath2(uri);
|
|
13463
|
-
const name2 =
|
|
14555
|
+
const name2 = path6.basename(filePath) || filePath;
|
|
13464
14556
|
return [
|
|
13465
14557
|
"Attached workspace file \u2014 use Read with required `file_path`:",
|
|
13466
14558
|
`- file_path: ${filePath}`,
|
|
@@ -13586,8 +14678,8 @@ var ToolContentBuilder = class {
|
|
|
13586
14678
|
this.items.push({ type: "content", content: image(data, mimeType, uri) });
|
|
13587
14679
|
return this;
|
|
13588
14680
|
}
|
|
13589
|
-
diff(
|
|
13590
|
-
this.items.push({ type: "diff", path:
|
|
14681
|
+
diff(path18, oldText, newText) {
|
|
14682
|
+
this.items.push({ type: "diff", path: path18, oldText, newText });
|
|
13591
14683
|
return this;
|
|
13592
14684
|
}
|
|
13593
14685
|
build() {
|
|
@@ -13806,6 +14898,60 @@ var createSubagentRewriteHook = (logger, registeredAgents) => async (input, _too
|
|
|
13806
14898
|
}
|
|
13807
14899
|
};
|
|
13808
14900
|
};
|
|
14901
|
+
var GIT_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
14902
|
+
"-C",
|
|
14903
|
+
"-c",
|
|
14904
|
+
"--git-dir",
|
|
14905
|
+
"--work-tree",
|
|
14906
|
+
"--namespace",
|
|
14907
|
+
"--exec-path"
|
|
14908
|
+
]);
|
|
14909
|
+
function gitSubcommand(segment) {
|
|
14910
|
+
const tokens = segment.trim().split(/\s+/).filter(Boolean);
|
|
14911
|
+
if (tokens.length === 0) return null;
|
|
14912
|
+
const head = tokens[0].split("/").pop();
|
|
14913
|
+
if (head !== "git") return null;
|
|
14914
|
+
let skipNext = false;
|
|
14915
|
+
for (const tok of tokens.slice(1)) {
|
|
14916
|
+
if (skipNext) {
|
|
14917
|
+
skipNext = false;
|
|
14918
|
+
continue;
|
|
14919
|
+
}
|
|
14920
|
+
if (GIT_VALUE_FLAGS.has(tok)) {
|
|
14921
|
+
skipNext = true;
|
|
14922
|
+
continue;
|
|
14923
|
+
}
|
|
14924
|
+
if (tok.startsWith("-")) continue;
|
|
14925
|
+
return tok;
|
|
14926
|
+
}
|
|
14927
|
+
return null;
|
|
14928
|
+
}
|
|
14929
|
+
function blocksUnsignedGit(command) {
|
|
14930
|
+
if (!command.includes("git")) return false;
|
|
14931
|
+
return command.split(/&&|\|\||[;\n|]/).some((segment) => {
|
|
14932
|
+
const sub = gitSubcommand(segment);
|
|
14933
|
+
return sub === "commit" || sub === "push";
|
|
14934
|
+
});
|
|
14935
|
+
}
|
|
14936
|
+
var createSignedCommitGuardHook = (logger) => async (input, _toolUseID) => {
|
|
14937
|
+
if (input.hook_event_name !== "PreToolUse") return { continue: true };
|
|
14938
|
+
if (input.tool_name !== "Bash") return { continue: true };
|
|
14939
|
+
const command = input.tool_input?.command;
|
|
14940
|
+
if (!command || !blocksUnsignedGit(command)) {
|
|
14941
|
+
return { continue: true };
|
|
14942
|
+
}
|
|
14943
|
+
logger.info(
|
|
14944
|
+
`[SignedCommitGuard] Blocking unsigned git command: ${command}`
|
|
14945
|
+
);
|
|
14946
|
+
return {
|
|
14947
|
+
continue: true,
|
|
14948
|
+
hookSpecificOutput: {
|
|
14949
|
+
hookEventName: "PreToolUse",
|
|
14950
|
+
permissionDecision: "deny",
|
|
14951
|
+
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.`
|
|
14952
|
+
}
|
|
14953
|
+
};
|
|
14954
|
+
};
|
|
13809
14955
|
var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID) => {
|
|
13810
14956
|
if (input.hook_event_name !== "PreToolUse") {
|
|
13811
14957
|
return { continue: true };
|
|
@@ -13859,8 +15005,8 @@ var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID
|
|
|
13859
15005
|
};
|
|
13860
15006
|
|
|
13861
15007
|
// src/adapters/claude/conversion/tool-use-to-acp.ts
|
|
13862
|
-
import
|
|
13863
|
-
import
|
|
15008
|
+
import fs6 from "fs";
|
|
15009
|
+
import path7 from "path";
|
|
13864
15010
|
|
|
13865
15011
|
// src/adapters/claude/mcp/tool-metadata.ts
|
|
13866
15012
|
var mcpToolMetadataCache = /* @__PURE__ */ new Map();
|
|
@@ -13870,7 +15016,7 @@ function buildToolKey(serverName, toolName) {
|
|
|
13870
15016
|
return `mcp__${serverName}__${toolName}`;
|
|
13871
15017
|
}
|
|
13872
15018
|
function delay2(ms) {
|
|
13873
|
-
return new Promise((
|
|
15019
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
13874
15020
|
}
|
|
13875
15021
|
async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
|
|
13876
15022
|
let retries = 0;
|
|
@@ -13890,14 +15036,14 @@ async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefi
|
|
|
13890
15036
|
continue;
|
|
13891
15037
|
}
|
|
13892
15038
|
let readOnlyCount = 0;
|
|
13893
|
-
for (const
|
|
13894
|
-
const toolKey = buildToolKey(server.name,
|
|
13895
|
-
const readOnly =
|
|
15039
|
+
for (const tool2 of server.tools) {
|
|
15040
|
+
const toolKey = buildToolKey(server.name, tool2.name);
|
|
15041
|
+
const readOnly = tool2.annotations?.readOnly === true;
|
|
13896
15042
|
const existing = mcpToolMetadataCache.get(toolKey);
|
|
13897
15043
|
mcpToolMetadataCache.set(toolKey, {
|
|
13898
15044
|
readOnly,
|
|
13899
|
-
name:
|
|
13900
|
-
description:
|
|
15045
|
+
name: tool2.name,
|
|
15046
|
+
description: tool2.description,
|
|
13901
15047
|
approvalState: existing?.approvalState
|
|
13902
15048
|
});
|
|
13903
15049
|
if (readOnly) readOnlyCount++;
|
|
@@ -13965,10 +15111,10 @@ function stripSystemReminders(value) {
|
|
|
13965
15111
|
}
|
|
13966
15112
|
function toDisplayPath(filePath, cwd) {
|
|
13967
15113
|
if (!cwd) return filePath;
|
|
13968
|
-
const resolvedCwd =
|
|
13969
|
-
const resolvedFile =
|
|
13970
|
-
if (resolvedFile.startsWith(resolvedCwd +
|
|
13971
|
-
return
|
|
15114
|
+
const resolvedCwd = path7.resolve(cwd);
|
|
15115
|
+
const resolvedFile = path7.resolve(filePath);
|
|
15116
|
+
if (resolvedFile.startsWith(resolvedCwd + path7.sep) || resolvedFile === resolvedCwd) {
|
|
15117
|
+
return path7.relative(resolvedCwd, resolvedFile);
|
|
13972
15118
|
}
|
|
13973
15119
|
return filePath;
|
|
13974
15120
|
}
|
|
@@ -14093,7 +15239,7 @@ function toolInfoFromToolUse(toolUse, options) {
|
|
|
14093
15239
|
oldContent = options.cachedFileContent[writeFilePath];
|
|
14094
15240
|
} else {
|
|
14095
15241
|
try {
|
|
14096
|
-
oldContent =
|
|
15242
|
+
oldContent = fs6.readFileSync(writeFilePath, "utf-8");
|
|
14097
15243
|
} catch {
|
|
14098
15244
|
}
|
|
14099
15245
|
}
|
|
@@ -14507,7 +15653,7 @@ function resolveFileContent(filePath, oldText, cachedFileContent) {
|
|
|
14507
15653
|
}
|
|
14508
15654
|
}
|
|
14509
15655
|
try {
|
|
14510
|
-
const content =
|
|
15656
|
+
const content = fs6.readFileSync(filePath, "utf-8");
|
|
14511
15657
|
if (content.includes(oldText)) {
|
|
14512
15658
|
return content;
|
|
14513
15659
|
}
|
|
@@ -15160,20 +16306,45 @@ async function handleUserAssistantMessage(message, context) {
|
|
|
15160
16306
|
return {};
|
|
15161
16307
|
}
|
|
15162
16308
|
|
|
16309
|
+
// src/adapters/claude/mcp/local-tools.ts
|
|
16310
|
+
import {
|
|
16311
|
+
createSdkMcpServer,
|
|
16312
|
+
tool
|
|
16313
|
+
} from "@anthropic-ai/claude-agent-sdk";
|
|
16314
|
+
function createLocalToolsMcpServer(ctx, meta) {
|
|
16315
|
+
const tools = enabledLocalTools(ctx, meta);
|
|
16316
|
+
if (tools.length === 0) {
|
|
16317
|
+
return void 0;
|
|
16318
|
+
}
|
|
16319
|
+
return createSdkMcpServer({
|
|
16320
|
+
name: LOCAL_TOOLS_MCP_NAME,
|
|
16321
|
+
version: "1.0.0",
|
|
16322
|
+
tools: tools.map(
|
|
16323
|
+
(t) => tool(
|
|
16324
|
+
t.name,
|
|
16325
|
+
t.description,
|
|
16326
|
+
t.schema,
|
|
16327
|
+
async (args2) => t.handler(ctx, args2),
|
|
16328
|
+
{ alwaysLoad: t.alwaysLoad ?? false }
|
|
16329
|
+
)
|
|
16330
|
+
)
|
|
16331
|
+
});
|
|
16332
|
+
}
|
|
16333
|
+
|
|
15163
16334
|
// src/adapters/claude/plan/utils.ts
|
|
15164
|
-
import * as
|
|
15165
|
-
import * as
|
|
16335
|
+
import * as os2 from "os";
|
|
16336
|
+
import * as path8 from "path";
|
|
15166
16337
|
function getClaudeConfigDir() {
|
|
15167
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
16338
|
+
return process.env.CLAUDE_CONFIG_DIR || path8.join(os2.homedir(), ".claude");
|
|
15168
16339
|
}
|
|
15169
16340
|
function getClaudePlansDir() {
|
|
15170
|
-
return
|
|
16341
|
+
return path8.join(getClaudeConfigDir(), "plans");
|
|
15171
16342
|
}
|
|
15172
16343
|
function isClaudePlanFilePath(filePath) {
|
|
15173
16344
|
if (!filePath) return false;
|
|
15174
|
-
const resolved =
|
|
15175
|
-
const plansDir =
|
|
15176
|
-
return resolved === plansDir || resolved.startsWith(plansDir +
|
|
16345
|
+
const resolved = path8.resolve(filePath);
|
|
16346
|
+
const plansDir = path8.resolve(getClaudePlansDir());
|
|
16347
|
+
return resolved === plansDir || resolved.startsWith(plansDir + path8.sep);
|
|
15177
16348
|
}
|
|
15178
16349
|
function isPlanReady(plan) {
|
|
15179
16350
|
if (!plan) return false;
|
|
@@ -15204,21 +16375,21 @@ function getLatestAssistantText(notifications) {
|
|
|
15204
16375
|
}
|
|
15205
16376
|
|
|
15206
16377
|
// src/adapters/claude/questions/utils.ts
|
|
15207
|
-
import { z } from "zod";
|
|
16378
|
+
import { z as z2 } from "zod";
|
|
15208
16379
|
var OPTION_PREFIX = "option_";
|
|
15209
|
-
var QuestionOptionSchema =
|
|
15210
|
-
label:
|
|
15211
|
-
description:
|
|
16380
|
+
var QuestionOptionSchema = z2.object({
|
|
16381
|
+
label: z2.string(),
|
|
16382
|
+
description: z2.string().optional()
|
|
15212
16383
|
});
|
|
15213
|
-
var QuestionItemSchema =
|
|
15214
|
-
question:
|
|
15215
|
-
header:
|
|
15216
|
-
options:
|
|
15217
|
-
multiSelect:
|
|
15218
|
-
completed:
|
|
16384
|
+
var QuestionItemSchema = z2.object({
|
|
16385
|
+
question: z2.string(),
|
|
16386
|
+
header: z2.string().optional(),
|
|
16387
|
+
options: z2.array(QuestionOptionSchema),
|
|
16388
|
+
multiSelect: z2.boolean().optional(),
|
|
16389
|
+
completed: z2.boolean().optional()
|
|
15219
16390
|
});
|
|
15220
|
-
var QuestionMetaSchema =
|
|
15221
|
-
questions:
|
|
16391
|
+
var QuestionMetaSchema = z2.object({
|
|
16392
|
+
questions: z2.array(QuestionItemSchema)
|
|
15222
16393
|
});
|
|
15223
16394
|
function normalizeAskUserQuestionInput(input) {
|
|
15224
16395
|
if (input.questions && input.questions.length > 0) {
|
|
@@ -15990,14 +17161,14 @@ function getAvailableSlashCommands(commands) {
|
|
|
15990
17161
|
}
|
|
15991
17162
|
|
|
15992
17163
|
// src/adapters/claude/session/mcp-config.ts
|
|
15993
|
-
import * as
|
|
15994
|
-
import * as
|
|
15995
|
-
import * as
|
|
15996
|
-
function loadUserClaudeJsonMcpServers(cwd, logger, homeDir =
|
|
15997
|
-
const claudeJsonPath =
|
|
17164
|
+
import * as fs7 from "fs";
|
|
17165
|
+
import * as os3 from "os";
|
|
17166
|
+
import * as path9 from "path";
|
|
17167
|
+
function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os3.homedir()) {
|
|
17168
|
+
const claudeJsonPath = path9.join(homeDir, ".claude.json");
|
|
15998
17169
|
let raw;
|
|
15999
17170
|
try {
|
|
16000
|
-
raw =
|
|
17171
|
+
raw = fs7.readFileSync(claudeJsonPath, "utf8");
|
|
16001
17172
|
} catch {
|
|
16002
17173
|
return {};
|
|
16003
17174
|
}
|
|
@@ -16148,9 +17319,9 @@ function resolveModelPreference(preference, options) {
|
|
|
16148
17319
|
|
|
16149
17320
|
// src/adapters/claude/session/options.ts
|
|
16150
17321
|
import { spawn as spawn3 } from "child_process";
|
|
16151
|
-
import * as
|
|
16152
|
-
import * as
|
|
16153
|
-
import * as
|
|
17322
|
+
import * as fs8 from "fs";
|
|
17323
|
+
import * as os4 from "os";
|
|
17324
|
+
import * as path10 from "path";
|
|
16154
17325
|
|
|
16155
17326
|
// src/adapters/claude/session/instructions.ts
|
|
16156
17327
|
var BRANCH_NAMING = `
|
|
@@ -16225,28 +17396,27 @@ ${bedrockFallbackHeader}` : bedrockFallbackHeader;
|
|
|
16225
17396
|
ANTHROPIC_CUSTOM_HEADERS: customHeaders
|
|
16226
17397
|
};
|
|
16227
17398
|
}
|
|
16228
|
-
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents) {
|
|
17399
|
+
function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode) {
|
|
16229
17400
|
const postToolUseHooks = [createPostToolUseHook({ onModeChange })];
|
|
16230
17401
|
if (enrichmentDeps && enrichedReadCache) {
|
|
16231
17402
|
postToolUseHooks.push(
|
|
16232
17403
|
createReadEnrichmentHook(enrichmentDeps, enrichedReadCache)
|
|
16233
17404
|
);
|
|
16234
17405
|
}
|
|
17406
|
+
const preToolUseHooks = [
|
|
17407
|
+
createPreToolUseHook(settingsManager, logger),
|
|
17408
|
+
createSubagentRewriteHook(logger, registeredAgents)
|
|
17409
|
+
];
|
|
17410
|
+
if (cloudMode) {
|
|
17411
|
+
preToolUseHooks.push(createSignedCommitGuardHook(logger));
|
|
17412
|
+
}
|
|
16235
17413
|
return {
|
|
16236
17414
|
...userHooks,
|
|
16237
17415
|
PostToolUse: [
|
|
16238
17416
|
...userHooks?.PostToolUse || [],
|
|
16239
17417
|
{ hooks: postToolUseHooks }
|
|
16240
17418
|
],
|
|
16241
|
-
PreToolUse: [
|
|
16242
|
-
...userHooks?.PreToolUse || [],
|
|
16243
|
-
{
|
|
16244
|
-
hooks: [
|
|
16245
|
-
createPreToolUseHook(settingsManager, logger),
|
|
16246
|
-
createSubagentRewriteHook(logger, registeredAgents)
|
|
16247
|
-
]
|
|
16248
|
-
}
|
|
16249
|
-
]
|
|
17419
|
+
PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }]
|
|
16250
17420
|
};
|
|
16251
17421
|
}
|
|
16252
17422
|
var PH_EXPLORE_AGENT = {
|
|
@@ -16358,12 +17528,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
|
|
|
16358
17528
|
};
|
|
16359
17529
|
}
|
|
16360
17530
|
function ensureLocalSettings(cwd) {
|
|
16361
|
-
const claudeDir =
|
|
16362
|
-
const localSettingsPath =
|
|
17531
|
+
const claudeDir = path10.join(cwd, ".claude");
|
|
17532
|
+
const localSettingsPath = path10.join(claudeDir, "settings.local.json");
|
|
16363
17533
|
try {
|
|
16364
|
-
if (!
|
|
16365
|
-
|
|
16366
|
-
|
|
17534
|
+
if (!fs8.existsSync(localSettingsPath)) {
|
|
17535
|
+
fs8.mkdirSync(claudeDir, { recursive: true });
|
|
17536
|
+
fs8.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
|
|
16367
17537
|
}
|
|
16368
17538
|
} catch {
|
|
16369
17539
|
}
|
|
@@ -16404,7 +17574,8 @@ function buildSessionOptions(params) {
|
|
|
16404
17574
|
params.logger,
|
|
16405
17575
|
params.enrichmentDeps,
|
|
16406
17576
|
params.enrichedReadCache,
|
|
16407
|
-
registeredAgentNames
|
|
17577
|
+
registeredAgentNames,
|
|
17578
|
+
params.cloudMode ?? false
|
|
16408
17579
|
),
|
|
16409
17580
|
outputFormat: params.outputFormat,
|
|
16410
17581
|
abortController: getAbortController(
|
|
@@ -16439,18 +17610,18 @@ function buildSessionOptions(params) {
|
|
|
16439
17610
|
return options;
|
|
16440
17611
|
}
|
|
16441
17612
|
function clearStatsigCache() {
|
|
16442
|
-
const statsigPath =
|
|
16443
|
-
process.env.CLAUDE_CONFIG_DIR ||
|
|
17613
|
+
const statsigPath = path10.join(
|
|
17614
|
+
process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude"),
|
|
16444
17615
|
"statsig"
|
|
16445
17616
|
);
|
|
16446
|
-
|
|
17617
|
+
fs8.rm(statsigPath, { recursive: true, force: true }, () => {
|
|
16447
17618
|
});
|
|
16448
17619
|
}
|
|
16449
17620
|
|
|
16450
17621
|
// src/adapters/claude/session/settings.ts
|
|
16451
|
-
import * as
|
|
16452
|
-
import * as
|
|
16453
|
-
import * as
|
|
17622
|
+
import * as fs9 from "fs";
|
|
17623
|
+
import * as os5 from "os";
|
|
17624
|
+
import * as path11 from "path";
|
|
16454
17625
|
import { minimatch } from "minimatch";
|
|
16455
17626
|
|
|
16456
17627
|
// src/utils/async-mutex.ts
|
|
@@ -16462,8 +17633,8 @@ var AsyncMutex = class {
|
|
|
16462
17633
|
this.locked = true;
|
|
16463
17634
|
return;
|
|
16464
17635
|
}
|
|
16465
|
-
return new Promise((
|
|
16466
|
-
this.queue.push(
|
|
17636
|
+
return new Promise((resolve8) => {
|
|
17637
|
+
this.queue.push(resolve8);
|
|
16467
17638
|
});
|
|
16468
17639
|
}
|
|
16469
17640
|
release() {
|
|
@@ -16531,13 +17702,13 @@ function parseRule(rule) {
|
|
|
16531
17702
|
function normalizePath(filePath, cwd) {
|
|
16532
17703
|
let resolved = filePath;
|
|
16533
17704
|
if (resolved.startsWith("~/")) {
|
|
16534
|
-
resolved =
|
|
17705
|
+
resolved = path11.join(os5.homedir(), resolved.slice(2));
|
|
16535
17706
|
} else if (resolved.startsWith("./")) {
|
|
16536
|
-
resolved =
|
|
16537
|
-
} else if (!
|
|
16538
|
-
resolved =
|
|
17707
|
+
resolved = path11.join(cwd, resolved.slice(2));
|
|
17708
|
+
} else if (!path11.isAbsolute(resolved)) {
|
|
17709
|
+
resolved = path11.join(cwd, resolved);
|
|
16539
17710
|
}
|
|
16540
|
-
return
|
|
17711
|
+
return path11.normalize(resolved).replace(/\\/g, "/");
|
|
16541
17712
|
}
|
|
16542
17713
|
function matchesGlob(pattern, filePath, cwd) {
|
|
16543
17714
|
const normalizedPattern = normalizePath(pattern, cwd);
|
|
@@ -16584,11 +17755,11 @@ function formatRule(rule) {
|
|
|
16584
17755
|
}
|
|
16585
17756
|
async function writeFileAtomic(filePath, data) {
|
|
16586
17757
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
16587
|
-
await
|
|
17758
|
+
await fs9.promises.writeFile(tmpPath, data);
|
|
16588
17759
|
try {
|
|
16589
|
-
await
|
|
17760
|
+
await fs9.promises.rename(tmpPath, filePath);
|
|
16590
17761
|
} catch (error) {
|
|
16591
|
-
await
|
|
17762
|
+
await fs9.promises.rm(tmpPath, { force: true });
|
|
16592
17763
|
throw error;
|
|
16593
17764
|
}
|
|
16594
17765
|
}
|
|
@@ -16597,7 +17768,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16597
17768
|
return {};
|
|
16598
17769
|
}
|
|
16599
17770
|
try {
|
|
16600
|
-
const content = await
|
|
17771
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
16601
17772
|
return JSON.parse(content);
|
|
16602
17773
|
} catch (error) {
|
|
16603
17774
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16612,7 +17783,7 @@ async function loadSettingsFile(filePath) {
|
|
|
16612
17783
|
}
|
|
16613
17784
|
async function readSettingsFileForUpdate(filePath) {
|
|
16614
17785
|
try {
|
|
16615
|
-
const content = await
|
|
17786
|
+
const content = await fs9.promises.readFile(filePath, "utf-8");
|
|
16616
17787
|
return JSON.parse(content);
|
|
16617
17788
|
} catch (error) {
|
|
16618
17789
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -16658,11 +17829,11 @@ var SettingsManager = class {
|
|
|
16658
17829
|
return this.initPromise;
|
|
16659
17830
|
}
|
|
16660
17831
|
getUserSettingsPath() {
|
|
16661
|
-
const configDir = process.env.CLAUDE_CONFIG_DIR ||
|
|
16662
|
-
return
|
|
17832
|
+
const configDir = process.env.CLAUDE_CONFIG_DIR || path11.join(os5.homedir(), ".claude");
|
|
17833
|
+
return path11.join(configDir, "settings.json");
|
|
16663
17834
|
}
|
|
16664
17835
|
getProjectSettingsPath() {
|
|
16665
|
-
return
|
|
17836
|
+
return path11.join(this.cwd, ".claude", "settings.json");
|
|
16666
17837
|
}
|
|
16667
17838
|
/**
|
|
16668
17839
|
* Local settings are anchored to the primary worktree so every worktree of
|
|
@@ -16670,7 +17841,7 @@ var SettingsManager = class {
|
|
|
16670
17841
|
* avoids re-prompting for the same permission in every worktree.
|
|
16671
17842
|
*/
|
|
16672
17843
|
getLocalSettingsPath() {
|
|
16673
|
-
return
|
|
17844
|
+
return path11.join(this.repoRoot, ".claude", "settings.local.json");
|
|
16674
17845
|
}
|
|
16675
17846
|
async loadAllSettings() {
|
|
16676
17847
|
this.repoRoot = await resolveMainRepoPath(this.cwd);
|
|
@@ -16728,8 +17899,8 @@ var SettingsManager = class {
|
|
|
16728
17899
|
merged.model = settings.model;
|
|
16729
17900
|
}
|
|
16730
17901
|
if (settings.posthogApprovedExecTools) {
|
|
16731
|
-
for (const
|
|
16732
|
-
posthogApprovedExecTools.add(
|
|
17902
|
+
for (const tool2 of settings.posthogApprovedExecTools) {
|
|
17903
|
+
posthogApprovedExecTools.add(tool2);
|
|
16733
17904
|
}
|
|
16734
17905
|
}
|
|
16735
17906
|
}
|
|
@@ -16797,7 +17968,7 @@ var SettingsManager = class {
|
|
|
16797
17968
|
}
|
|
16798
17969
|
permissions.allow = Array.from(current2);
|
|
16799
17970
|
const next = { ...existing, permissions };
|
|
16800
|
-
await
|
|
17971
|
+
await fs9.promises.mkdir(path11.dirname(filePath), { recursive: true });
|
|
16801
17972
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16802
17973
|
`);
|
|
16803
17974
|
this.localSettings = next;
|
|
@@ -16830,7 +18001,7 @@ var SettingsManager = class {
|
|
|
16830
18001
|
...existing,
|
|
16831
18002
|
posthogApprovedExecTools: Array.from(current2)
|
|
16832
18003
|
};
|
|
16833
|
-
await
|
|
18004
|
+
await fs9.promises.mkdir(path11.dirname(filePath), { recursive: true });
|
|
16834
18005
|
await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
|
|
16835
18006
|
`);
|
|
16836
18007
|
this.localSettings = next;
|
|
@@ -16936,7 +18107,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16936
18107
|
};
|
|
16937
18108
|
}
|
|
16938
18109
|
async newSession(params) {
|
|
16939
|
-
if (
|
|
18110
|
+
if (fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json.backup")) && !fs10.existsSync(path12.resolve(os6.homedir(), ".claude.json"))) {
|
|
16940
18111
|
throw RequestError2.authRequired();
|
|
16941
18112
|
}
|
|
16942
18113
|
const response = await this.createSession(params, {
|
|
@@ -17034,8 +18205,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17034
18205
|
if (this.session.promptRunning) {
|
|
17035
18206
|
this.session.input.push(userMessage);
|
|
17036
18207
|
const order = this.session.nextPendingOrder++;
|
|
17037
|
-
const cancelled = await new Promise((
|
|
17038
|
-
this.session.pendingMessages.set(promptUuid, { resolve:
|
|
18208
|
+
const cancelled = await new Promise((resolve8) => {
|
|
18209
|
+
this.session.pendingMessages.set(promptUuid, { resolve: resolve8, order });
|
|
17039
18210
|
});
|
|
17040
18211
|
if (cancelled) {
|
|
17041
18212
|
return { stopReason: "cancelled" };
|
|
@@ -17557,7 +18728,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17557
18728
|
const { resume, forkSession } = creationOpts;
|
|
17558
18729
|
const isResume = !!resume;
|
|
17559
18730
|
const meta = params._meta;
|
|
17560
|
-
const taskId = meta
|
|
18731
|
+
const taskId = resolveTaskId(meta);
|
|
18732
|
+
const cloudRun = isCloudRun(meta);
|
|
17561
18733
|
const effort = meta?.claudeCode?.options?.effort;
|
|
17562
18734
|
let sessionId;
|
|
17563
18735
|
if (forkSession) {
|
|
@@ -17572,6 +18744,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17572
18744
|
await settingsManager.initialize();
|
|
17573
18745
|
const earlyModelId = settingsManager.getSettings().model || meta?.model || "";
|
|
17574
18746
|
const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params) : {};
|
|
18747
|
+
const localToolsServer = createLocalToolsMcpServer(
|
|
18748
|
+
{ cwd, token: resolveGithubToken(), taskId },
|
|
18749
|
+
meta
|
|
18750
|
+
);
|
|
18751
|
+
if (localToolsServer) {
|
|
18752
|
+
mcpServers[LOCAL_TOOLS_MCP_NAME] = localToolsServer;
|
|
18753
|
+
} else if (cloudRun) {
|
|
18754
|
+
this.logger.warn(
|
|
18755
|
+
"Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
|
|
18756
|
+
);
|
|
18757
|
+
}
|
|
17575
18758
|
const systemPrompt = buildSystemPrompt(meta?.systemPrompt);
|
|
17576
18759
|
if (meta?.mcpToolApprovals) {
|
|
17577
18760
|
setMcpToolApprovalStates(meta.mcpToolApprovals);
|
|
@@ -17607,7 +18790,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17607
18790
|
onProcessExited: this.options?.onProcessExited,
|
|
17608
18791
|
effort,
|
|
17609
18792
|
enrichmentDeps: this.enrichment?.deps,
|
|
17610
|
-
enrichedReadCache: this.enrichedReadCache
|
|
18793
|
+
enrichedReadCache: this.enrichedReadCache,
|
|
18794
|
+
cloudMode: cloudRun
|
|
17611
18795
|
});
|
|
17612
18796
|
const abortController = options.abortController;
|
|
17613
18797
|
const q = query({ prompt: input, options });
|
|
@@ -17939,7 +19123,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17939
19123
|
*/
|
|
17940
19124
|
deferBackgroundFetches(q) {
|
|
17941
19125
|
Promise.all([
|
|
17942
|
-
new Promise((
|
|
19126
|
+
new Promise((resolve8) => setTimeout(resolve8, 10)).then(
|
|
17943
19127
|
() => this.sendAvailableCommandsUpdate()
|
|
17944
19128
|
),
|
|
17945
19129
|
fetchMcpToolMetadata(q, this.logger).then(() => {
|
|
@@ -18217,9 +19401,9 @@ function resetUsage(state) {
|
|
|
18217
19401
|
}
|
|
18218
19402
|
|
|
18219
19403
|
// src/adapters/codex/settings.ts
|
|
18220
|
-
import * as
|
|
18221
|
-
import * as
|
|
18222
|
-
import * as
|
|
19404
|
+
import * as fs11 from "fs";
|
|
19405
|
+
import * as os7 from "os";
|
|
19406
|
+
import * as path13 from "path";
|
|
18223
19407
|
var CodexSettingsManager = class {
|
|
18224
19408
|
cwd;
|
|
18225
19409
|
settings = { mcpServerNames: [] };
|
|
@@ -18230,12 +19414,12 @@ var CodexSettingsManager = class {
|
|
|
18230
19414
|
async initialize() {
|
|
18231
19415
|
}
|
|
18232
19416
|
getConfigPath() {
|
|
18233
|
-
return
|
|
19417
|
+
return path13.join(os7.homedir(), ".codex", "config.toml");
|
|
18234
19418
|
}
|
|
18235
19419
|
loadSettings() {
|
|
18236
19420
|
const configPath = this.getConfigPath();
|
|
18237
19421
|
try {
|
|
18238
|
-
const content =
|
|
19422
|
+
const content = fs11.readFileSync(configPath, "utf-8");
|
|
18239
19423
|
this.settings = parseCodexToml(content, this.cwd);
|
|
18240
19424
|
} catch {
|
|
18241
19425
|
this.settings = { mcpServerNames: [] };
|
|
@@ -18293,7 +19477,7 @@ function parseCodexToml(content, cwd) {
|
|
|
18293
19477
|
// src/adapters/codex/spawn.ts
|
|
18294
19478
|
import { spawn as spawn4 } from "child_process";
|
|
18295
19479
|
import { existsSync as existsSync4 } from "fs";
|
|
18296
|
-
import { delimiter, dirname as
|
|
19480
|
+
import { delimiter, dirname as dirname6 } from "path";
|
|
18297
19481
|
function buildConfigArgs(options) {
|
|
18298
19482
|
const args2 = [];
|
|
18299
19483
|
args2.push("-c", `features.remote_models=false`);
|
|
@@ -18344,7 +19528,7 @@ function spawnCodexProcess(options) {
|
|
|
18344
19528
|
}
|
|
18345
19529
|
const { command, args: args2 } = findCodexBinary(options);
|
|
18346
19530
|
if (options.binaryPath && existsSync4(options.binaryPath)) {
|
|
18347
|
-
const binDir =
|
|
19531
|
+
const binDir = dirname6(options.binaryPath);
|
|
18348
19532
|
env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
|
|
18349
19533
|
}
|
|
18350
19534
|
logger.info("Spawning codex-acp process", {
|
|
@@ -18449,8 +19633,7 @@ function getCurrentPermissionMode(currentModeId, fallbackMode) {
|
|
|
18449
19633
|
var STRUCTURED_OUTPUT_INSTRUCTIONS = `
|
|
18450
19634
|
|
|
18451
19635
|
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.`;
|
|
18452
|
-
function
|
|
18453
|
-
const rel = "adapters/codex/structured-output-mcp-server.js";
|
|
19636
|
+
function resolveBundledMcpScript(rel) {
|
|
18454
19637
|
let dir = import.meta.dirname ?? __dirname;
|
|
18455
19638
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
18456
19639
|
const candidate = resolvePath(dir, rel);
|
|
@@ -18462,7 +19645,9 @@ function resolveStructuredOutputMcpScript() {
|
|
|
18462
19645
|
);
|
|
18463
19646
|
}
|
|
18464
19647
|
function buildStructuredOutputMcpServer(jsonSchema) {
|
|
18465
|
-
const scriptPath =
|
|
19648
|
+
const scriptPath = resolveBundledMcpScript(
|
|
19649
|
+
"adapters/codex/structured-output-mcp-server.js"
|
|
19650
|
+
);
|
|
18466
19651
|
const schemaBase64 = Buffer.from(JSON.stringify(jsonSchema)).toString(
|
|
18467
19652
|
"base64"
|
|
18468
19653
|
);
|
|
@@ -18473,6 +19658,30 @@ function buildStructuredOutputMcpServer(jsonSchema) {
|
|
|
18473
19658
|
env: [{ name: "POSTHOG_OUTPUT_SCHEMA", value: schemaBase64 }]
|
|
18474
19659
|
};
|
|
18475
19660
|
}
|
|
19661
|
+
function buildLocalToolsMcpServer(ctx, enabledNames) {
|
|
19662
|
+
const scriptPath = resolveBundledMcpScript(
|
|
19663
|
+
"adapters/codex/local-tools-mcp-server.js"
|
|
19664
|
+
);
|
|
19665
|
+
const ctxBase64 = Buffer.from(JSON.stringify(ctx)).toString("base64");
|
|
19666
|
+
const env = [
|
|
19667
|
+
{ name: "POSTHOG_LOCAL_TOOLS_CTX", value: ctxBase64 },
|
|
19668
|
+
{ name: "POSTHOG_LOCAL_TOOLS_ENABLED", value: enabledNames.join(",") }
|
|
19669
|
+
];
|
|
19670
|
+
if (ctx.token) {
|
|
19671
|
+
env.push(
|
|
19672
|
+
...Object.entries(ghTokenEnv(ctx.token)).map(([name2, value]) => ({
|
|
19673
|
+
name: name2,
|
|
19674
|
+
value
|
|
19675
|
+
}))
|
|
19676
|
+
);
|
|
19677
|
+
}
|
|
19678
|
+
return {
|
|
19679
|
+
name: LOCAL_TOOLS_MCP_NAME,
|
|
19680
|
+
command: process.execPath,
|
|
19681
|
+
args: [scriptPath],
|
|
19682
|
+
env
|
|
19683
|
+
};
|
|
19684
|
+
}
|
|
18476
19685
|
var CodexAcpAgent = class extends BaseAcpAgent {
|
|
18477
19686
|
adapterName = "codex";
|
|
18478
19687
|
codexProcess;
|
|
@@ -18560,14 +19769,17 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18560
19769
|
async newSession(params) {
|
|
18561
19770
|
const meta = params._meta;
|
|
18562
19771
|
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
|
|
18563
|
-
const injectedParams = this.
|
|
19772
|
+
const injectedParams = this.applyLocalTools(
|
|
19773
|
+
this.applyStructuredOutput(params, meta),
|
|
19774
|
+
meta
|
|
19775
|
+
);
|
|
18564
19776
|
const response = await this.codexConnection.newSession(injectedParams);
|
|
18565
19777
|
response.configOptions = normalizeCodexConfigOptions(
|
|
18566
19778
|
response.configOptions
|
|
18567
19779
|
);
|
|
18568
19780
|
this.sessionState = createSessionState(response.sessionId, params.cwd, {
|
|
18569
19781
|
taskRunId: meta?.taskRunId,
|
|
18570
|
-
taskId: meta
|
|
19782
|
+
taskId: resolveTaskId(meta),
|
|
18571
19783
|
modeId: response.modes?.currentModeId ?? "auto",
|
|
18572
19784
|
modelId: response.models?.currentModelId,
|
|
18573
19785
|
permissionMode: requestedPermissionMode
|
|
@@ -18594,7 +19806,10 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18594
19806
|
}
|
|
18595
19807
|
async loadSession(params) {
|
|
18596
19808
|
const meta = params._meta;
|
|
18597
|
-
const injectedParams = this.
|
|
19809
|
+
const injectedParams = this.applyLocalTools(
|
|
19810
|
+
this.applyStructuredOutput(params, meta),
|
|
19811
|
+
meta
|
|
19812
|
+
);
|
|
18598
19813
|
const response = await this.codexConnection.loadSession(injectedParams);
|
|
18599
19814
|
response.configOptions = normalizeCodexConfigOptions(
|
|
18600
19815
|
response.configOptions
|
|
@@ -18605,7 +19820,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18605
19820
|
);
|
|
18606
19821
|
this.sessionState = createSessionState(params.sessionId, params.cwd, {
|
|
18607
19822
|
taskRunId: meta?.taskRunId,
|
|
18608
|
-
taskId: meta
|
|
19823
|
+
taskId: resolveTaskId(meta),
|
|
18609
19824
|
modeId: response.modes?.currentModeId ?? "auto",
|
|
18610
19825
|
permissionMode: currentPermissionMode
|
|
18611
19826
|
});
|
|
@@ -18622,13 +19837,16 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18622
19837
|
}
|
|
18623
19838
|
async unstable_resumeSession(params) {
|
|
18624
19839
|
const meta = params._meta;
|
|
18625
|
-
const injectedParams = this.
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
19840
|
+
const injectedParams = this.applyLocalTools(
|
|
19841
|
+
this.applyStructuredOutput(
|
|
19842
|
+
{
|
|
19843
|
+
sessionId: params.sessionId,
|
|
19844
|
+
cwd: params.cwd,
|
|
19845
|
+
mcpServers: params.mcpServers ?? [],
|
|
19846
|
+
_meta: params._meta
|
|
19847
|
+
},
|
|
19848
|
+
meta
|
|
19849
|
+
),
|
|
18632
19850
|
meta
|
|
18633
19851
|
);
|
|
18634
19852
|
const loadResponse = await this.codexConnection.loadSession(injectedParams);
|
|
@@ -18641,7 +19859,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18641
19859
|
);
|
|
18642
19860
|
this.sessionState = createSessionState(params.sessionId, params.cwd, {
|
|
18643
19861
|
taskRunId: meta?.taskRunId,
|
|
18644
|
-
taskId: meta
|
|
19862
|
+
taskId: resolveTaskId(meta),
|
|
18645
19863
|
modeId: loadResponse.modes?.currentModeId ?? "auto",
|
|
18646
19864
|
permissionMode: currentPermissionMode
|
|
18647
19865
|
});
|
|
@@ -18662,12 +19880,15 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18662
19880
|
}
|
|
18663
19881
|
async unstable_forkSession(params) {
|
|
18664
19882
|
const meta = params._meta;
|
|
18665
|
-
const injectedParams = this.
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
19883
|
+
const injectedParams = this.applyLocalTools(
|
|
19884
|
+
this.applyStructuredOutput(
|
|
19885
|
+
{
|
|
19886
|
+
cwd: params.cwd,
|
|
19887
|
+
mcpServers: params.mcpServers ?? [],
|
|
19888
|
+
_meta: params._meta
|
|
19889
|
+
},
|
|
19890
|
+
meta
|
|
19891
|
+
),
|
|
18671
19892
|
meta
|
|
18672
19893
|
);
|
|
18673
19894
|
const newResponse = await this.codexConnection.newSession(injectedParams);
|
|
@@ -18677,7 +19898,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18677
19898
|
const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
|
|
18678
19899
|
this.sessionState = createSessionState(newResponse.sessionId, params.cwd, {
|
|
18679
19900
|
taskRunId: meta?.taskRunId,
|
|
18680
|
-
taskId: meta
|
|
19901
|
+
taskId: resolveTaskId(meta),
|
|
18681
19902
|
modeId: newResponse.modes?.currentModeId ?? "auto",
|
|
18682
19903
|
permissionMode: requestedPermissionMode
|
|
18683
19904
|
});
|
|
@@ -18714,6 +19935,41 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18714
19935
|
}
|
|
18715
19936
|
};
|
|
18716
19937
|
}
|
|
19938
|
+
/**
|
|
19939
|
+
* Injects the stdio general local-tools MCP server. Tools self-gate via the
|
|
19940
|
+
* registry (e.g. signed-commit is cloud-only and needs a GH token), so the
|
|
19941
|
+
* server is only injected when at least one tool's gate passes. Their
|
|
19942
|
+
* instructions already live in the shared cloud system prompt, so only the
|
|
19943
|
+
* server needs injecting here.
|
|
19944
|
+
*/
|
|
19945
|
+
applyLocalTools(request, meta) {
|
|
19946
|
+
const cwd = request.cwd;
|
|
19947
|
+
if (!cwd) {
|
|
19948
|
+
return request;
|
|
19949
|
+
}
|
|
19950
|
+
const ctx = {
|
|
19951
|
+
cwd,
|
|
19952
|
+
token: resolveGithubToken(),
|
|
19953
|
+
taskId: resolveTaskId(meta)
|
|
19954
|
+
};
|
|
19955
|
+
const tools = enabledLocalTools(ctx, meta);
|
|
19956
|
+
if (tools.length === 0) {
|
|
19957
|
+
if (isCloudRun(meta)) {
|
|
19958
|
+
this.logger.warn(
|
|
19959
|
+
"Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
|
|
19960
|
+
);
|
|
19961
|
+
}
|
|
19962
|
+
return request;
|
|
19963
|
+
}
|
|
19964
|
+
const mcpServer = buildLocalToolsMcpServer(
|
|
19965
|
+
ctx,
|
|
19966
|
+
tools.map((t) => t.name)
|
|
19967
|
+
);
|
|
19968
|
+
return {
|
|
19969
|
+
...request,
|
|
19970
|
+
mcpServers: [...request.mcpServers ?? [], mcpServer]
|
|
19971
|
+
};
|
|
19972
|
+
}
|
|
18717
19973
|
async applyInitialPermissionMode(sessionId, permissionMode, currentModeId) {
|
|
18718
19974
|
if (!permissionMode) {
|
|
18719
19975
|
return;
|
|
@@ -19085,20 +20341,20 @@ function createCodexConnection(config) {
|
|
|
19085
20341
|
}
|
|
19086
20342
|
|
|
19087
20343
|
// src/handoff-checkpoint.ts
|
|
19088
|
-
import { mkdtemp as mkdtemp2, readFile as readFile4, rm as
|
|
20344
|
+
import { mkdtemp as mkdtemp2, readFile as readFile4, rm as rm5, writeFile as writeFile2 } from "fs/promises";
|
|
19089
20345
|
import { tmpdir as tmpdir2 } from "os";
|
|
19090
|
-
import { dirname as
|
|
20346
|
+
import { dirname as dirname7, join as join11 } from "path";
|
|
19091
20347
|
|
|
19092
20348
|
// ../git/dist/handoff.js
|
|
19093
20349
|
import { spawn as spawn5 } from "child_process";
|
|
19094
|
-
import { copyFile, mkdtemp, readFile as readFile3, rm as
|
|
20350
|
+
import { copyFile as copyFile2, mkdtemp, readFile as readFile3, rm as rm4, stat as stat3 } from "fs/promises";
|
|
19095
20351
|
import { tmpdir } from "os";
|
|
19096
|
-
import
|
|
20352
|
+
import path15 from "path";
|
|
19097
20353
|
|
|
19098
20354
|
// ../git/dist/sagas/checkpoint.js
|
|
19099
20355
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
19100
|
-
import * as
|
|
19101
|
-
import * as
|
|
20356
|
+
import * as fs12 from "fs/promises";
|
|
20357
|
+
import * as path14 from "path";
|
|
19102
20358
|
|
|
19103
20359
|
// ../shared/dist/index.js
|
|
19104
20360
|
var CLOUD_PROMPT_PREFIX = "__twig_cloud_prompt_v1__:";
|
|
@@ -19384,7 +20640,7 @@ async function createWorktreeTree(git, baseDir, head) {
|
|
|
19384
20640
|
const treeHash = await tempGit.raw(["write-tree"]);
|
|
19385
20641
|
return treeHash.trim();
|
|
19386
20642
|
} finally {
|
|
19387
|
-
await
|
|
20643
|
+
await fs12.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19388
20644
|
});
|
|
19389
20645
|
}
|
|
19390
20646
|
}
|
|
@@ -19482,7 +20738,7 @@ async function createMetaTree(git, baseDir, indexTree, worktreeTree) {
|
|
|
19482
20738
|
const metaTree = await tempGit.raw(["write-tree"]);
|
|
19483
20739
|
return metaTree.trim();
|
|
19484
20740
|
} finally {
|
|
19485
|
-
await
|
|
20741
|
+
await fs12.rm(tempIndexPath, { force: true }).catch(() => {
|
|
19486
20742
|
});
|
|
19487
20743
|
}
|
|
19488
20744
|
}
|
|
@@ -19499,12 +20755,12 @@ function formatCheckpointMessage(meta) {
|
|
|
19499
20755
|
async function getGitCommonDir(git, baseDir) {
|
|
19500
20756
|
const raw = await git.raw(["rev-parse", "--git-common-dir"]);
|
|
19501
20757
|
const dir = raw.trim() || ".git";
|
|
19502
|
-
return
|
|
20758
|
+
return path14.isAbsolute(dir) ? dir : path14.resolve(baseDir, dir);
|
|
19503
20759
|
}
|
|
19504
20760
|
async function createTempIndexGit(git, baseDir, label) {
|
|
19505
|
-
const tmpDir =
|
|
19506
|
-
await
|
|
19507
|
-
const tempIndexPath =
|
|
20761
|
+
const tmpDir = path14.join(await getGitCommonDir(git, baseDir), "posthog-code-tmp");
|
|
20762
|
+
await fs12.mkdir(tmpDir, { recursive: true });
|
|
20763
|
+
const tempIndexPath = path14.join(tmpDir, `${label}-${Date.now()}-${randomUUID2()}`);
|
|
19508
20764
|
const tempGit = createGitClient(baseDir).env({
|
|
19509
20765
|
...process.env,
|
|
19510
20766
|
GIT_INDEX_FILE: tempIndexPath
|
|
@@ -19559,7 +20815,7 @@ var GitHandoffTracker = class {
|
|
|
19559
20815
|
packBaseline ? `^${packBaseline}` : null
|
|
19560
20816
|
].filter((ref) => !!ref);
|
|
19561
20817
|
const headRef = checkpoint.head ? `${HANDOFF_HEAD_REF_PREFIX}${checkpoint.checkpointId}` : void 0;
|
|
19562
|
-
const packPrefix =
|
|
20818
|
+
const packPrefix = path15.join(tempDir, checkpoint.checkpointId);
|
|
19563
20819
|
const [headPack, indexFile, tracking] = await Promise.all([
|
|
19564
20820
|
this.captureObjectPack(packPrefix, packRefs),
|
|
19565
20821
|
this.statFileArtifact(reconciledIndex.indexFilePath),
|
|
@@ -19628,14 +20884,14 @@ var GitHandoffTracker = class {
|
|
|
19628
20884
|
`);
|
|
19629
20885
|
const packPath = `${packPrefix}-${hash.trim()}.pack`;
|
|
19630
20886
|
const rawBytes = await this.getFileSize(packPath);
|
|
19631
|
-
await
|
|
20887
|
+
await rm4(`${packPath}.idx`, { force: true }).catch(() => {
|
|
19632
20888
|
});
|
|
19633
20889
|
return { path: packPath, rawBytes };
|
|
19634
20890
|
}
|
|
19635
20891
|
async reconcileHandoffIndex(git, head, indexTree, tempDir, checkpointId) {
|
|
19636
20892
|
const realIndexPath = await this.getGitPath(git, "index");
|
|
19637
|
-
const tempIndexPath =
|
|
19638
|
-
await
|
|
20893
|
+
const tempIndexPath = path15.join(tempDir, `${checkpointId}.index`);
|
|
20894
|
+
await copyFile2(realIndexPath, tempIndexPath);
|
|
19639
20895
|
const largePaths = await this.listLargeBlobsInTree(indexTree, MAX_HANDOFF_FILE_BYTES);
|
|
19640
20896
|
if (largePaths.length === 0) {
|
|
19641
20897
|
return { indexTree, indexFilePath: tempIndexPath };
|
|
@@ -19718,7 +20974,7 @@ var GitHandoffTracker = class {
|
|
|
19718
20974
|
}
|
|
19719
20975
|
async restoreIndexFile(git, indexPath) {
|
|
19720
20976
|
const gitIndexPath = await this.getGitPath(git, "index");
|
|
19721
|
-
await
|
|
20977
|
+
await copyFile2(indexPath, gitIndexPath);
|
|
19722
20978
|
}
|
|
19723
20979
|
async unpackPackFile(packPath) {
|
|
19724
20980
|
const content = await readFile3(packPath);
|
|
@@ -19856,7 +21112,7 @@ var GitHandoffTracker = class {
|
|
|
19856
21112
|
async getGitPath(git, gitPath) {
|
|
19857
21113
|
const raw = await git.raw(["rev-parse", "--git-path", gitPath]);
|
|
19858
21114
|
const resolved = raw.trim();
|
|
19859
|
-
return
|
|
21115
|
+
return path15.isAbsolute(resolved) ? resolved : path15.resolve(this.repositoryPath, resolved);
|
|
19860
21116
|
}
|
|
19861
21117
|
async getFileSize(filePath) {
|
|
19862
21118
|
return (await stat3(filePath)).size;
|
|
@@ -19869,7 +21125,7 @@ var GitHandoffTracker = class {
|
|
|
19869
21125
|
await this.runGitProcess(args2, input);
|
|
19870
21126
|
}
|
|
19871
21127
|
async runGitProcessAllowingFailure(args2) {
|
|
19872
|
-
return new Promise((
|
|
21128
|
+
return new Promise((resolve8, reject) => {
|
|
19873
21129
|
const child = spawn5("git", args2, {
|
|
19874
21130
|
cwd: this.repositoryPath,
|
|
19875
21131
|
stdio: ["ignore", "ignore", "pipe"]
|
|
@@ -19888,12 +21144,12 @@ var GitHandoffTracker = class {
|
|
|
19888
21144
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
19889
21145
|
return;
|
|
19890
21146
|
}
|
|
19891
|
-
|
|
21147
|
+
resolve8(code);
|
|
19892
21148
|
});
|
|
19893
21149
|
});
|
|
19894
21150
|
}
|
|
19895
21151
|
async runGitWithEnv(env, args2) {
|
|
19896
|
-
return new Promise((
|
|
21152
|
+
return new Promise((resolve8, reject) => {
|
|
19897
21153
|
const child = spawn5("git", args2, {
|
|
19898
21154
|
cwd: this.repositoryPath,
|
|
19899
21155
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -19910,7 +21166,7 @@ var GitHandoffTracker = class {
|
|
|
19910
21166
|
child.on("error", reject);
|
|
19911
21167
|
child.on("close", (code) => {
|
|
19912
21168
|
if (code === 0) {
|
|
19913
|
-
|
|
21169
|
+
resolve8(stdout);
|
|
19914
21170
|
return;
|
|
19915
21171
|
}
|
|
19916
21172
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
@@ -19918,7 +21174,7 @@ var GitHandoffTracker = class {
|
|
|
19918
21174
|
});
|
|
19919
21175
|
}
|
|
19920
21176
|
runGitProcess(args2, input) {
|
|
19921
|
-
return new Promise((
|
|
21177
|
+
return new Promise((resolve8, reject) => {
|
|
19922
21178
|
const child = spawn5("git", args2, {
|
|
19923
21179
|
cwd: this.repositoryPath,
|
|
19924
21180
|
stdio: "pipe"
|
|
@@ -19934,7 +21190,7 @@ var GitHandoffTracker = class {
|
|
|
19934
21190
|
child.on("error", reject);
|
|
19935
21191
|
child.on("close", (code) => {
|
|
19936
21192
|
if (code === 0) {
|
|
19937
|
-
|
|
21193
|
+
resolve8({ stdout, stderr });
|
|
19938
21194
|
return;
|
|
19939
21195
|
}
|
|
19940
21196
|
reject(new Error(stderr || `git ${args2.join(" ")} failed with code ${code}`));
|
|
@@ -19946,7 +21202,7 @@ var GitHandoffTracker = class {
|
|
|
19946
21202
|
}
|
|
19947
21203
|
};
|
|
19948
21204
|
function joinTempPrefix(checkpointId) {
|
|
19949
|
-
return
|
|
21205
|
+
return path15.join(tmpdir(), `posthog-code-handoff-${checkpointId}-`);
|
|
19950
21206
|
}
|
|
19951
21207
|
async function getCurrentBranchName(git) {
|
|
19952
21208
|
try {
|
|
@@ -20034,10 +21290,10 @@ var HandoffCheckpointTracker = class {
|
|
|
20034
21290
|
indexArtifactPath: uploads.index?.storagePath
|
|
20035
21291
|
};
|
|
20036
21292
|
} finally {
|
|
20037
|
-
const tempDir = capture.headPack?.path ?
|
|
21293
|
+
const tempDir = capture.headPack?.path ? dirname7(capture.headPack.path) : dirname7(capture.indexFile.path);
|
|
20038
21294
|
await this.removeIfPresent(capture.headPack?.path);
|
|
20039
21295
|
await this.removeIfPresent(capture.indexFile.path);
|
|
20040
|
-
await
|
|
21296
|
+
await rm5(tempDir, { recursive: true, force: true }).catch(() => {
|
|
20041
21297
|
});
|
|
20042
21298
|
}
|
|
20043
21299
|
}
|
|
@@ -20049,10 +21305,10 @@ var HandoffCheckpointTracker = class {
|
|
|
20049
21305
|
}
|
|
20050
21306
|
const gitTracker = this.createGitTracker();
|
|
20051
21307
|
const tmpDir = await mkdtemp2(
|
|
20052
|
-
|
|
21308
|
+
join11(tmpdir2(), `posthog-code-handoff-${checkpoint.checkpointId}-`)
|
|
20053
21309
|
);
|
|
20054
|
-
const packPath =
|
|
20055
|
-
const indexPath =
|
|
21310
|
+
const packPath = join11(tmpDir, `${checkpoint.checkpointId}.pack`);
|
|
21311
|
+
const indexPath = join11(tmpDir, `${checkpoint.checkpointId}.index`);
|
|
20056
21312
|
try {
|
|
20057
21313
|
const downloads = await this.downloadArtifacts([
|
|
20058
21314
|
{
|
|
@@ -20084,7 +21340,7 @@ var HandoffCheckpointTracker = class {
|
|
|
20084
21340
|
} finally {
|
|
20085
21341
|
await this.removeIfPresent(packPath);
|
|
20086
21342
|
await this.removeIfPresent(indexPath);
|
|
20087
|
-
await
|
|
21343
|
+
await rm5(tmpDir, { recursive: true, force: true }).catch(() => {
|
|
20088
21344
|
});
|
|
20089
21345
|
}
|
|
20090
21346
|
}
|
|
@@ -20215,12 +21471,24 @@ var HandoffCheckpointTracker = class {
|
|
|
20215
21471
|
if (!filePath) {
|
|
20216
21472
|
return;
|
|
20217
21473
|
}
|
|
20218
|
-
await
|
|
21474
|
+
await rm5(filePath, { force: true }).catch(() => {
|
|
20219
21475
|
});
|
|
20220
21476
|
}
|
|
20221
21477
|
};
|
|
20222
21478
|
|
|
20223
21479
|
// src/utils/gateway.ts
|
|
21480
|
+
function resolveGatewayProduct({
|
|
21481
|
+
isInternal,
|
|
21482
|
+
originProduct
|
|
21483
|
+
} = {}) {
|
|
21484
|
+
if (isInternal) {
|
|
21485
|
+
return originProduct === "signal_report" ? "signals" : "background_agents";
|
|
21486
|
+
}
|
|
21487
|
+
return "posthog_code";
|
|
21488
|
+
}
|
|
21489
|
+
function buildGatewayPropertyHeaders(properties) {
|
|
21490
|
+
return Object.entries(properties).filter(([, value]) => value !== null && value !== void 0).map(([key, value]) => `x-posthog-property-${key}: ${value}`).join("\n");
|
|
21491
|
+
}
|
|
20224
21492
|
function getGatewayBaseUrl(posthogHost) {
|
|
20225
21493
|
const url = new URL(posthogHost);
|
|
20226
21494
|
const hostname = url.hostname;
|
|
@@ -20462,9 +21730,9 @@ function extractCreatedPrUrl(input) {
|
|
|
20462
21730
|
|
|
20463
21731
|
// src/adapters/claude/session/jsonl-hydration.ts
|
|
20464
21732
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
20465
|
-
import * as
|
|
20466
|
-
import * as
|
|
20467
|
-
import * as
|
|
21733
|
+
import * as fs13 from "fs/promises";
|
|
21734
|
+
import * as os8 from "os";
|
|
21735
|
+
import * as path16 from "path";
|
|
20468
21736
|
var CHARS_PER_TOKEN = 4;
|
|
20469
21737
|
var DEFAULT_MAX_TOKENS = 15e4;
|
|
20470
21738
|
function estimateTurnTokens(turn) {
|
|
@@ -20771,9 +22039,9 @@ ${toolSummary}`);
|
|
|
20771
22039
|
}
|
|
20772
22040
|
|
|
20773
22041
|
// src/session-log-writer.ts
|
|
20774
|
-
import
|
|
22042
|
+
import fs14 from "fs";
|
|
20775
22043
|
import fsp from "fs/promises";
|
|
20776
|
-
import
|
|
22044
|
+
import path17 from "path";
|
|
20777
22045
|
var SessionLogWriter = class _SessionLogWriter {
|
|
20778
22046
|
static FLUSH_DEBOUNCE_MS = 500;
|
|
20779
22047
|
static FLUSH_MAX_INTERVAL_MS = 5e3;
|
|
@@ -20809,13 +22077,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20809
22077
|
this.sessions.set(sessionId, { context, currentTurnMessages: [] });
|
|
20810
22078
|
this.lastFlushAttemptTime.set(sessionId, Date.now());
|
|
20811
22079
|
if (this.localCachePath) {
|
|
20812
|
-
const sessionDir =
|
|
22080
|
+
const sessionDir = path17.join(
|
|
20813
22081
|
this.localCachePath,
|
|
20814
22082
|
"sessions",
|
|
20815
22083
|
context.runId
|
|
20816
22084
|
);
|
|
20817
22085
|
try {
|
|
20818
|
-
|
|
22086
|
+
fs14.mkdirSync(sessionDir, { recursive: true });
|
|
20819
22087
|
} catch (error) {
|
|
20820
22088
|
this.logger.warn("Failed to create local cache directory", {
|
|
20821
22089
|
sessionDir,
|
|
@@ -21067,14 +22335,14 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21067
22335
|
if (!this.localCachePath) return;
|
|
21068
22336
|
const session = this.sessions.get(sessionId);
|
|
21069
22337
|
if (!session) return;
|
|
21070
|
-
const logPath =
|
|
22338
|
+
const logPath = path17.join(
|
|
21071
22339
|
this.localCachePath,
|
|
21072
22340
|
"sessions",
|
|
21073
22341
|
session.context.runId,
|
|
21074
22342
|
"logs.ndjson"
|
|
21075
22343
|
);
|
|
21076
22344
|
try {
|
|
21077
|
-
|
|
22345
|
+
fs14.appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
21078
22346
|
`);
|
|
21079
22347
|
} catch (error) {
|
|
21080
22348
|
this.logger.warn("Failed to write to local cache", {
|
|
@@ -21086,13 +22354,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21086
22354
|
}
|
|
21087
22355
|
}
|
|
21088
22356
|
static async cleanupOldSessions(localCachePath) {
|
|
21089
|
-
const sessionsDir =
|
|
22357
|
+
const sessionsDir = path17.join(localCachePath, "sessions");
|
|
21090
22358
|
let deleted = 0;
|
|
21091
22359
|
try {
|
|
21092
22360
|
const entries = await fsp.readdir(sessionsDir);
|
|
21093
22361
|
const now = Date.now();
|
|
21094
22362
|
for (const entry of entries) {
|
|
21095
|
-
const entryPath =
|
|
22363
|
+
const entryPath = path17.join(sessionsDir, entry);
|
|
21096
22364
|
try {
|
|
21097
22365
|
const stats = await fsp.stat(entryPath);
|
|
21098
22366
|
if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
|
|
@@ -21109,11 +22377,11 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21109
22377
|
};
|
|
21110
22378
|
|
|
21111
22379
|
// src/server/agentsh-runtime.ts
|
|
21112
|
-
import { execFile as
|
|
22380
|
+
import { execFile as execFile5 } from "child_process";
|
|
21113
22381
|
import { readFile as readFile5 } from "fs/promises";
|
|
21114
22382
|
import { promisify as promisify2 } from "util";
|
|
21115
22383
|
var AGENTSH_SESSION_ID_FILE = "/tmp/agentsh-session-id";
|
|
21116
|
-
var execFileAsync2 = promisify2(
|
|
22384
|
+
var execFileAsync2 = promisify2(execFile5);
|
|
21117
22385
|
function errorMessage(error) {
|
|
21118
22386
|
return error instanceof Error ? error.message : String(error);
|
|
21119
22387
|
}
|
|
@@ -21130,7 +22398,7 @@ async function getAgentshVersion() {
|
|
|
21130
22398
|
}
|
|
21131
22399
|
async function resolveAgentshRuntimeInfo({
|
|
21132
22400
|
sessionIdPath = AGENTSH_SESSION_ID_FILE,
|
|
21133
|
-
readSessionId = async (
|
|
22401
|
+
readSessionId = async (path18) => readFile5(path18, "utf8"),
|
|
21134
22402
|
getVersion = getAgentshVersion
|
|
21135
22403
|
} = {}) {
|
|
21136
22404
|
let sessionId;
|
|
@@ -21184,20 +22452,20 @@ function normalizeCloudPromptContent(content) {
|
|
|
21184
22452
|
|
|
21185
22453
|
// src/server/jwt.ts
|
|
21186
22454
|
import jwt from "jsonwebtoken";
|
|
21187
|
-
import { z as
|
|
22455
|
+
import { z as z3 } from "zod";
|
|
21188
22456
|
var SANDBOX_CONNECTION_AUDIENCE = "posthog:sandbox_connection";
|
|
21189
|
-
var userDataSchema =
|
|
21190
|
-
run_id:
|
|
21191
|
-
task_id:
|
|
21192
|
-
team_id:
|
|
21193
|
-
user_id:
|
|
21194
|
-
distinct_id:
|
|
21195
|
-
mode:
|
|
22457
|
+
var userDataSchema = z3.object({
|
|
22458
|
+
run_id: z3.string(),
|
|
22459
|
+
task_id: z3.string(),
|
|
22460
|
+
team_id: z3.number(),
|
|
22461
|
+
user_id: z3.number(),
|
|
22462
|
+
distinct_id: z3.string(),
|
|
22463
|
+
mode: z3.enum(["interactive", "background"]).optional().default("interactive")
|
|
21196
22464
|
});
|
|
21197
22465
|
var jwtPayloadSchema = userDataSchema.extend({
|
|
21198
|
-
exp:
|
|
21199
|
-
iat:
|
|
21200
|
-
aud:
|
|
22466
|
+
exp: z3.number(),
|
|
22467
|
+
iat: z3.number().optional(),
|
|
22468
|
+
aud: z3.string().optional()
|
|
21201
22469
|
});
|
|
21202
22470
|
var JwtValidationError = class extends Error {
|
|
21203
22471
|
constructor(message, code) {
|
|
@@ -21235,49 +22503,49 @@ function validateJwt(token, publicKey) {
|
|
|
21235
22503
|
}
|
|
21236
22504
|
|
|
21237
22505
|
// src/server/schemas.ts
|
|
21238
|
-
import { z as
|
|
21239
|
-
var httpHeaderSchema =
|
|
21240
|
-
name:
|
|
21241
|
-
value:
|
|
22506
|
+
import { z as z4 } from "zod/v4";
|
|
22507
|
+
var httpHeaderSchema = z4.object({
|
|
22508
|
+
name: z4.string(),
|
|
22509
|
+
value: z4.string()
|
|
21242
22510
|
});
|
|
21243
|
-
var nullishString =
|
|
21244
|
-
var handoffLocalGitStateSchema =
|
|
22511
|
+
var nullishString = z4.string().nullish().transform((value) => value ?? null);
|
|
22512
|
+
var handoffLocalGitStateSchema = z4.object({
|
|
21245
22513
|
head: nullishString,
|
|
21246
22514
|
branch: nullishString,
|
|
21247
22515
|
upstreamHead: nullishString,
|
|
21248
22516
|
upstreamRemote: nullishString,
|
|
21249
22517
|
upstreamMergeRef: nullishString
|
|
21250
22518
|
});
|
|
21251
|
-
var remoteMcpServerSchema =
|
|
21252
|
-
type:
|
|
21253
|
-
name:
|
|
21254
|
-
url:
|
|
21255
|
-
headers:
|
|
22519
|
+
var remoteMcpServerSchema = z4.object({
|
|
22520
|
+
type: z4.enum(["http", "sse"]),
|
|
22521
|
+
name: z4.string().min(1, "MCP server name is required"),
|
|
22522
|
+
url: z4.url({ error: "MCP server url must be a valid URL" }),
|
|
22523
|
+
headers: z4.array(httpHeaderSchema).default([])
|
|
21256
22524
|
});
|
|
21257
|
-
var mcpServersSchema =
|
|
21258
|
-
var claudeCodeConfigSchema =
|
|
21259
|
-
systemPrompt:
|
|
21260
|
-
|
|
21261
|
-
|
|
21262
|
-
type:
|
|
21263
|
-
preset:
|
|
21264
|
-
append:
|
|
22525
|
+
var mcpServersSchema = z4.array(remoteMcpServerSchema);
|
|
22526
|
+
var claudeCodeConfigSchema = z4.object({
|
|
22527
|
+
systemPrompt: z4.union([
|
|
22528
|
+
z4.string(),
|
|
22529
|
+
z4.object({
|
|
22530
|
+
type: z4.literal("preset"),
|
|
22531
|
+
preset: z4.literal("claude_code"),
|
|
22532
|
+
append: z4.string().optional()
|
|
21265
22533
|
})
|
|
21266
22534
|
]).optional(),
|
|
21267
|
-
plugins:
|
|
22535
|
+
plugins: z4.array(z4.object({ type: z4.literal("local"), path: z4.string() })).optional()
|
|
21268
22536
|
});
|
|
21269
|
-
var jsonRpcRequestSchema =
|
|
21270
|
-
jsonrpc:
|
|
21271
|
-
method:
|
|
21272
|
-
params:
|
|
21273
|
-
id:
|
|
22537
|
+
var jsonRpcRequestSchema = z4.object({
|
|
22538
|
+
jsonrpc: z4.literal("2.0"),
|
|
22539
|
+
method: z4.string(),
|
|
22540
|
+
params: z4.record(z4.string(), z4.unknown()).optional(),
|
|
22541
|
+
id: z4.union([z4.string(), z4.number()]).optional()
|
|
21274
22542
|
});
|
|
21275
|
-
var userMessageParamsSchema =
|
|
21276
|
-
content:
|
|
21277
|
-
|
|
21278
|
-
|
|
22543
|
+
var userMessageParamsSchema = z4.object({
|
|
22544
|
+
content: z4.union([
|
|
22545
|
+
z4.string().min(1, "Content is required"),
|
|
22546
|
+
z4.array(z4.record(z4.string(), z4.unknown())).min(1, "Content is required")
|
|
21279
22547
|
]).optional(),
|
|
21280
|
-
artifacts:
|
|
22548
|
+
artifacts: z4.array(z4.record(z4.string(), z4.unknown())).optional()
|
|
21281
22549
|
}).refine(
|
|
21282
22550
|
(params) => {
|
|
21283
22551
|
const hasContent = typeof params.content === "string" ? params.content.trim().length > 0 : Array.isArray(params.content) && params.content.length > 0;
|
|
@@ -21286,27 +22554,27 @@ var userMessageParamsSchema = z3.object({
|
|
|
21286
22554
|
},
|
|
21287
22555
|
{ error: "Either content or artifacts are required" }
|
|
21288
22556
|
);
|
|
21289
|
-
var permissionResponseParamsSchema =
|
|
21290
|
-
requestId:
|
|
21291
|
-
optionId:
|
|
21292
|
-
customInput:
|
|
21293
|
-
answers:
|
|
22557
|
+
var permissionResponseParamsSchema = z4.object({
|
|
22558
|
+
requestId: z4.string().min(1, "requestId is required"),
|
|
22559
|
+
optionId: z4.string().min(1, "optionId is required"),
|
|
22560
|
+
customInput: z4.string().optional(),
|
|
22561
|
+
answers: z4.record(z4.string(), z4.string()).optional()
|
|
21294
22562
|
});
|
|
21295
|
-
var setConfigOptionParamsSchema =
|
|
21296
|
-
configId:
|
|
21297
|
-
value:
|
|
22563
|
+
var setConfigOptionParamsSchema = z4.object({
|
|
22564
|
+
configId: z4.string().min(1, "configId is required"),
|
|
22565
|
+
value: z4.string().min(1, "value is required")
|
|
21298
22566
|
});
|
|
21299
|
-
var refreshSessionParamsSchema =
|
|
22567
|
+
var refreshSessionParamsSchema = z4.object({
|
|
21300
22568
|
mcpServers: mcpServersSchema
|
|
21301
22569
|
});
|
|
21302
|
-
var closeParamsSchema =
|
|
22570
|
+
var closeParamsSchema = z4.object({
|
|
21303
22571
|
localGitState: handoffLocalGitStateSchema.optional()
|
|
21304
22572
|
}).optional();
|
|
21305
22573
|
var commandParamsSchemas = {
|
|
21306
22574
|
user_message: userMessageParamsSchema,
|
|
21307
22575
|
"posthog/user_message": userMessageParamsSchema,
|
|
21308
|
-
cancel:
|
|
21309
|
-
"posthog/cancel":
|
|
22576
|
+
cancel: z4.object({}).optional(),
|
|
22577
|
+
"posthog/cancel": z4.object({}).optional(),
|
|
21310
22578
|
close: closeParamsSchema,
|
|
21311
22579
|
"posthog/close": closeParamsSchema,
|
|
21312
22580
|
permission_response: permissionResponseParamsSchema,
|
|
@@ -21330,7 +22598,7 @@ function validateCommandParams(method, params) {
|
|
|
21330
22598
|
}
|
|
21331
22599
|
|
|
21332
22600
|
// src/server/agent-server.ts
|
|
21333
|
-
var agentErrorClassificationSchema =
|
|
22601
|
+
var agentErrorClassificationSchema = z5.enum([
|
|
21334
22602
|
"upstream_stream_terminated",
|
|
21335
22603
|
"upstream_connection_error",
|
|
21336
22604
|
"upstream_provider_failure",
|
|
@@ -21342,8 +22610,8 @@ var upstreamProviderFailureClassifications = /* @__PURE__ */ new Set([
|
|
|
21342
22610
|
"upstream_connection_error",
|
|
21343
22611
|
"upstream_provider_failure"
|
|
21344
22612
|
]);
|
|
21345
|
-
var errorWithClassificationSchema =
|
|
21346
|
-
data:
|
|
22613
|
+
var errorWithClassificationSchema = z5.object({
|
|
22614
|
+
data: z5.object({ classification: agentErrorClassificationSchema })
|
|
21347
22615
|
});
|
|
21348
22616
|
var SSE_KEEPALIVE_INTERVAL_MS = 25e3;
|
|
21349
22617
|
var NdJsonTap = class {
|
|
@@ -21664,7 +22932,7 @@ var AgentServer = class {
|
|
|
21664
22932
|
return app;
|
|
21665
22933
|
}
|
|
21666
22934
|
async start() {
|
|
21667
|
-
await new Promise((
|
|
22935
|
+
await new Promise((resolve8) => {
|
|
21668
22936
|
this.server = serve(
|
|
21669
22937
|
{
|
|
21670
22938
|
fetch: this.app.fetch,
|
|
@@ -21674,7 +22942,7 @@ var AgentServer = class {
|
|
|
21674
22942
|
this.logger.debug(
|
|
21675
22943
|
`HTTP server listening on port ${this.config.port}`
|
|
21676
22944
|
);
|
|
21677
|
-
|
|
22945
|
+
resolve8();
|
|
21678
22946
|
}
|
|
21679
22947
|
);
|
|
21680
22948
|
});
|
|
@@ -21923,7 +23191,13 @@ var AgentServer = class {
|
|
|
21923
23191
|
return null;
|
|
21924
23192
|
})
|
|
21925
23193
|
]);
|
|
21926
|
-
this.configureEnvironment({
|
|
23194
|
+
this.configureEnvironment({
|
|
23195
|
+
isInternal: preTask?.internal === true,
|
|
23196
|
+
originProduct: preTask?.origin_product,
|
|
23197
|
+
taskId: payload.task_id,
|
|
23198
|
+
taskRunId: payload.run_id,
|
|
23199
|
+
taskUserId: payload.user_id
|
|
23200
|
+
});
|
|
21927
23201
|
const prUrl = getTaskRunStateString(preTaskRun, "slack_notified_pr_url");
|
|
21928
23202
|
if (prUrl) {
|
|
21929
23203
|
this.detectedPrUrl = prUrl;
|
|
@@ -22000,6 +23274,7 @@ var AgentServer = class {
|
|
|
22000
23274
|
_meta: {
|
|
22001
23275
|
sessionId: payload.run_id,
|
|
22002
23276
|
taskRunId: payload.run_id,
|
|
23277
|
+
taskId: payload.task_id,
|
|
22003
23278
|
systemPrompt: sessionSystemPrompt,
|
|
22004
23279
|
...this.config.model && { model: this.config.model },
|
|
22005
23280
|
allowedDomains: this.config.allowedDomains,
|
|
@@ -22393,15 +23668,15 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
22393
23668
|
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
22394
23669
|
}
|
|
22395
23670
|
const safeName = this.getSafeArtifactName(artifact.name);
|
|
22396
|
-
const artifactDir =
|
|
23671
|
+
const artifactDir = join13(
|
|
22397
23672
|
this.config.repositoryPath ?? "/tmp/workspace",
|
|
22398
23673
|
".posthog",
|
|
22399
23674
|
"attachments",
|
|
22400
23675
|
runId,
|
|
22401
23676
|
artifact.id ?? safeName
|
|
22402
23677
|
);
|
|
22403
|
-
await
|
|
22404
|
-
const artifactPath =
|
|
23678
|
+
await mkdir5(artifactDir, { recursive: true });
|
|
23679
|
+
const artifactPath = join13(artifactDir, safeName);
|
|
22405
23680
|
await writeFile4(artifactPath, Buffer.from(data));
|
|
22406
23681
|
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
22407
23682
|
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|
|
@@ -22409,7 +23684,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
22409
23684
|
});
|
|
22410
23685
|
}
|
|
22411
23686
|
getSafeArtifactName(name2) {
|
|
22412
|
-
const baseName =
|
|
23687
|
+
const baseName = basename3(name2).trim();
|
|
22413
23688
|
const normalizedName = baseName.replace(/[^\w.-]/g, "_");
|
|
22414
23689
|
return normalizedName.length > 0 ? normalizedName : "attachment";
|
|
22415
23690
|
}
|
|
@@ -22483,24 +23758,21 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`;
|
|
|
22483
23758
|
buildCloudSystemPrompt(prUrl) {
|
|
22484
23759
|
const taskId = this.config.taskId;
|
|
22485
23760
|
const shouldAutoCreatePr = this.shouldAutoPublishCloudChanges();
|
|
22486
|
-
const
|
|
22487
|
-
##
|
|
22488
|
-
|
|
23761
|
+
const signedCommitInstructions = `
|
|
23762
|
+
## Committing (signed commits required)
|
|
23763
|
+
Commits MUST be signed. \`git commit\` and \`git push\` are blocked in this environment.
|
|
23764
|
+
To commit: stage your changes with \`git add\`, then call the \`git_signed_commit\` tool (full
|
|
23765
|
+
name \`${SIGNED_COMMIT_QUALIFIED_TOOL_NAME}\`) with a \`message\` (and optional \`body\`/\`paths\`).
|
|
23766
|
+
It creates a GitHub-signed ("Verified") commit on the branch and keeps your local checkout in
|
|
23767
|
+
sync. To start a new branch, pass \`branch\` (prefixed with \`posthog-code/\`) \u2014 the tool creates
|
|
23768
|
+
it on the remote for you.
|
|
22489
23769
|
|
|
22490
|
-
|
|
23770
|
+
## Attribution
|
|
23771
|
+
Do NOT add "Co-Authored-By" trailers or "Generated with [Claude Code]" lines to your
|
|
23772
|
+
commit messages. The \`git_signed_commit\` tool automatically appends the only trailers
|
|
23773
|
+
we want:
|
|
22491
23774
|
Generated-By: PostHog Code
|
|
22492
|
-
Task-Id: ${taskId}
|
|
22493
|
-
|
|
22494
|
-
Example:
|
|
22495
|
-
\`\`\`
|
|
22496
|
-
git commit -m "$(cat <<'EOF'
|
|
22497
|
-
fix: resolve login redirect loop
|
|
22498
|
-
|
|
22499
|
-
Generated-By: PostHog Code
|
|
22500
|
-
Task-Id: ${taskId}
|
|
22501
|
-
EOF
|
|
22502
|
-
)"
|
|
22503
|
-
\`\`\``;
|
|
23775
|
+
Task-Id: ${taskId}`;
|
|
22504
23776
|
if (prUrl) {
|
|
22505
23777
|
if (!shouldAutoCreatePr) {
|
|
22506
23778
|
return `
|
|
@@ -22513,7 +23785,7 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22513
23785
|
Important:
|
|
22514
23786
|
- Do NOT create new commits, push to the branch, or update the pull request unless the user explicitly asks.
|
|
22515
23787
|
- Do NOT create a new branch or a new pull request.
|
|
22516
|
-
${
|
|
23788
|
+
${signedCommitInstructions}
|
|
22517
23789
|
`;
|
|
22518
23790
|
}
|
|
22519
23791
|
return `
|
|
@@ -22523,9 +23795,8 @@ This task already has an open pull request: ${prUrl}
|
|
|
22523
23795
|
|
|
22524
23796
|
After completing the requested changes:
|
|
22525
23797
|
1. Check out the existing PR branch with \`gh pr checkout ${prUrl}\`
|
|
22526
|
-
2. Stage
|
|
22527
|
-
3.
|
|
22528
|
-
4. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
23798
|
+
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.
|
|
23799
|
+
3. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
22529
23800
|
- 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='...'\`.
|
|
22530
23801
|
- 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>"\`.
|
|
22531
23802
|
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.
|
|
@@ -22533,7 +23804,7 @@ After completing the requested changes:
|
|
|
22533
23804
|
Important:
|
|
22534
23805
|
- Do NOT create a new branch or a new pull request.
|
|
22535
23806
|
- Do NOT push fixes for review comments without replying to and resolving each related thread.
|
|
22536
|
-
${
|
|
23807
|
+
${signedCommitInstructions}
|
|
22537
23808
|
`;
|
|
22538
23809
|
}
|
|
22539
23810
|
if (!this.config.repositoryPath) {
|
|
@@ -22544,7 +23815,7 @@ When the user asks for code changes:
|
|
|
22544
23815
|
When the user explicitly asks to clone or work in a GitHub repository:
|
|
22545
23816
|
- Clone the repository into /tmp/workspace/repos/<owner>/<repo> using \`gh repo clone <owner>/<repo> /tmp/workspace/repos/<owner>/<repo>\`
|
|
22546
23817
|
- Work from inside that cloned repository for follow-up code changes
|
|
22547
|
-
- If the user explicitly asks you to open or update a pull request, create a branch, commit the
|
|
23818
|
+
- 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.
|
|
22548
23819
|
- Do NOT create branches, commits, push changes, or open pull requests unless the user explicitly asks for that`;
|
|
22549
23820
|
return `
|
|
22550
23821
|
# Cloud Task Execution \u2014 No Repository Mode
|
|
@@ -22563,7 +23834,7 @@ ${publishInstructions}
|
|
|
22563
23834
|
|
|
22564
23835
|
Important:
|
|
22565
23836
|
- Prefer using MCP tools to answer questions with real data over giving generic advice.
|
|
22566
|
-
${
|
|
23837
|
+
${signedCommitInstructions}
|
|
22567
23838
|
`;
|
|
22568
23839
|
}
|
|
22569
23840
|
if (!shouldAutoCreatePr) {
|
|
@@ -22574,21 +23845,20 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22574
23845
|
|
|
22575
23846
|
Important:
|
|
22576
23847
|
- Do NOT create a branch, commit, push, or open a pull request unless the user explicitly asks.
|
|
22577
|
-
${
|
|
23848
|
+
${signedCommitInstructions}
|
|
22578
23849
|
`;
|
|
22579
23850
|
}
|
|
22580
23851
|
return `
|
|
22581
23852
|
# Cloud Task Execution
|
|
22582
23853
|
|
|
22583
23854
|
After completing the requested changes:
|
|
22584
|
-
1.
|
|
22585
|
-
2. Stage
|
|
22586
|
-
3.
|
|
22587
|
-
4. Before opening the PR, prepare the body:
|
|
23855
|
+
1. Pick a new branch name prefixed with \`posthog-code/\` (e.g. \`posthog-code/fix-login-redirect\`)
|
|
23856
|
+
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.
|
|
23857
|
+
3. Before opening the PR, prepare the body:
|
|
22588
23858
|
- 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.
|
|
22589
23859
|
- 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.
|
|
22590
23860
|
- 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.
|
|
22591
|
-
|
|
23861
|
+
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:
|
|
22592
23862
|
\`\`\`
|
|
22593
23863
|
---
|
|
22594
23864
|
*Created with [PostHog Code](https://posthog.com/code?ref=pr)*
|
|
@@ -22596,7 +23866,7 @@ After completing the requested changes:
|
|
|
22596
23866
|
|
|
22597
23867
|
Important:
|
|
22598
23868
|
- Always create the PR as a draft. Do not ask for confirmation.
|
|
22599
|
-
${
|
|
23869
|
+
${signedCommitInstructions}
|
|
22600
23870
|
`;
|
|
22601
23871
|
}
|
|
22602
23872
|
async getCurrentGitBranch() {
|
|
@@ -22665,12 +23935,23 @@ ${attributionInstructions}
|
|
|
22665
23935
|
}
|
|
22666
23936
|
}
|
|
22667
23937
|
configureEnvironment({
|
|
22668
|
-
isInternal = false
|
|
23938
|
+
isInternal = false,
|
|
23939
|
+
originProduct,
|
|
23940
|
+
taskId,
|
|
23941
|
+
taskRunId,
|
|
23942
|
+
taskUserId
|
|
22669
23943
|
} = {}) {
|
|
22670
23944
|
const { apiKey, apiUrl, projectId } = this.config;
|
|
22671
|
-
const product = isInternal
|
|
23945
|
+
const product = resolveGatewayProduct({ isInternal, originProduct });
|
|
22672
23946
|
const gatewayUrl = process.env.LLM_GATEWAY_URL || getLlmGatewayUrl(apiUrl, product);
|
|
22673
23947
|
const openaiBaseUrl = gatewayUrl.endsWith("/v1") ? gatewayUrl : `${gatewayUrl}/v1`;
|
|
23948
|
+
const customHeaders = buildGatewayPropertyHeaders({
|
|
23949
|
+
task_origin_product: originProduct,
|
|
23950
|
+
task_internal: isInternal,
|
|
23951
|
+
task_id: taskId,
|
|
23952
|
+
task_run_id: taskRunId,
|
|
23953
|
+
task_user_id: taskUserId
|
|
23954
|
+
});
|
|
22674
23955
|
Object.assign(process.env, {
|
|
22675
23956
|
// PostHog
|
|
22676
23957
|
POSTHOG_API_KEY: apiKey,
|
|
@@ -22682,6 +23963,7 @@ ${attributionInstructions}
|
|
|
22682
23963
|
ANTHROPIC_API_KEY: apiKey,
|
|
22683
23964
|
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
22684
23965
|
ANTHROPIC_BASE_URL: gatewayUrl,
|
|
23966
|
+
ANTHROPIC_CUSTOM_HEADERS: customHeaders,
|
|
22685
23967
|
// OpenAI (for models like GPT-4, o1, etc.)
|
|
22686
23968
|
OPENAI_API_KEY: apiKey,
|
|
22687
23969
|
OPENAI_BASE_URL: openaiBaseUrl,
|
|
@@ -23052,8 +24334,8 @@ ${attributionInstructions}
|
|
|
23052
24334
|
options: params.options,
|
|
23053
24335
|
toolCall: params.toolCall
|
|
23054
24336
|
});
|
|
23055
|
-
return new Promise((
|
|
23056
|
-
this.pendingPermissions.set(requestId, { resolve:
|
|
24337
|
+
return new Promise((resolve8) => {
|
|
24338
|
+
this.pendingPermissions.set(requestId, { resolve: resolve8 });
|
|
23057
24339
|
});
|
|
23058
24340
|
}
|
|
23059
24341
|
resolvePermission(requestId, optionId, customInput, answers) {
|
|
@@ -23075,4 +24357,17 @@ export {
|
|
|
23075
24357
|
SSE_KEEPALIVE_INTERVAL_MS,
|
|
23076
24358
|
UPSTREAM_PROVIDER_FAILURE_MESSAGE
|
|
23077
24359
|
};
|
|
24360
|
+
/*! Bundled license information:
|
|
24361
|
+
|
|
24362
|
+
git-url-parse/lib/index.js:
|
|
24363
|
+
(*!
|
|
24364
|
+
* buildToken
|
|
24365
|
+
* Builds OAuth token prefix (helper function)
|
|
24366
|
+
*
|
|
24367
|
+
* @name buildToken
|
|
24368
|
+
* @function
|
|
24369
|
+
* @param {GitUrl} obj The parsed Git url object.
|
|
24370
|
+
* @return {String} token prefix
|
|
24371
|
+
*)
|
|
24372
|
+
*/
|
|
23078
24373
|
//# sourceMappingURL=agent-server.js.map
|