@posthog/agent 2.3.643 → 2.3.655
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/claude/permissions/permission-options.js +700 -0
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
- package/dist/adapters/claude/tools.js +700 -0
- package/dist/adapters/claude/tools.js.map +1 -1
- package/dist/adapters/codex/local-tools-mcp-server.d.ts +2 -0
- package/dist/adapters/codex/local-tools-mcp-server.js +1172 -0
- package/dist/adapters/codex/local-tools-mcp-server.js.map +1 -0
- package/dist/agent.js +1488 -219
- package/dist/agent.js.map +1 -1
- package/dist/execution-mode.js +700 -0
- package/dist/execution-mode.js.map +1 -1
- package/dist/handoff-checkpoint.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +1604 -339
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +1520 -258
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/claude-agent.ts +32 -2
- package/src/adapters/claude/hooks.test.ts +54 -0
- package/src/adapters/claude/hooks.ts +86 -0
- package/src/adapters/claude/mcp/local-tools.test.ts +50 -0
- package/src/adapters/claude/mcp/local-tools.ts +40 -0
- package/src/adapters/claude/session/options.ts +14 -9
- package/src/adapters/claude/types.ts +1 -0
- package/src/adapters/codex/codex-agent.ts +117 -22
- package/src/adapters/codex/local-tools-mcp-server.ts +71 -0
- package/src/adapters/local-tools/index.ts +22 -0
- package/src/adapters/local-tools/registry.test.ts +57 -0
- package/src/adapters/local-tools/registry.ts +81 -0
- package/src/adapters/local-tools/tools/signed-commit.ts +26 -0
- package/src/adapters/session-meta.ts +16 -0
- package/src/adapters/signed-commit-shared.ts +82 -0
- package/src/server/agent-server.test.ts +2 -4
- package/src/server/agent-server.ts +27 -30
- package/src/utils/common.ts +14 -0
|
@@ -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.655",
|
|
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,7 +21471,7 @@ 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
|
};
|
|
@@ -20462,9 +21718,9 @@ function extractCreatedPrUrl(input) {
|
|
|
20462
21718
|
|
|
20463
21719
|
// src/adapters/claude/session/jsonl-hydration.ts
|
|
20464
21720
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
20465
|
-
import * as
|
|
20466
|
-
import * as
|
|
20467
|
-
import * as
|
|
21721
|
+
import * as fs13 from "fs/promises";
|
|
21722
|
+
import * as os8 from "os";
|
|
21723
|
+
import * as path16 from "path";
|
|
20468
21724
|
var CHARS_PER_TOKEN = 4;
|
|
20469
21725
|
var DEFAULT_MAX_TOKENS = 15e4;
|
|
20470
21726
|
function estimateTurnTokens(turn) {
|
|
@@ -20771,9 +22027,9 @@ ${toolSummary}`);
|
|
|
20771
22027
|
}
|
|
20772
22028
|
|
|
20773
22029
|
// src/session-log-writer.ts
|
|
20774
|
-
import
|
|
22030
|
+
import fs14 from "fs";
|
|
20775
22031
|
import fsp from "fs/promises";
|
|
20776
|
-
import
|
|
22032
|
+
import path17 from "path";
|
|
20777
22033
|
var SessionLogWriter = class _SessionLogWriter {
|
|
20778
22034
|
static FLUSH_DEBOUNCE_MS = 500;
|
|
20779
22035
|
static FLUSH_MAX_INTERVAL_MS = 5e3;
|
|
@@ -20809,13 +22065,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20809
22065
|
this.sessions.set(sessionId, { context, currentTurnMessages: [] });
|
|
20810
22066
|
this.lastFlushAttemptTime.set(sessionId, Date.now());
|
|
20811
22067
|
if (this.localCachePath) {
|
|
20812
|
-
const sessionDir =
|
|
22068
|
+
const sessionDir = path17.join(
|
|
20813
22069
|
this.localCachePath,
|
|
20814
22070
|
"sessions",
|
|
20815
22071
|
context.runId
|
|
20816
22072
|
);
|
|
20817
22073
|
try {
|
|
20818
|
-
|
|
22074
|
+
fs14.mkdirSync(sessionDir, { recursive: true });
|
|
20819
22075
|
} catch (error) {
|
|
20820
22076
|
this.logger.warn("Failed to create local cache directory", {
|
|
20821
22077
|
sessionDir,
|
|
@@ -21067,14 +22323,14 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21067
22323
|
if (!this.localCachePath) return;
|
|
21068
22324
|
const session = this.sessions.get(sessionId);
|
|
21069
22325
|
if (!session) return;
|
|
21070
|
-
const logPath =
|
|
22326
|
+
const logPath = path17.join(
|
|
21071
22327
|
this.localCachePath,
|
|
21072
22328
|
"sessions",
|
|
21073
22329
|
session.context.runId,
|
|
21074
22330
|
"logs.ndjson"
|
|
21075
22331
|
);
|
|
21076
22332
|
try {
|
|
21077
|
-
|
|
22333
|
+
fs14.appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
21078
22334
|
`);
|
|
21079
22335
|
} catch (error) {
|
|
21080
22336
|
this.logger.warn("Failed to write to local cache", {
|
|
@@ -21086,13 +22342,13 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21086
22342
|
}
|
|
21087
22343
|
}
|
|
21088
22344
|
static async cleanupOldSessions(localCachePath) {
|
|
21089
|
-
const sessionsDir =
|
|
22345
|
+
const sessionsDir = path17.join(localCachePath, "sessions");
|
|
21090
22346
|
let deleted = 0;
|
|
21091
22347
|
try {
|
|
21092
22348
|
const entries = await fsp.readdir(sessionsDir);
|
|
21093
22349
|
const now = Date.now();
|
|
21094
22350
|
for (const entry of entries) {
|
|
21095
|
-
const entryPath =
|
|
22351
|
+
const entryPath = path17.join(sessionsDir, entry);
|
|
21096
22352
|
try {
|
|
21097
22353
|
const stats = await fsp.stat(entryPath);
|
|
21098
22354
|
if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
|
|
@@ -21109,11 +22365,11 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21109
22365
|
};
|
|
21110
22366
|
|
|
21111
22367
|
// src/server/agentsh-runtime.ts
|
|
21112
|
-
import { execFile as
|
|
22368
|
+
import { execFile as execFile5 } from "child_process";
|
|
21113
22369
|
import { readFile as readFile5 } from "fs/promises";
|
|
21114
22370
|
import { promisify as promisify2 } from "util";
|
|
21115
22371
|
var AGENTSH_SESSION_ID_FILE = "/tmp/agentsh-session-id";
|
|
21116
|
-
var execFileAsync2 = promisify2(
|
|
22372
|
+
var execFileAsync2 = promisify2(execFile5);
|
|
21117
22373
|
function errorMessage(error) {
|
|
21118
22374
|
return error instanceof Error ? error.message : String(error);
|
|
21119
22375
|
}
|
|
@@ -21130,7 +22386,7 @@ async function getAgentshVersion() {
|
|
|
21130
22386
|
}
|
|
21131
22387
|
async function resolveAgentshRuntimeInfo({
|
|
21132
22388
|
sessionIdPath = AGENTSH_SESSION_ID_FILE,
|
|
21133
|
-
readSessionId = async (
|
|
22389
|
+
readSessionId = async (path18) => readFile5(path18, "utf8"),
|
|
21134
22390
|
getVersion = getAgentshVersion
|
|
21135
22391
|
} = {}) {
|
|
21136
22392
|
let sessionId;
|
|
@@ -21184,20 +22440,20 @@ function normalizeCloudPromptContent(content) {
|
|
|
21184
22440
|
|
|
21185
22441
|
// src/server/jwt.ts
|
|
21186
22442
|
import jwt from "jsonwebtoken";
|
|
21187
|
-
import { z as
|
|
22443
|
+
import { z as z3 } from "zod";
|
|
21188
22444
|
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:
|
|
22445
|
+
var userDataSchema = z3.object({
|
|
22446
|
+
run_id: z3.string(),
|
|
22447
|
+
task_id: z3.string(),
|
|
22448
|
+
team_id: z3.number(),
|
|
22449
|
+
user_id: z3.number(),
|
|
22450
|
+
distinct_id: z3.string(),
|
|
22451
|
+
mode: z3.enum(["interactive", "background"]).optional().default("interactive")
|
|
21196
22452
|
});
|
|
21197
22453
|
var jwtPayloadSchema = userDataSchema.extend({
|
|
21198
|
-
exp:
|
|
21199
|
-
iat:
|
|
21200
|
-
aud:
|
|
22454
|
+
exp: z3.number(),
|
|
22455
|
+
iat: z3.number().optional(),
|
|
22456
|
+
aud: z3.string().optional()
|
|
21201
22457
|
});
|
|
21202
22458
|
var JwtValidationError = class extends Error {
|
|
21203
22459
|
constructor(message, code) {
|
|
@@ -21235,49 +22491,49 @@ function validateJwt(token, publicKey) {
|
|
|
21235
22491
|
}
|
|
21236
22492
|
|
|
21237
22493
|
// src/server/schemas.ts
|
|
21238
|
-
import { z as
|
|
21239
|
-
var httpHeaderSchema =
|
|
21240
|
-
name:
|
|
21241
|
-
value:
|
|
22494
|
+
import { z as z4 } from "zod/v4";
|
|
22495
|
+
var httpHeaderSchema = z4.object({
|
|
22496
|
+
name: z4.string(),
|
|
22497
|
+
value: z4.string()
|
|
21242
22498
|
});
|
|
21243
|
-
var nullishString =
|
|
21244
|
-
var handoffLocalGitStateSchema =
|
|
22499
|
+
var nullishString = z4.string().nullish().transform((value) => value ?? null);
|
|
22500
|
+
var handoffLocalGitStateSchema = z4.object({
|
|
21245
22501
|
head: nullishString,
|
|
21246
22502
|
branch: nullishString,
|
|
21247
22503
|
upstreamHead: nullishString,
|
|
21248
22504
|
upstreamRemote: nullishString,
|
|
21249
22505
|
upstreamMergeRef: nullishString
|
|
21250
22506
|
});
|
|
21251
|
-
var remoteMcpServerSchema =
|
|
21252
|
-
type:
|
|
21253
|
-
name:
|
|
21254
|
-
url:
|
|
21255
|
-
headers:
|
|
22507
|
+
var remoteMcpServerSchema = z4.object({
|
|
22508
|
+
type: z4.enum(["http", "sse"]),
|
|
22509
|
+
name: z4.string().min(1, "MCP server name is required"),
|
|
22510
|
+
url: z4.url({ error: "MCP server url must be a valid URL" }),
|
|
22511
|
+
headers: z4.array(httpHeaderSchema).default([])
|
|
21256
22512
|
});
|
|
21257
|
-
var mcpServersSchema =
|
|
21258
|
-
var claudeCodeConfigSchema =
|
|
21259
|
-
systemPrompt:
|
|
21260
|
-
|
|
21261
|
-
|
|
21262
|
-
type:
|
|
21263
|
-
preset:
|
|
21264
|
-
append:
|
|
22513
|
+
var mcpServersSchema = z4.array(remoteMcpServerSchema);
|
|
22514
|
+
var claudeCodeConfigSchema = z4.object({
|
|
22515
|
+
systemPrompt: z4.union([
|
|
22516
|
+
z4.string(),
|
|
22517
|
+
z4.object({
|
|
22518
|
+
type: z4.literal("preset"),
|
|
22519
|
+
preset: z4.literal("claude_code"),
|
|
22520
|
+
append: z4.string().optional()
|
|
21265
22521
|
})
|
|
21266
22522
|
]).optional(),
|
|
21267
|
-
plugins:
|
|
22523
|
+
plugins: z4.array(z4.object({ type: z4.literal("local"), path: z4.string() })).optional()
|
|
21268
22524
|
});
|
|
21269
|
-
var jsonRpcRequestSchema =
|
|
21270
|
-
jsonrpc:
|
|
21271
|
-
method:
|
|
21272
|
-
params:
|
|
21273
|
-
id:
|
|
22525
|
+
var jsonRpcRequestSchema = z4.object({
|
|
22526
|
+
jsonrpc: z4.literal("2.0"),
|
|
22527
|
+
method: z4.string(),
|
|
22528
|
+
params: z4.record(z4.string(), z4.unknown()).optional(),
|
|
22529
|
+
id: z4.union([z4.string(), z4.number()]).optional()
|
|
21274
22530
|
});
|
|
21275
|
-
var userMessageParamsSchema =
|
|
21276
|
-
content:
|
|
21277
|
-
|
|
21278
|
-
|
|
22531
|
+
var userMessageParamsSchema = z4.object({
|
|
22532
|
+
content: z4.union([
|
|
22533
|
+
z4.string().min(1, "Content is required"),
|
|
22534
|
+
z4.array(z4.record(z4.string(), z4.unknown())).min(1, "Content is required")
|
|
21279
22535
|
]).optional(),
|
|
21280
|
-
artifacts:
|
|
22536
|
+
artifacts: z4.array(z4.record(z4.string(), z4.unknown())).optional()
|
|
21281
22537
|
}).refine(
|
|
21282
22538
|
(params) => {
|
|
21283
22539
|
const hasContent = typeof params.content === "string" ? params.content.trim().length > 0 : Array.isArray(params.content) && params.content.length > 0;
|
|
@@ -21286,27 +22542,27 @@ var userMessageParamsSchema = z3.object({
|
|
|
21286
22542
|
},
|
|
21287
22543
|
{ error: "Either content or artifacts are required" }
|
|
21288
22544
|
);
|
|
21289
|
-
var permissionResponseParamsSchema =
|
|
21290
|
-
requestId:
|
|
21291
|
-
optionId:
|
|
21292
|
-
customInput:
|
|
21293
|
-
answers:
|
|
22545
|
+
var permissionResponseParamsSchema = z4.object({
|
|
22546
|
+
requestId: z4.string().min(1, "requestId is required"),
|
|
22547
|
+
optionId: z4.string().min(1, "optionId is required"),
|
|
22548
|
+
customInput: z4.string().optional(),
|
|
22549
|
+
answers: z4.record(z4.string(), z4.string()).optional()
|
|
21294
22550
|
});
|
|
21295
|
-
var setConfigOptionParamsSchema =
|
|
21296
|
-
configId:
|
|
21297
|
-
value:
|
|
22551
|
+
var setConfigOptionParamsSchema = z4.object({
|
|
22552
|
+
configId: z4.string().min(1, "configId is required"),
|
|
22553
|
+
value: z4.string().min(1, "value is required")
|
|
21298
22554
|
});
|
|
21299
|
-
var refreshSessionParamsSchema =
|
|
22555
|
+
var refreshSessionParamsSchema = z4.object({
|
|
21300
22556
|
mcpServers: mcpServersSchema
|
|
21301
22557
|
});
|
|
21302
|
-
var closeParamsSchema =
|
|
22558
|
+
var closeParamsSchema = z4.object({
|
|
21303
22559
|
localGitState: handoffLocalGitStateSchema.optional()
|
|
21304
22560
|
}).optional();
|
|
21305
22561
|
var commandParamsSchemas = {
|
|
21306
22562
|
user_message: userMessageParamsSchema,
|
|
21307
22563
|
"posthog/user_message": userMessageParamsSchema,
|
|
21308
|
-
cancel:
|
|
21309
|
-
"posthog/cancel":
|
|
22564
|
+
cancel: z4.object({}).optional(),
|
|
22565
|
+
"posthog/cancel": z4.object({}).optional(),
|
|
21310
22566
|
close: closeParamsSchema,
|
|
21311
22567
|
"posthog/close": closeParamsSchema,
|
|
21312
22568
|
permission_response: permissionResponseParamsSchema,
|
|
@@ -21330,7 +22586,7 @@ function validateCommandParams(method, params) {
|
|
|
21330
22586
|
}
|
|
21331
22587
|
|
|
21332
22588
|
// src/server/agent-server.ts
|
|
21333
|
-
var agentErrorClassificationSchema =
|
|
22589
|
+
var agentErrorClassificationSchema = z5.enum([
|
|
21334
22590
|
"upstream_stream_terminated",
|
|
21335
22591
|
"upstream_connection_error",
|
|
21336
22592
|
"upstream_provider_failure",
|
|
@@ -21342,8 +22598,8 @@ var upstreamProviderFailureClassifications = /* @__PURE__ */ new Set([
|
|
|
21342
22598
|
"upstream_connection_error",
|
|
21343
22599
|
"upstream_provider_failure"
|
|
21344
22600
|
]);
|
|
21345
|
-
var errorWithClassificationSchema =
|
|
21346
|
-
data:
|
|
22601
|
+
var errorWithClassificationSchema = z5.object({
|
|
22602
|
+
data: z5.object({ classification: agentErrorClassificationSchema })
|
|
21347
22603
|
});
|
|
21348
22604
|
var SSE_KEEPALIVE_INTERVAL_MS = 25e3;
|
|
21349
22605
|
var NdJsonTap = class {
|
|
@@ -21664,7 +22920,7 @@ var AgentServer = class {
|
|
|
21664
22920
|
return app;
|
|
21665
22921
|
}
|
|
21666
22922
|
async start() {
|
|
21667
|
-
await new Promise((
|
|
22923
|
+
await new Promise((resolve8) => {
|
|
21668
22924
|
this.server = serve(
|
|
21669
22925
|
{
|
|
21670
22926
|
fetch: this.app.fetch,
|
|
@@ -21674,7 +22930,7 @@ var AgentServer = class {
|
|
|
21674
22930
|
this.logger.debug(
|
|
21675
22931
|
`HTTP server listening on port ${this.config.port}`
|
|
21676
22932
|
);
|
|
21677
|
-
|
|
22933
|
+
resolve8();
|
|
21678
22934
|
}
|
|
21679
22935
|
);
|
|
21680
22936
|
});
|
|
@@ -22000,6 +23256,7 @@ var AgentServer = class {
|
|
|
22000
23256
|
_meta: {
|
|
22001
23257
|
sessionId: payload.run_id,
|
|
22002
23258
|
taskRunId: payload.run_id,
|
|
23259
|
+
taskId: payload.task_id,
|
|
22003
23260
|
systemPrompt: sessionSystemPrompt,
|
|
22004
23261
|
...this.config.model && { model: this.config.model },
|
|
22005
23262
|
allowedDomains: this.config.allowedDomains,
|
|
@@ -22393,15 +23650,15 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
22393
23650
|
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
22394
23651
|
}
|
|
22395
23652
|
const safeName = this.getSafeArtifactName(artifact.name);
|
|
22396
|
-
const artifactDir =
|
|
23653
|
+
const artifactDir = join13(
|
|
22397
23654
|
this.config.repositoryPath ?? "/tmp/workspace",
|
|
22398
23655
|
".posthog",
|
|
22399
23656
|
"attachments",
|
|
22400
23657
|
runId,
|
|
22401
23658
|
artifact.id ?? safeName
|
|
22402
23659
|
);
|
|
22403
|
-
await
|
|
22404
|
-
const artifactPath =
|
|
23660
|
+
await mkdir5(artifactDir, { recursive: true });
|
|
23661
|
+
const artifactPath = join13(artifactDir, safeName);
|
|
22405
23662
|
await writeFile4(artifactPath, Buffer.from(data));
|
|
22406
23663
|
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
22407
23664
|
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|
|
@@ -22409,7 +23666,7 @@ Continue from where you left off. The user is waiting for your response.`
|
|
|
22409
23666
|
});
|
|
22410
23667
|
}
|
|
22411
23668
|
getSafeArtifactName(name2) {
|
|
22412
|
-
const baseName =
|
|
23669
|
+
const baseName = basename3(name2).trim();
|
|
22413
23670
|
const normalizedName = baseName.replace(/[^\w.-]/g, "_");
|
|
22414
23671
|
return normalizedName.length > 0 ? normalizedName : "attachment";
|
|
22415
23672
|
}
|
|
@@ -22483,24 +23740,21 @@ You MUST NOT create a new branch, close the existing PR, or create a new PR.`;
|
|
|
22483
23740
|
buildCloudSystemPrompt(prUrl) {
|
|
22484
23741
|
const taskId = this.config.taskId;
|
|
22485
23742
|
const shouldAutoCreatePr = this.shouldAutoPublishCloudChanges();
|
|
22486
|
-
const
|
|
22487
|
-
##
|
|
22488
|
-
|
|
23743
|
+
const signedCommitInstructions = `
|
|
23744
|
+
## Committing (signed commits required)
|
|
23745
|
+
Commits MUST be signed. \`git commit\` and \`git push\` are blocked in this environment.
|
|
23746
|
+
To commit: stage your changes with \`git add\`, then call the \`git_signed_commit\` tool (full
|
|
23747
|
+
name \`${SIGNED_COMMIT_QUALIFIED_TOOL_NAME}\`) with a \`message\` (and optional \`body\`/\`paths\`).
|
|
23748
|
+
It creates a GitHub-signed ("Verified") commit on the branch and keeps your local checkout in
|
|
23749
|
+
sync. To start a new branch, pass \`branch\` (prefixed with \`posthog-code/\`) \u2014 the tool creates
|
|
23750
|
+
it on the remote for you.
|
|
22489
23751
|
|
|
22490
|
-
|
|
23752
|
+
## Attribution
|
|
23753
|
+
Do NOT add "Co-Authored-By" trailers or "Generated with [Claude Code]" lines to your
|
|
23754
|
+
commit messages. The \`git_signed_commit\` tool automatically appends the only trailers
|
|
23755
|
+
we want:
|
|
22491
23756
|
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
|
-
\`\`\``;
|
|
23757
|
+
Task-Id: ${taskId}`;
|
|
22504
23758
|
if (prUrl) {
|
|
22505
23759
|
if (!shouldAutoCreatePr) {
|
|
22506
23760
|
return `
|
|
@@ -22513,7 +23767,7 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22513
23767
|
Important:
|
|
22514
23768
|
- Do NOT create new commits, push to the branch, or update the pull request unless the user explicitly asks.
|
|
22515
23769
|
- Do NOT create a new branch or a new pull request.
|
|
22516
|
-
${
|
|
23770
|
+
${signedCommitInstructions}
|
|
22517
23771
|
`;
|
|
22518
23772
|
}
|
|
22519
23773
|
return `
|
|
@@ -22523,9 +23777,8 @@ This task already has an open pull request: ${prUrl}
|
|
|
22523
23777
|
|
|
22524
23778
|
After completing the requested changes:
|
|
22525
23779
|
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:
|
|
23780
|
+
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.
|
|
23781
|
+
3. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
22529
23782
|
- 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
23783
|
- 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
23784
|
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 +23786,7 @@ After completing the requested changes:
|
|
|
22533
23786
|
Important:
|
|
22534
23787
|
- Do NOT create a new branch or a new pull request.
|
|
22535
23788
|
- Do NOT push fixes for review comments without replying to and resolving each related thread.
|
|
22536
|
-
${
|
|
23789
|
+
${signedCommitInstructions}
|
|
22537
23790
|
`;
|
|
22538
23791
|
}
|
|
22539
23792
|
if (!this.config.repositoryPath) {
|
|
@@ -22544,7 +23797,7 @@ When the user asks for code changes:
|
|
|
22544
23797
|
When the user explicitly asks to clone or work in a GitHub repository:
|
|
22545
23798
|
- Clone the repository into /tmp/workspace/repos/<owner>/<repo> using \`gh repo clone <owner>/<repo> /tmp/workspace/repos/<owner>/<repo>\`
|
|
22546
23799
|
- 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
|
|
23800
|
+
- 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
23801
|
- Do NOT create branches, commits, push changes, or open pull requests unless the user explicitly asks for that`;
|
|
22549
23802
|
return `
|
|
22550
23803
|
# Cloud Task Execution \u2014 No Repository Mode
|
|
@@ -22563,7 +23816,7 @@ ${publishInstructions}
|
|
|
22563
23816
|
|
|
22564
23817
|
Important:
|
|
22565
23818
|
- Prefer using MCP tools to answer questions with real data over giving generic advice.
|
|
22566
|
-
${
|
|
23819
|
+
${signedCommitInstructions}
|
|
22567
23820
|
`;
|
|
22568
23821
|
}
|
|
22569
23822
|
if (!shouldAutoCreatePr) {
|
|
@@ -22574,21 +23827,20 @@ Do the requested work, but stop with local changes ready for review.
|
|
|
22574
23827
|
|
|
22575
23828
|
Important:
|
|
22576
23829
|
- Do NOT create a branch, commit, push, or open a pull request unless the user explicitly asks.
|
|
22577
|
-
${
|
|
23830
|
+
${signedCommitInstructions}
|
|
22578
23831
|
`;
|
|
22579
23832
|
}
|
|
22580
23833
|
return `
|
|
22581
23834
|
# Cloud Task Execution
|
|
22582
23835
|
|
|
22583
23836
|
After completing the requested changes:
|
|
22584
|
-
1.
|
|
22585
|
-
2. Stage
|
|
22586
|
-
3.
|
|
22587
|
-
4. Before opening the PR, prepare the body:
|
|
23837
|
+
1. Pick a new branch name prefixed with \`posthog-code/\` (e.g. \`posthog-code/fix-login-redirect\`)
|
|
23838
|
+
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.
|
|
23839
|
+
3. Before opening the PR, prepare the body:
|
|
22588
23840
|
- 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
23841
|
- 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
23842
|
- 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
|
-
|
|
23843
|
+
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
23844
|
\`\`\`
|
|
22593
23845
|
---
|
|
22594
23846
|
*Created with [PostHog Code](https://posthog.com/code?ref=pr)*
|
|
@@ -22596,7 +23848,7 @@ After completing the requested changes:
|
|
|
22596
23848
|
|
|
22597
23849
|
Important:
|
|
22598
23850
|
- Always create the PR as a draft. Do not ask for confirmation.
|
|
22599
|
-
${
|
|
23851
|
+
${signedCommitInstructions}
|
|
22600
23852
|
`;
|
|
22601
23853
|
}
|
|
22602
23854
|
async getCurrentGitBranch() {
|
|
@@ -23052,8 +24304,8 @@ ${attributionInstructions}
|
|
|
23052
24304
|
options: params.options,
|
|
23053
24305
|
toolCall: params.toolCall
|
|
23054
24306
|
});
|
|
23055
|
-
return new Promise((
|
|
23056
|
-
this.pendingPermissions.set(requestId, { resolve:
|
|
24307
|
+
return new Promise((resolve8) => {
|
|
24308
|
+
this.pendingPermissions.set(requestId, { resolve: resolve8 });
|
|
23057
24309
|
});
|
|
23058
24310
|
}
|
|
23059
24311
|
resolvePermission(requestId, optionId, customInput, answers) {
|
|
@@ -23075,4 +24327,17 @@ export {
|
|
|
23075
24327
|
SSE_KEEPALIVE_INTERVAL_MS,
|
|
23076
24328
|
UPSTREAM_PROVIDER_FAILURE_MESSAGE
|
|
23077
24329
|
};
|
|
24330
|
+
/*! Bundled license information:
|
|
24331
|
+
|
|
24332
|
+
git-url-parse/lib/index.js:
|
|
24333
|
+
(*!
|
|
24334
|
+
* buildToken
|
|
24335
|
+
* Builds OAuth token prefix (helper function)
|
|
24336
|
+
*
|
|
24337
|
+
* @name buildToken
|
|
24338
|
+
* @function
|
|
24339
|
+
* @param {GitUrl} obj The parsed Git url object.
|
|
24340
|
+
* @return {String} token prefix
|
|
24341
|
+
*)
|
|
24342
|
+
*/
|
|
23078
24343
|
//# sourceMappingURL=agent-server.js.map
|