@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.
Files changed (37) hide show
  1. package/dist/adapters/claude/permissions/permission-options.js +700 -0
  2. package/dist/adapters/claude/permissions/permission-options.js.map +1 -1
  3. package/dist/adapters/claude/tools.js +700 -0
  4. package/dist/adapters/claude/tools.js.map +1 -1
  5. package/dist/adapters/codex/local-tools-mcp-server.d.ts +2 -0
  6. package/dist/adapters/codex/local-tools-mcp-server.js +1172 -0
  7. package/dist/adapters/codex/local-tools-mcp-server.js.map +1 -0
  8. package/dist/agent.js +1488 -219
  9. package/dist/agent.js.map +1 -1
  10. package/dist/execution-mode.js +700 -0
  11. package/dist/execution-mode.js.map +1 -1
  12. package/dist/handoff-checkpoint.js.map +1 -1
  13. package/dist/posthog-api.js +1 -1
  14. package/dist/posthog-api.js.map +1 -1
  15. package/dist/server/agent-server.js +1604 -339
  16. package/dist/server/agent-server.js.map +1 -1
  17. package/dist/server/bin.cjs +1520 -258
  18. package/dist/server/bin.cjs.map +1 -1
  19. package/package.json +3 -3
  20. package/src/adapters/claude/claude-agent.ts +32 -2
  21. package/src/adapters/claude/hooks.test.ts +54 -0
  22. package/src/adapters/claude/hooks.ts +86 -0
  23. package/src/adapters/claude/mcp/local-tools.test.ts +50 -0
  24. package/src/adapters/claude/mcp/local-tools.ts +40 -0
  25. package/src/adapters/claude/session/options.ts +14 -9
  26. package/src/adapters/claude/types.ts +1 -0
  27. package/src/adapters/codex/codex-agent.ts +117 -22
  28. package/src/adapters/codex/local-tools-mcp-server.ts +71 -0
  29. package/src/adapters/local-tools/index.ts +22 -0
  30. package/src/adapters/local-tools/registry.test.ts +57 -0
  31. package/src/adapters/local-tools/registry.ts +81 -0
  32. package/src/adapters/local-tools/tools/signed-commit.ts +26 -0
  33. package/src/adapters/session-meta.ts +16 -0
  34. package/src/adapters/signed-commit-shared.ts +82 -0
  35. package/src/server/agent-server.test.ts +2 -4
  36. package/src/server/agent-server.ts +27 -30
  37. package/src/utils/common.ts +14 -0
package/dist/agent.js CHANGED
@@ -63,11 +63,11 @@ var require_tree_sitter = __commonJS({
63
63
  throw toThrow;
64
64
  };
65
65
  var scriptDirectory = "";
66
- function locateFile(path16) {
66
+ function locateFile(path17) {
67
67
  if (Module["locateFile"]) {
68
- return Module["locateFile"](path16, scriptDirectory);
68
+ return Module["locateFile"](path17, scriptDirectory);
69
69
  }
70
- return scriptDirectory + path16;
70
+ return scriptDirectory + path17;
71
71
  }
72
72
  var readAsync, readBinary;
73
73
  if (ENVIRONMENT_IS_NODE) {
@@ -81,10 +81,10 @@ var require_tree_sitter = __commonJS({
81
81
  };
82
82
  readAsync = (filename, binary2 = true) => {
83
83
  filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
84
- return new Promise((resolve6, reject) => {
84
+ return new Promise((resolve7, reject) => {
85
85
  fs.readFile(filename, binary2 ? void 0 : "utf8", (err2, data) => {
86
86
  if (err2) reject(err2);
87
- else resolve6(binary2 ? data.buffer : data);
87
+ else resolve7(binary2 ? data.buffer : data);
88
88
  });
89
89
  });
90
90
  };
@@ -125,13 +125,13 @@ var require_tree_sitter = __commonJS({
125
125
  }
126
126
  readAsync = (url) => {
127
127
  if (isFileURI(url)) {
128
- return new Promise((reject, resolve6) => {
128
+ return new Promise((reject, resolve7) => {
129
129
  var xhr = new XMLHttpRequest();
130
130
  xhr.open("GET", url, true);
131
131
  xhr.responseType = "arraybuffer";
132
132
  xhr.onload = () => {
133
133
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
134
- resolve6(xhr.response);
134
+ resolve7(xhr.response);
135
135
  }
136
136
  reject(xhr.status);
137
137
  };
@@ -1091,8 +1091,8 @@ var require_tree_sitter = __commonJS({
1091
1091
  }
1092
1092
  var libFile = locateFile(libName2);
1093
1093
  if (flags2.loadAsync) {
1094
- return new Promise(function(resolve6, reject) {
1095
- asyncLoad(libFile, resolve6, reject);
1094
+ return new Promise(function(resolve7, reject) {
1095
+ asyncLoad(libFile, resolve7, reject);
1096
1096
  });
1097
1097
  }
1098
1098
  if (!readBinary) {
@@ -2588,8 +2588,8 @@ var require_tree_sitter = __commonJS({
2588
2588
  } else {
2589
2589
  const url = input;
2590
2590
  if (typeof process !== "undefined" && process.versions && process.versions.node) {
2591
- const fs12 = __require("fs");
2592
- bytes = Promise.resolve(fs12.readFileSync(url));
2591
+ const fs13 = __require("fs");
2592
+ bytes = Promise.resolve(fs13.readFileSync(url));
2593
2593
  } else {
2594
2594
  bytes = fetch(url).then((response) => response.arrayBuffer().then((buffer) => {
2595
2595
  if (response.ok) {
@@ -2917,6 +2917,650 @@ ${JSON.stringify(symbolNames, null, 2)}`);
2917
2917
  }
2918
2918
  });
2919
2919
 
2920
+ // ../../node_modules/protocols/lib/index.js
2921
+ var require_lib = __commonJS({
2922
+ "../../node_modules/protocols/lib/index.js"(exports2, module2) {
2923
+ "use strict";
2924
+ module2.exports = function protocols(input, first2) {
2925
+ if (first2 === true) {
2926
+ first2 = 0;
2927
+ }
2928
+ var prots = "";
2929
+ if (typeof input === "string") {
2930
+ try {
2931
+ prots = new URL(input).protocol;
2932
+ } catch (e) {
2933
+ }
2934
+ } else if (input && input.constructor === URL) {
2935
+ prots = input.protocol;
2936
+ }
2937
+ var splits = prots.split(/\:|\+/).filter(Boolean);
2938
+ if (typeof first2 === "number") {
2939
+ return splits[first2];
2940
+ }
2941
+ return splits;
2942
+ };
2943
+ }
2944
+ });
2945
+
2946
+ // ../../node_modules/parse-path/lib/index.js
2947
+ var require_lib2 = __commonJS({
2948
+ "../../node_modules/parse-path/lib/index.js"(exports2, module2) {
2949
+ "use strict";
2950
+ var protocols = require_lib();
2951
+ function parsePath(url) {
2952
+ var output = {
2953
+ protocols: [],
2954
+ protocol: null,
2955
+ port: null,
2956
+ resource: "",
2957
+ host: "",
2958
+ user: "",
2959
+ password: "",
2960
+ pathname: "",
2961
+ hash: "",
2962
+ search: "",
2963
+ href: url,
2964
+ query: {},
2965
+ parse_failed: false
2966
+ };
2967
+ try {
2968
+ var parsed = new URL(url);
2969
+ output.protocols = protocols(parsed);
2970
+ output.protocol = output.protocols[0];
2971
+ output.port = parsed.port;
2972
+ output.resource = parsed.hostname;
2973
+ output.host = parsed.host;
2974
+ output.user = parsed.username || "";
2975
+ output.password = parsed.password || "";
2976
+ output.pathname = parsed.pathname;
2977
+ output.hash = parsed.hash.slice(1);
2978
+ output.search = parsed.search.slice(1);
2979
+ output.href = parsed.href;
2980
+ output.query = Object.fromEntries(parsed.searchParams);
2981
+ } catch (e) {
2982
+ output.protocols = ["file"];
2983
+ output.protocol = output.protocols[0];
2984
+ output.port = "";
2985
+ output.resource = "";
2986
+ output.user = "";
2987
+ output.pathname = "";
2988
+ output.hash = "";
2989
+ output.search = "";
2990
+ output.href = url;
2991
+ output.query = {};
2992
+ output.parse_failed = true;
2993
+ }
2994
+ return output;
2995
+ }
2996
+ module2.exports = parsePath;
2997
+ }
2998
+ });
2999
+
3000
+ // ../../node_modules/parse-url/dist/index.js
3001
+ var require_dist = __commonJS({
3002
+ "../../node_modules/parse-url/dist/index.js"(exports2, module2) {
3003
+ "use strict";
3004
+ var require$$1 = require_lib2();
3005
+ function _interopDefaultLegacy(e) {
3006
+ return e && typeof e === "object" && "default" in e ? e : { "default": e };
3007
+ }
3008
+ var require$$1__default = /* @__PURE__ */ _interopDefaultLegacy(require$$1);
3009
+ function getAugmentedNamespace(n) {
3010
+ if (n.__esModule) return n;
3011
+ var f = n.default;
3012
+ if (typeof f == "function") {
3013
+ var a = function a2() {
3014
+ if (this instanceof a2) {
3015
+ var args2 = [null];
3016
+ args2.push.apply(args2, arguments);
3017
+ var Ctor = Function.bind.apply(f, args2);
3018
+ return new Ctor();
3019
+ }
3020
+ return f.apply(this, arguments);
3021
+ };
3022
+ a.prototype = f.prototype;
3023
+ } else a = {};
3024
+ Object.defineProperty(a, "__esModule", { value: true });
3025
+ Object.keys(n).forEach(function(k) {
3026
+ var d = Object.getOwnPropertyDescriptor(n, k);
3027
+ Object.defineProperty(a, k, d.get ? d : {
3028
+ enumerable: true,
3029
+ get: function() {
3030
+ return n[k];
3031
+ }
3032
+ });
3033
+ });
3034
+ return a;
3035
+ }
3036
+ var src = {};
3037
+ var DATA_URL_DEFAULT_MIME_TYPE = "text/plain";
3038
+ var DATA_URL_DEFAULT_CHARSET = "us-ascii";
3039
+ var testParameter = (name2, filters) => filters.some((filter) => filter instanceof RegExp ? filter.test(name2) : filter === name2);
3040
+ var normalizeDataURL = (urlString, { stripHash }) => {
3041
+ const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
3042
+ if (!match) {
3043
+ throw new Error(`Invalid URL: ${urlString}`);
3044
+ }
3045
+ let { type, data, hash } = match.groups;
3046
+ const mediaType = type.split(";");
3047
+ hash = stripHash ? "" : hash;
3048
+ let isBase64 = false;
3049
+ if (mediaType[mediaType.length - 1] === "base64") {
3050
+ mediaType.pop();
3051
+ isBase64 = true;
3052
+ }
3053
+ const mimeType = (mediaType.shift() || "").toLowerCase();
3054
+ const attributes = mediaType.map((attribute) => {
3055
+ let [key, value = ""] = attribute.split("=").map((string) => string.trim());
3056
+ if (key === "charset") {
3057
+ value = value.toLowerCase();
3058
+ if (value === DATA_URL_DEFAULT_CHARSET) {
3059
+ return "";
3060
+ }
3061
+ }
3062
+ return `${key}${value ? `=${value}` : ""}`;
3063
+ }).filter(Boolean);
3064
+ const normalizedMediaType = [
3065
+ ...attributes
3066
+ ];
3067
+ if (isBase64) {
3068
+ normalizedMediaType.push("base64");
3069
+ }
3070
+ if (normalizedMediaType.length > 0 || mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE) {
3071
+ normalizedMediaType.unshift(mimeType);
3072
+ }
3073
+ return `data:${normalizedMediaType.join(";")},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ""}`;
3074
+ };
3075
+ function normalizeUrl(urlString, options) {
3076
+ options = {
3077
+ defaultProtocol: "http:",
3078
+ normalizeProtocol: true,
3079
+ forceHttp: false,
3080
+ forceHttps: false,
3081
+ stripAuthentication: true,
3082
+ stripHash: false,
3083
+ stripTextFragment: true,
3084
+ stripWWW: true,
3085
+ removeQueryParameters: [/^utm_\w+/i],
3086
+ removeTrailingSlash: true,
3087
+ removeSingleSlash: true,
3088
+ removeDirectoryIndex: false,
3089
+ sortQueryParameters: true,
3090
+ ...options
3091
+ };
3092
+ urlString = urlString.trim();
3093
+ if (/^data:/i.test(urlString)) {
3094
+ return normalizeDataURL(urlString, options);
3095
+ }
3096
+ if (/^view-source:/i.test(urlString)) {
3097
+ throw new Error("`view-source:` is not supported as it is a non-standard protocol");
3098
+ }
3099
+ const hasRelativeProtocol = urlString.startsWith("//");
3100
+ const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
3101
+ if (!isRelativeUrl) {
3102
+ urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
3103
+ }
3104
+ const urlObject = new URL(urlString);
3105
+ if (options.forceHttp && options.forceHttps) {
3106
+ throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");
3107
+ }
3108
+ if (options.forceHttp && urlObject.protocol === "https:") {
3109
+ urlObject.protocol = "http:";
3110
+ }
3111
+ if (options.forceHttps && urlObject.protocol === "http:") {
3112
+ urlObject.protocol = "https:";
3113
+ }
3114
+ if (options.stripAuthentication) {
3115
+ urlObject.username = "";
3116
+ urlObject.password = "";
3117
+ }
3118
+ if (options.stripHash) {
3119
+ urlObject.hash = "";
3120
+ } else if (options.stripTextFragment) {
3121
+ urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, "");
3122
+ }
3123
+ if (urlObject.pathname) {
3124
+ const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
3125
+ let lastIndex = 0;
3126
+ let result = "";
3127
+ for (; ; ) {
3128
+ const match = protocolRegex.exec(urlObject.pathname);
3129
+ if (!match) {
3130
+ break;
3131
+ }
3132
+ const protocol = match[0];
3133
+ const protocolAtIndex = match.index;
3134
+ const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
3135
+ result += intermediate.replace(/\/{2,}/g, "/");
3136
+ result += protocol;
3137
+ lastIndex = protocolAtIndex + protocol.length;
3138
+ }
3139
+ const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
3140
+ result += remnant.replace(/\/{2,}/g, "/");
3141
+ urlObject.pathname = result;
3142
+ }
3143
+ if (urlObject.pathname) {
3144
+ try {
3145
+ urlObject.pathname = decodeURI(urlObject.pathname);
3146
+ } catch {
3147
+ }
3148
+ }
3149
+ if (options.removeDirectoryIndex === true) {
3150
+ options.removeDirectoryIndex = [/^index\.[a-z]+$/];
3151
+ }
3152
+ if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
3153
+ let pathComponents = urlObject.pathname.split("/");
3154
+ const lastComponent = pathComponents[pathComponents.length - 1];
3155
+ if (testParameter(lastComponent, options.removeDirectoryIndex)) {
3156
+ pathComponents = pathComponents.slice(0, -1);
3157
+ urlObject.pathname = pathComponents.slice(1).join("/") + "/";
3158
+ }
3159
+ }
3160
+ if (urlObject.hostname) {
3161
+ urlObject.hostname = urlObject.hostname.replace(/\.$/, "");
3162
+ if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) {
3163
+ urlObject.hostname = urlObject.hostname.replace(/^www\./, "");
3164
+ }
3165
+ }
3166
+ if (Array.isArray(options.removeQueryParameters)) {
3167
+ for (const key of [...urlObject.searchParams.keys()]) {
3168
+ if (testParameter(key, options.removeQueryParameters)) {
3169
+ urlObject.searchParams.delete(key);
3170
+ }
3171
+ }
3172
+ }
3173
+ if (options.removeQueryParameters === true) {
3174
+ urlObject.search = "";
3175
+ }
3176
+ if (options.sortQueryParameters) {
3177
+ urlObject.searchParams.sort();
3178
+ try {
3179
+ urlObject.search = decodeURIComponent(urlObject.search);
3180
+ } catch {
3181
+ }
3182
+ }
3183
+ if (options.removeTrailingSlash) {
3184
+ urlObject.pathname = urlObject.pathname.replace(/\/$/, "");
3185
+ }
3186
+ const oldUrlString = urlString;
3187
+ urlString = urlObject.toString();
3188
+ if (!options.removeSingleSlash && urlObject.pathname === "/" && !oldUrlString.endsWith("/") && urlObject.hash === "") {
3189
+ urlString = urlString.replace(/\/$/, "");
3190
+ }
3191
+ if ((options.removeTrailingSlash || urlObject.pathname === "/") && urlObject.hash === "" && options.removeSingleSlash) {
3192
+ urlString = urlString.replace(/\/$/, "");
3193
+ }
3194
+ if (hasRelativeProtocol && !options.normalizeProtocol) {
3195
+ urlString = urlString.replace(/^http:\/\//, "//");
3196
+ }
3197
+ if (options.stripProtocol) {
3198
+ urlString = urlString.replace(/^(?:https?:)?\/\//, "");
3199
+ }
3200
+ return urlString;
3201
+ }
3202
+ var normalizeUrl$1 = /* @__PURE__ */ Object.freeze({
3203
+ __proto__: null,
3204
+ "default": normalizeUrl
3205
+ });
3206
+ var require$$0 = /* @__PURE__ */ getAugmentedNamespace(normalizeUrl$1);
3207
+ Object.defineProperty(src, "__esModule", {
3208
+ value: true
3209
+ });
3210
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
3211
+ return typeof obj;
3212
+ } : function(obj) {
3213
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
3214
+ };
3215
+ var _normalizeUrl = require$$0;
3216
+ var _normalizeUrl2 = _interopRequireDefault(_normalizeUrl);
3217
+ var _parsePath = require$$1__default["default"];
3218
+ var _parsePath2 = _interopRequireDefault(_parsePath);
3219
+ function _interopRequireDefault(obj) {
3220
+ return obj && obj.__esModule ? obj : { default: obj };
3221
+ }
3222
+ var parseUrl = function parseUrl2(url) {
3223
+ var normalize3 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
3224
+ var GIT_RE = /^(?:([a-zA-Z_][a-zA-Z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:](([\~,\.\w,\-,\_,\/,\s]|%[0-9A-Fa-f]{2})+?(?:\.git|\/)?)$/;
3225
+ var throwErr = function throwErr2(msg) {
3226
+ var err2 = new Error(msg);
3227
+ err2.subject_url = url;
3228
+ throw err2;
3229
+ };
3230
+ if (typeof url !== "string" || !url.trim()) {
3231
+ throwErr("Invalid url.");
3232
+ }
3233
+ if (url.length > parseUrl2.MAX_INPUT_LENGTH) {
3234
+ throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.");
3235
+ }
3236
+ if (normalize3) {
3237
+ if ((typeof normalize3 === "undefined" ? "undefined" : _typeof(normalize3)) !== "object") {
3238
+ normalize3 = {
3239
+ stripHash: false
3240
+ };
3241
+ }
3242
+ url = (0, _normalizeUrl2.default)(url, normalize3);
3243
+ }
3244
+ var parsed = (0, _parsePath2.default)(url);
3245
+ if (parsed.parse_failed) {
3246
+ var matched = parsed.href.match(GIT_RE);
3247
+ if (matched) {
3248
+ parsed.protocols = ["ssh"];
3249
+ parsed.protocol = "ssh";
3250
+ parsed.resource = matched[2];
3251
+ parsed.host = matched[2];
3252
+ parsed.user = matched[1];
3253
+ parsed.pathname = "/" + matched[3];
3254
+ parsed.parse_failed = false;
3255
+ } else {
3256
+ throwErr("URL parsing failed.");
3257
+ }
3258
+ }
3259
+ return parsed;
3260
+ };
3261
+ parseUrl.MAX_INPUT_LENGTH = 2048;
3262
+ var _default = src.default = parseUrl;
3263
+ module2.exports = _default;
3264
+ }
3265
+ });
3266
+
3267
+ // ../../node_modules/is-ssh/lib/index.js
3268
+ var require_lib3 = __commonJS({
3269
+ "../../node_modules/is-ssh/lib/index.js"(exports2, module2) {
3270
+ "use strict";
3271
+ var protocols = require_lib();
3272
+ function isSsh(input) {
3273
+ if (Array.isArray(input)) {
3274
+ return input.indexOf("ssh") !== -1 || input.indexOf("rsync") !== -1;
3275
+ }
3276
+ if (typeof input !== "string") {
3277
+ return false;
3278
+ }
3279
+ var prots = protocols(input);
3280
+ input = input.substring(input.indexOf("://") + 3);
3281
+ if (isSsh(prots)) {
3282
+ return true;
3283
+ }
3284
+ var urlPortPattern = new RegExp(".([a-zA-Z\\d]+):(\\d+)/");
3285
+ return !input.match(urlPortPattern) && input.indexOf("@") < input.indexOf(":");
3286
+ }
3287
+ module2.exports = isSsh;
3288
+ }
3289
+ });
3290
+
3291
+ // ../../node_modules/git-up/lib/index.js
3292
+ var require_lib4 = __commonJS({
3293
+ "../../node_modules/git-up/lib/index.js"(exports2, module2) {
3294
+ "use strict";
3295
+ var parseUrl = require_dist();
3296
+ var isSsh = require_lib3();
3297
+ function gitUp(input) {
3298
+ let output = parseUrl(input);
3299
+ output.token = "";
3300
+ if (output.password === "x-oauth-basic") {
3301
+ output.token = output.user;
3302
+ } else if (output.user === "x-token-auth") {
3303
+ output.token = output.password;
3304
+ }
3305
+ if (isSsh(output.protocols) || output.protocols.length === 0 && isSsh(input)) {
3306
+ output.protocol = "ssh";
3307
+ } else if (output.protocols.length) {
3308
+ output.protocol = output.protocols[0];
3309
+ } else {
3310
+ output.protocol = "file";
3311
+ output.protocols = ["file"];
3312
+ }
3313
+ output.href = output.href.replace(/\/$/, "");
3314
+ return output;
3315
+ }
3316
+ module2.exports = gitUp;
3317
+ }
3318
+ });
3319
+
3320
+ // ../../node_modules/git-url-parse/lib/index.js
3321
+ var require_lib5 = __commonJS({
3322
+ "../../node_modules/git-url-parse/lib/index.js"(exports2, module2) {
3323
+ "use strict";
3324
+ var gitUp = require_lib4();
3325
+ function gitUrlParse2(url, refs) {
3326
+ refs = refs || [];
3327
+ if (typeof url !== "string") {
3328
+ throw new Error("The url must be a string.");
3329
+ }
3330
+ if (!refs.every(function(item) {
3331
+ return typeof item === "string";
3332
+ })) {
3333
+ throw new Error("The refs should contain only strings");
3334
+ }
3335
+ var shorthandRe = /^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;
3336
+ if (shorthandRe.test(url)) {
3337
+ url = "https://github.com/" + url;
3338
+ }
3339
+ var urlInfo = gitUp(url), sourceParts = urlInfo.resource.split("."), splits = null;
3340
+ urlInfo.toString = function(type) {
3341
+ return gitUrlParse2.stringify(this, type);
3342
+ };
3343
+ urlInfo.source = sourceParts.length > 2 ? sourceParts.slice(1 - sourceParts.length).join(".") : urlInfo.source = urlInfo.resource;
3344
+ urlInfo.git_suffix = /\.git$/.test(urlInfo.pathname);
3345
+ urlInfo.name = decodeURIComponent((urlInfo.pathname || urlInfo.href).replace(/(^\/)|(\/$)/g, "").replace(/\.git$/, ""));
3346
+ urlInfo.owner = decodeURIComponent(urlInfo.user);
3347
+ switch (urlInfo.source) {
3348
+ case "git.cloudforge.com":
3349
+ urlInfo.owner = urlInfo.user;
3350
+ urlInfo.organization = sourceParts[0];
3351
+ urlInfo.source = "cloudforge.com";
3352
+ break;
3353
+ case "visualstudio.com":
3354
+ if (urlInfo.resource === "vs-ssh.visualstudio.com") {
3355
+ splits = urlInfo.name.split("/");
3356
+ if (splits.length === 4) {
3357
+ urlInfo.organization = splits[1];
3358
+ urlInfo.owner = splits[2];
3359
+ urlInfo.name = splits[3];
3360
+ urlInfo.full_name = splits[2] + "/" + splits[3];
3361
+ }
3362
+ break;
3363
+ } else {
3364
+ splits = urlInfo.name.split("/");
3365
+ if (splits.length === 2) {
3366
+ urlInfo.owner = splits[1];
3367
+ urlInfo.name = splits[1];
3368
+ urlInfo.full_name = "_git/" + urlInfo.name;
3369
+ } else if (splits.length === 3) {
3370
+ urlInfo.name = splits[2];
3371
+ if (splits[0] === "DefaultCollection") {
3372
+ urlInfo.owner = splits[2];
3373
+ urlInfo.organization = splits[0];
3374
+ urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
3375
+ } else {
3376
+ urlInfo.owner = splits[0];
3377
+ urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
3378
+ }
3379
+ } else if (splits.length === 4) {
3380
+ urlInfo.organization = splits[0];
3381
+ urlInfo.owner = splits[1];
3382
+ urlInfo.name = splits[3];
3383
+ urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
3384
+ }
3385
+ break;
3386
+ }
3387
+ // Azure DevOps (formerly Visual Studio Team Services)
3388
+ case "dev.azure.com":
3389
+ case "azure.com":
3390
+ if (urlInfo.resource === "ssh.dev.azure.com") {
3391
+ splits = urlInfo.name.split("/");
3392
+ if (splits.length === 4) {
3393
+ urlInfo.organization = splits[1];
3394
+ urlInfo.owner = splits[2];
3395
+ urlInfo.name = splits[3];
3396
+ }
3397
+ break;
3398
+ } else {
3399
+ splits = urlInfo.name.split("/");
3400
+ if (splits.length === 5) {
3401
+ urlInfo.organization = splits[0];
3402
+ urlInfo.owner = splits[1];
3403
+ urlInfo.name = splits[4];
3404
+ urlInfo.full_name = "_git/" + urlInfo.name;
3405
+ } else if (splits.length === 3) {
3406
+ urlInfo.name = splits[2];
3407
+ if (splits[0] === "DefaultCollection") {
3408
+ urlInfo.owner = splits[2];
3409
+ urlInfo.organization = splits[0];
3410
+ urlInfo.full_name = urlInfo.organization + "/_git/" + urlInfo.name;
3411
+ } else {
3412
+ urlInfo.owner = splits[0];
3413
+ urlInfo.full_name = urlInfo.owner + "/_git/" + urlInfo.name;
3414
+ }
3415
+ } else if (splits.length === 4) {
3416
+ urlInfo.organization = splits[0];
3417
+ urlInfo.owner = splits[1];
3418
+ urlInfo.name = splits[3];
3419
+ urlInfo.full_name = urlInfo.organization + "/" + urlInfo.owner + "/_git/" + urlInfo.name;
3420
+ }
3421
+ if (urlInfo.query && urlInfo.query["path"]) {
3422
+ urlInfo.filepath = urlInfo.query["path"].replace(/^\/+/g, "");
3423
+ }
3424
+ if (urlInfo.query && urlInfo.query["version"]) {
3425
+ urlInfo.ref = urlInfo.query["version"].replace(/^GB/, "");
3426
+ }
3427
+ break;
3428
+ }
3429
+ default:
3430
+ splits = urlInfo.name.split("/");
3431
+ var nameIndex = splits.length - 1;
3432
+ if (splits.length >= 2) {
3433
+ var dashIndex = splits.indexOf("-", 2);
3434
+ var blobIndex = splits.indexOf("blob", 2);
3435
+ var treeIndex = splits.indexOf("tree", 2);
3436
+ var commitIndex = splits.indexOf("commit", 2);
3437
+ var issuesIndex = splits.indexOf("issues", 2);
3438
+ var srcIndex = splits.indexOf("src", 2);
3439
+ var rawIndex = splits.indexOf("raw", 2);
3440
+ var editIndex = splits.indexOf("edit", 2);
3441
+ 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;
3442
+ urlInfo.owner = splits.slice(0, nameIndex).join("/");
3443
+ urlInfo.name = splits[nameIndex];
3444
+ if (commitIndex && issuesIndex < 0) {
3445
+ urlInfo.commit = splits[nameIndex + 2];
3446
+ }
3447
+ }
3448
+ urlInfo.ref = "";
3449
+ urlInfo.filepathtype = "";
3450
+ urlInfo.filepath = "";
3451
+ var offsetNameIndex = splits.length > nameIndex && splits[nameIndex + 1] === "-" ? nameIndex + 1 : nameIndex;
3452
+ if (splits.length > offsetNameIndex + 2 && ["raw", "src", "blob", "tree", "edit"].indexOf(splits[offsetNameIndex + 1]) >= 0) {
3453
+ urlInfo.filepathtype = splits[offsetNameIndex + 1];
3454
+ urlInfo.ref = splits[offsetNameIndex + 2];
3455
+ if (splits.length > offsetNameIndex + 3) {
3456
+ urlInfo.filepath = splits.slice(offsetNameIndex + 3).join("/");
3457
+ }
3458
+ }
3459
+ urlInfo.organization = urlInfo.owner;
3460
+ break;
3461
+ }
3462
+ if (!urlInfo.full_name) {
3463
+ urlInfo.full_name = urlInfo.owner;
3464
+ if (urlInfo.name) {
3465
+ urlInfo.full_name && (urlInfo.full_name += "/");
3466
+ urlInfo.full_name += urlInfo.name;
3467
+ }
3468
+ }
3469
+ if (urlInfo.owner.startsWith("scm/")) {
3470
+ urlInfo.source = "bitbucket-server";
3471
+ urlInfo.owner = urlInfo.owner.replace("scm/", "");
3472
+ urlInfo.organization = urlInfo.owner;
3473
+ urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
3474
+ }
3475
+ var bitbucket = /(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/;
3476
+ var matches = bitbucket.exec(urlInfo.pathname);
3477
+ if (matches != null) {
3478
+ urlInfo.source = "bitbucket-server";
3479
+ if (matches[1] === "users") {
3480
+ urlInfo.owner = "~" + matches[2];
3481
+ } else {
3482
+ urlInfo.owner = matches[2];
3483
+ }
3484
+ urlInfo.organization = urlInfo.owner;
3485
+ urlInfo.name = matches[3];
3486
+ splits = matches[4].split("/");
3487
+ if (splits.length > 1) {
3488
+ if (["raw", "browse"].indexOf(splits[1]) >= 0) {
3489
+ urlInfo.filepathtype = splits[1];
3490
+ if (splits.length > 2) {
3491
+ urlInfo.filepath = splits.slice(2).join("/");
3492
+ }
3493
+ } else if (splits[1] === "commits" && splits.length > 2) {
3494
+ urlInfo.commit = splits[2];
3495
+ }
3496
+ }
3497
+ urlInfo.full_name = urlInfo.owner + "/" + urlInfo.name;
3498
+ if (urlInfo.query.at) {
3499
+ urlInfo.ref = urlInfo.query.at;
3500
+ } else {
3501
+ urlInfo.ref = "";
3502
+ }
3503
+ }
3504
+ if (refs.length !== 0 && urlInfo.ref) {
3505
+ urlInfo.ref = findLongestMatchingSubstring(urlInfo.href, refs) || urlInfo.ref;
3506
+ urlInfo.filepath = urlInfo.href.split(urlInfo.ref + "/")[1];
3507
+ }
3508
+ return urlInfo;
3509
+ }
3510
+ gitUrlParse2.stringify = function(obj, type) {
3511
+ type = type || (obj.protocols && obj.protocols.length ? obj.protocols.join("+") : obj.protocol);
3512
+ var port = obj.port ? ":" + obj.port : "";
3513
+ var user = obj.user || "git";
3514
+ var maybeGitSuffix = obj.git_suffix ? ".git" : "";
3515
+ switch (type) {
3516
+ case "ssh":
3517
+ if (port) return "ssh://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
3518
+ else return user + "@" + obj.resource + ":" + obj.full_name + maybeGitSuffix;
3519
+ case "git+ssh":
3520
+ case "ssh+git":
3521
+ case "ftp":
3522
+ case "ftps":
3523
+ return type + "://" + user + "@" + obj.resource + port + "/" + obj.full_name + maybeGitSuffix;
3524
+ case "http":
3525
+ case "https":
3526
+ var auth = obj.token ? buildToken(obj) : obj.user && (obj.protocols.includes("http") || obj.protocols.includes("https")) ? obj.user + "@" : "";
3527
+ return type + "://" + auth + obj.resource + port + "/" + buildPath(obj) + maybeGitSuffix;
3528
+ default:
3529
+ return obj.href;
3530
+ }
3531
+ };
3532
+ function buildToken(obj) {
3533
+ switch (obj.source) {
3534
+ case "bitbucket.org":
3535
+ return "x-token-auth:" + obj.token + "@";
3536
+ default:
3537
+ return obj.token + "@";
3538
+ }
3539
+ }
3540
+ function buildPath(obj) {
3541
+ switch (obj.source) {
3542
+ case "bitbucket-server":
3543
+ return "scm/" + obj.full_name;
3544
+ default:
3545
+ var encoded_full_name = obj.full_name.split("/").map(function(x) {
3546
+ return encodeURIComponent(x);
3547
+ }).join("/");
3548
+ return encoded_full_name;
3549
+ }
3550
+ }
3551
+ function findLongestMatchingSubstring(string, array) {
3552
+ var longestMatch = "";
3553
+ array.forEach(function(item) {
3554
+ if (string.includes(item) && item.length > longestMatch.length) {
3555
+ longestMatch = item;
3556
+ }
3557
+ });
3558
+ return longestMatch;
3559
+ }
3560
+ module2.exports = gitUrlParse2;
3561
+ }
3562
+ });
3563
+
2920
3564
  // ../../node_modules/ms/index.js
2921
3565
  var require_ms = __commonJS({
2922
3566
  "../../node_modules/ms/index.js"(exports2, module2) {
@@ -3400,7 +4044,7 @@ var require_has_flag = __commonJS({
3400
4044
  var require_supports_color = __commonJS({
3401
4045
  "../../node_modules/supports-color/index.js"(exports2, module2) {
3402
4046
  "use strict";
3403
- var os7 = __require("os");
4047
+ var os8 = __require("os");
3404
4048
  var tty = __require("tty");
3405
4049
  var hasFlag = require_has_flag();
3406
4050
  var { env } = process;
@@ -3448,7 +4092,7 @@ var require_supports_color = __commonJS({
3448
4092
  return min;
3449
4093
  }
3450
4094
  if (process.platform === "win32") {
3451
- const osRelease = os7.release().split(".");
4095
+ const osRelease = os8.release().split(".");
3452
4096
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
3453
4097
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
3454
4098
  }
@@ -3696,10 +4340,10 @@ var require_src2 = __commonJS({
3696
4340
  var fs_1 = __require("fs");
3697
4341
  var debug_1 = __importDefault(require_src());
3698
4342
  var log = debug_1.default("@kwsites/file-exists");
3699
- function check(path16, isFile2, isDirectory) {
3700
- log(`checking %s`, path16);
4343
+ function check(path17, isFile2, isDirectory) {
4344
+ log(`checking %s`, path17);
3701
4345
  try {
3702
- const stat3 = fs_1.statSync(path16);
4346
+ const stat3 = fs_1.statSync(path17);
3703
4347
  if (stat3.isFile() && isFile2) {
3704
4348
  log(`[OK] path represents a file`);
3705
4349
  return true;
@@ -3719,8 +4363,8 @@ var require_src2 = __commonJS({
3719
4363
  throw e;
3720
4364
  }
3721
4365
  }
3722
- function exists2(path16, type = exports2.READABLE) {
3723
- return check(path16, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
4366
+ function exists2(path17, type = exports2.READABLE) {
4367
+ return check(path17, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
3724
4368
  }
3725
4369
  exports2.exists = exists2;
3726
4370
  exports2.FILE = 1;
@@ -3730,7 +4374,7 @@ var require_src2 = __commonJS({
3730
4374
  });
3731
4375
 
3732
4376
  // ../../node_modules/@kwsites/file-exists/dist/index.js
3733
- var require_dist = __commonJS({
4377
+ var require_dist2 = __commonJS({
3734
4378
  "../../node_modules/@kwsites/file-exists/dist/index.js"(exports2) {
3735
4379
  "use strict";
3736
4380
  function __export2(m) {
@@ -3742,7 +4386,7 @@ var require_dist = __commonJS({
3742
4386
  });
3743
4387
 
3744
4388
  // ../../node_modules/@kwsites/promise-deferred/dist/index.js
3745
- var require_dist2 = __commonJS({
4389
+ var require_dist3 = __commonJS({
3746
4390
  "../../node_modules/@kwsites/promise-deferred/dist/index.js"(exports2) {
3747
4391
  "use strict";
3748
4392
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -3846,17 +4490,17 @@ var Pushable = class {
3846
4490
  resolvers = [];
3847
4491
  done = false;
3848
4492
  push(item) {
3849
- const resolve6 = this.resolvers.shift();
3850
- if (resolve6) {
3851
- resolve6({ value: item, done: false });
4493
+ const resolve7 = this.resolvers.shift();
4494
+ if (resolve7) {
4495
+ resolve7({ value: item, done: false });
3852
4496
  } else {
3853
4497
  this.queue.push(item);
3854
4498
  }
3855
4499
  }
3856
4500
  end() {
3857
4501
  this.done = true;
3858
- for (const resolve6 of this.resolvers) {
3859
- resolve6({ value: void 0, done: true });
4502
+ for (const resolve7 of this.resolvers) {
4503
+ resolve7({ value: void 0, done: true });
3860
4504
  }
3861
4505
  this.resolvers = [];
3862
4506
  }
@@ -3873,8 +4517,8 @@ var Pushable = class {
3873
4517
  done: true
3874
4518
  });
3875
4519
  }
3876
- return new Promise((resolve6) => {
3877
- this.resolvers.push(resolve6);
4520
+ return new Promise((resolve7) => {
4521
+ this.resolvers.push(resolve7);
3878
4522
  });
3879
4523
  }
3880
4524
  };
@@ -3988,20 +4632,20 @@ function nodeReadableToWebReadable(nodeStream) {
3988
4632
  function nodeWritableToWebWritable(nodeStream) {
3989
4633
  return new WritableStream({
3990
4634
  write(chunk) {
3991
- return new Promise((resolve6, reject) => {
4635
+ return new Promise((resolve7, reject) => {
3992
4636
  const ok = nodeStream.write(Buffer.from(chunk), (err2) => {
3993
4637
  if (err2) reject(err2);
3994
4638
  });
3995
4639
  if (ok) {
3996
- resolve6();
4640
+ resolve7();
3997
4641
  } else {
3998
- nodeStream.once("drain", resolve6);
4642
+ nodeStream.once("drain", resolve7);
3999
4643
  }
4000
4644
  });
4001
4645
  },
4002
4646
  close() {
4003
- return new Promise((resolve6) => {
4004
- nodeStream.end(resolve6);
4647
+ return new Promise((resolve7) => {
4648
+ nodeStream.end(resolve7);
4005
4649
  });
4006
4650
  },
4007
4651
  abort(reason) {
@@ -4014,9 +4658,9 @@ function nodeWritableToWebWritable(nodeStream) {
4014
4658
 
4015
4659
  // src/adapters/claude/claude-agent.ts
4016
4660
  import { randomUUID } from "crypto";
4017
- import * as fs9 from "fs";
4018
- import * as os5 from "os";
4019
- import * as path13 from "path";
4661
+ import * as fs10 from "fs";
4662
+ import * as os6 from "os";
4663
+ import * as path14 from "path";
4020
4664
  import {
4021
4665
  RequestError as RequestError2
4022
4666
  } from "@agentclientprotocol/sdk";
@@ -4030,7 +4674,7 @@ import { v7 as uuidv7 } from "uuid";
4030
4674
  // package.json
4031
4675
  var package_default = {
4032
4676
  name: "@posthog/agent",
4033
- version: "2.3.643",
4677
+ version: "2.3.655",
4034
4678
  repository: "https://github.com/PostHog/code",
4035
4679
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
4036
4680
  exports: {
@@ -8371,10 +9015,378 @@ async function buildWrapperContext(deps, content, langId, absPath) {
8371
9015
  return { wrappersByLocalName, namespaceWrappers };
8372
9016
  }
8373
9017
 
9018
+ // ../git/dist/signed-commit.js
9019
+ import * as childProcess3 from "child_process";
9020
+
9021
+ // ../git/dist/concurrency.js
9022
+ async function mapWithConcurrency(items, concurrency, mapper, options) {
9023
+ if (items.length === 0)
9024
+ return [];
9025
+ const results = new Array(items.length);
9026
+ let index = 0;
9027
+ const worker = async () => {
9028
+ while (index < items.length) {
9029
+ if (options?.signal?.aborted)
9030
+ return;
9031
+ const i2 = index++;
9032
+ results[i2] = await mapper(items[i2]);
9033
+ }
9034
+ };
9035
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
9036
+ return results;
9037
+ }
9038
+
9039
+ // ../git/dist/gh.js
9040
+ import * as childProcess from "child_process";
9041
+ function execGh(args2, options = {}) {
9042
+ const env = options.env ? { ...process.env, ...options.env } : process.env;
9043
+ return new Promise((resolve7) => {
9044
+ const child = childProcess.execFile("gh", args2, { cwd: options.cwd, env, timeout: options.timeoutMs ?? 0 }, (error, stdout, stderr) => {
9045
+ if (!error) {
9046
+ resolve7({ stdout, stderr, exitCode: 0 });
9047
+ return;
9048
+ }
9049
+ const err2 = error;
9050
+ const timedOut = err2.killed === true && !!options.timeoutMs;
9051
+ const exitCode = typeof err2.code === "number" ? err2.code : err2.code === "ENOENT" ? 127 : 1;
9052
+ resolve7({
9053
+ stdout: stdout ?? err2.stdout ?? "",
9054
+ stderr: stderr ?? err2.stderr ?? "",
9055
+ exitCode,
9056
+ error: timedOut ? `gh timed out after ${options.timeoutMs}ms` : err2.message
9057
+ });
9058
+ });
9059
+ if (options.input !== void 0) {
9060
+ child.stdin?.end(options.input);
9061
+ }
9062
+ });
9063
+ }
9064
+ var TRANSIENT_GH_PATTERNS = [
9065
+ /HTTP 5\d\d/,
9066
+ /HTTP 499/,
9067
+ /\btimed out\b/i,
9068
+ /\bETIMEDOUT\b/,
9069
+ /\bECONNRESET\b/,
9070
+ /\bECONNREFUSED\b/,
9071
+ /\bEAI_AGAIN\b/,
9072
+ /connection reset/i
9073
+ ];
9074
+ function isTransientGhFailure(res) {
9075
+ if (res.exitCode === 0) {
9076
+ return false;
9077
+ }
9078
+ const text2 = `${res.stderr} ${res.error ?? ""} ${res.stdout}`;
9079
+ return TRANSIENT_GH_PATTERNS.some((re) => re.test(text2));
9080
+ }
9081
+ var sleep = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
9082
+ async function execGhWithRetry(args2, options = {}, retry = {}, exec = execGh) {
9083
+ const maxAttempts = retry.maxAttempts ?? 3;
9084
+ const backoffMs = retry.backoffMs ?? 500;
9085
+ let res = await exec(args2, options);
9086
+ for (let attempt = 2; attempt <= maxAttempts && isTransientGhFailure(res); attempt++) {
9087
+ await sleep(backoffMs * 2 ** (attempt - 2));
9088
+ res = await exec(args2, options);
9089
+ }
9090
+ return res;
9091
+ }
9092
+
9093
+ // ../git/dist/trailers.js
9094
+ function buildPostHogTrailers(taskId) {
9095
+ const trailers = ["Generated-By: PostHog Code"];
9096
+ if (taskId)
9097
+ trailers.push(`Task-Id: ${taskId}`);
9098
+ return trailers;
9099
+ }
9100
+
9101
+ // ../git/dist/utils.js
9102
+ var import_git_url_parse = __toESM(require_lib5(), 1);
9103
+ import * as childProcess2 from "child_process";
9104
+ import * as fs3 from "fs/promises";
9105
+ import * as os from "os";
9106
+ import * as path5 from "path";
9107
+ function parseGithubUrl(url) {
9108
+ if (!url)
9109
+ return null;
9110
+ let parsed;
9111
+ try {
9112
+ parsed = (0, import_git_url_parse.default)(url.trim());
9113
+ } catch {
9114
+ return null;
9115
+ }
9116
+ const resource = parsed.resource.toLowerCase();
9117
+ if (resource !== "github.com" && resource !== "ssh.github.com")
9118
+ return null;
9119
+ const raw = parsed.pathname.split("/");
9120
+ if (raw[0] !== "")
9121
+ return null;
9122
+ const parts2 = raw[raw.length - 1] === "" ? raw.slice(1, -1) : raw.slice(1);
9123
+ if (parts2.length < 2 || parts2.some((p) => p === ""))
9124
+ return null;
9125
+ const [owner, repoRaw, segment, num] = parts2;
9126
+ const repo = repoRaw.replace(/\.git$/, "");
9127
+ if (segment === "issues" || segment === "pull") {
9128
+ const number = Number(num);
9129
+ if (!Number.isInteger(number) || number <= 0)
9130
+ return null;
9131
+ return {
9132
+ kind: segment === "pull" ? "pr" : "issue",
9133
+ owner,
9134
+ repo,
9135
+ number
9136
+ };
9137
+ }
9138
+ return { kind: "repo", owner, repo };
9139
+ }
9140
+
9141
+ // ../git/dist/signed-commit.js
9142
+ var DEFAULT_MAX_PAYLOAD_BYTES = 35 * 1024 * 1024;
9143
+ var MAX_GIT_BUFFER = 256 * 1024 * 1024;
9144
+ var GH_GRAPHQL_TIMEOUT_MS = 3e4;
9145
+ var OversizedFileError = class extends Error {
9146
+ path;
9147
+ bytes;
9148
+ maxBytes;
9149
+ constructor(path17, bytes, maxBytes) {
9150
+ super(`File '${path17}' (~${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.`);
9151
+ this.path = path17;
9152
+ this.bytes = bytes;
9153
+ this.maxBytes = maxBytes;
9154
+ this.name = "OversizedFileError";
9155
+ }
9156
+ };
9157
+ function runGit(args2, cwd) {
9158
+ return new Promise((resolve7) => {
9159
+ childProcess3.execFile("git", args2, { cwd, maxBuffer: MAX_GIT_BUFFER, encoding: "buffer" }, (error, stdout, stderr) => {
9160
+ const err2 = error;
9161
+ const exitCode = err2 && typeof err2.code === "number" ? err2.code : err2 ? 1 : 0;
9162
+ resolve7({
9163
+ stdout: stdout ?? Buffer.alloc(0),
9164
+ stderr: (stderr ?? Buffer.alloc(0)).toString("utf8"),
9165
+ exitCode
9166
+ });
9167
+ });
9168
+ });
9169
+ }
9170
+ async function gitText(args2, cwd) {
9171
+ const r = await runGit(args2, cwd);
9172
+ if (r.exitCode !== 0) {
9173
+ throw new Error(`git ${args2.join(" ")} failed: ${r.stderr.trim()}`);
9174
+ }
9175
+ return r.stdout.toString("utf8").trim();
9176
+ }
9177
+ async function resolveRepoNameWithOwner(ctx) {
9178
+ const url = await gitText(["remote", "get-url", "origin"], ctx.cwd);
9179
+ const parsed = parseGithubUrl(url);
9180
+ if (!parsed) {
9181
+ throw new Error(`Could not parse owner/repo from origin remote: ${url}`);
9182
+ }
9183
+ return `${parsed.owner}/${parsed.repo}`;
9184
+ }
9185
+ async function resolveBaseBranch(ctx) {
9186
+ if (ctx.baseBranch)
9187
+ return ctx.baseBranch;
9188
+ const r = await runGit(["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], ctx.cwd);
9189
+ if (r.exitCode !== 0)
9190
+ return null;
9191
+ return r.stdout.toString("utf8").trim().replace(/^origin\//, "") || null;
9192
+ }
9193
+ async function resolveBranchName(ctx, input) {
9194
+ const branch = input.branch ? input.branch.replace(/^refs\/heads\//, "") : await resolveCurrentBranch(ctx);
9195
+ const baseBranch = await resolveBaseBranch(ctx);
9196
+ if (baseBranch && branch === baseBranch) {
9197
+ throw new Error(`Refusing to commit directly to base branch '${baseBranch}'. Pass a 'branch' name prefixed with posthog-code/.`);
9198
+ }
9199
+ return branch;
9200
+ }
9201
+ async function resolveCurrentBranch(ctx) {
9202
+ const current2 = await gitText(["rev-parse", "--abbrev-ref", "HEAD"], ctx.cwd);
9203
+ if (!current2 || current2 === "HEAD") {
9204
+ throw new Error("Detached HEAD \u2014 pass a `branch` to git_signed_commit (e.g. posthog-code/...).");
9205
+ }
9206
+ return current2;
9207
+ }
9208
+ async function remoteTip(ctx, branch) {
9209
+ const out2 = await gitText(["ls-remote", "--heads", "origin", branch], ctx.cwd);
9210
+ if (!out2)
9211
+ return null;
9212
+ return out2.split(" ")[0]?.trim() || null;
9213
+ }
9214
+ async function createRef(ctx, repo, branch, sha) {
9215
+ const res = await execGh([
9216
+ "api",
9217
+ "-X",
9218
+ "POST",
9219
+ `/repos/${repo}/git/refs`,
9220
+ "-f",
9221
+ `ref=refs/heads/${branch}`,
9222
+ "-f",
9223
+ `sha=${sha}`
9224
+ ], { cwd: ctx.cwd, env: ghTokenEnv(ctx.token) });
9225
+ if (res.exitCode !== 0) {
9226
+ throw new Error(`Failed to create branch '${branch}': ${res.stderr || res.error}`);
9227
+ }
9228
+ }
9229
+ var GITHUB_TOKEN_ENV_VARS = ["GH_TOKEN", "GITHUB_TOKEN"];
9230
+ function readGithubTokenFromEnv(env = process.env) {
9231
+ for (const name2 of GITHUB_TOKEN_ENV_VARS) {
9232
+ if (env[name2])
9233
+ return env[name2];
9234
+ }
9235
+ return void 0;
9236
+ }
9237
+ function ghTokenEnv(token) {
9238
+ return Object.fromEntries(GITHUB_TOKEN_ENV_VARS.map((name2) => [name2, token]));
9239
+ }
9240
+ var STAGED_READ_CONCURRENCY = 16;
9241
+ async function buildFileChanges(ctx, baseOid) {
9242
+ const diff = await runGit(["diff", "--cached", "-z", "--no-renames", "--name-status", baseOid], ctx.cwd);
9243
+ if (diff.exitCode !== 0) {
9244
+ throw new Error(`git diff --cached failed: ${diff.stderr.trim()}`);
9245
+ }
9246
+ const tokens = diff.stdout.toString("utf8").split("\0").filter(Boolean);
9247
+ const addPaths = [];
9248
+ const deletions = [];
9249
+ for (let i2 = 0; i2 + 1 < tokens.length; i2 += 2) {
9250
+ const path17 = tokens[i2 + 1];
9251
+ if (tokens[i2].startsWith("D")) {
9252
+ deletions.push({ path: path17 });
9253
+ } else {
9254
+ addPaths.push(path17);
9255
+ }
9256
+ }
9257
+ const additions = await mapWithConcurrency(addPaths, STAGED_READ_CONCURRENCY, async (path17) => {
9258
+ const r = await runGit(["show", `:${path17}`], ctx.cwd);
9259
+ if (r.exitCode !== 0) {
9260
+ throw new Error(`Failed to read staged file '${path17}': ${r.stderr.trim()}`);
9261
+ }
9262
+ return { path: path17, contents: r.stdout.toString("base64") };
9263
+ });
9264
+ return { additions, deletions };
9265
+ }
9266
+ function additionBytes(a) {
9267
+ return a.contents.length + a.path.length + 32;
9268
+ }
9269
+ function chunkFileChanges(changes, maxBytes) {
9270
+ for (const a of changes.additions) {
9271
+ const bytes = additionBytes(a);
9272
+ if (bytes > maxBytes)
9273
+ throw new OversizedFileError(a.path, bytes, maxBytes);
9274
+ }
9275
+ if (changes.additions.length === 0) {
9276
+ return [{ additions: [], deletions: changes.deletions }];
9277
+ }
9278
+ const chunks = [];
9279
+ let cur = { additions: [], deletions: [...changes.deletions] };
9280
+ let curBytes = changes.deletions.reduce((n, d) => n + d.path.length + 16, 0);
9281
+ for (const a of changes.additions) {
9282
+ const bytes = additionBytes(a);
9283
+ if (cur.additions.length > 0 && curBytes + bytes > maxBytes) {
9284
+ chunks.push(cur);
9285
+ cur = { additions: [], deletions: [] };
9286
+ curBytes = 0;
9287
+ }
9288
+ cur.additions.push(a);
9289
+ curBytes += bytes;
9290
+ }
9291
+ chunks.push(cur);
9292
+ return chunks;
9293
+ }
9294
+ var CREATE_COMMIT_MUTATION = `mutation($input: CreateCommitOnBranchInput!) {
9295
+ createCommitOnBranch(input: $input) { commit { oid url } }
9296
+ }`;
9297
+ async function createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, changes) {
9298
+ const payload = JSON.stringify({
9299
+ query: CREATE_COMMIT_MUTATION,
9300
+ variables: {
9301
+ input: {
9302
+ branch: { repositoryNameWithOwner: repo, branchName: branch },
9303
+ expectedHeadOid,
9304
+ message: { headline, body: body2 },
9305
+ fileChanges: changes
9306
+ }
9307
+ }
9308
+ });
9309
+ const res = await execGhWithRetry(["api", "graphql", "--input", "-"], {
9310
+ cwd: ctx.cwd,
9311
+ input: payload,
9312
+ env: ghTokenEnv(ctx.token),
9313
+ // Bound each attempt so a stalled connection can't hang the tool forever.
9314
+ timeoutMs: GH_GRAPHQL_TIMEOUT_MS
9315
+ }, { maxAttempts: 3 });
9316
+ if (res.exitCode !== 0) {
9317
+ throw new Error(`createCommitOnBranch failed: ${res.stderr || res.error || res.stdout}`);
9318
+ }
9319
+ let parsed;
9320
+ try {
9321
+ parsed = JSON.parse(res.stdout);
9322
+ } catch {
9323
+ throw new Error(`createCommitOnBranch returned non-JSON: ${res.stdout.slice(0, 500)}`);
9324
+ }
9325
+ if (parsed.errors) {
9326
+ throw new Error(`createCommitOnBranch errors: ${JSON.stringify(parsed.errors)}`);
9327
+ }
9328
+ const commit = parsed.data?.createCommitOnBranch?.commit;
9329
+ if (!commit?.oid) {
9330
+ throw new Error(`createCommitOnBranch returned no commit: ${res.stdout}`);
9331
+ }
9332
+ return commit;
9333
+ }
9334
+ async function syncLocalCheckout(ctx, branch, newOid) {
9335
+ const steps = [
9336
+ ["fetch", ["fetch", "--no-tags", "origin", branch]],
9337
+ ["update-ref", ["update-ref", `refs/heads/${branch}`, newOid]],
9338
+ ["symbolic-ref", ["symbolic-ref", "HEAD", `refs/heads/${branch}`]],
9339
+ ["reset", ["reset", "-q"]]
9340
+ ];
9341
+ for (const [label, args2] of steps) {
9342
+ const r = await runGit(args2, ctx.cwd);
9343
+ if (r.exitCode !== 0) {
9344
+ process.stderr.write(`[signed-commit] local sync step '${label}' failed after committing ${newOid}: ${r.stderr.trim()}
9345
+ `);
9346
+ }
9347
+ }
9348
+ }
9349
+ async function createSignedCommit(ctx, input) {
9350
+ const [repo, branch] = await Promise.all([
9351
+ resolveRepoNameWithOwner(ctx),
9352
+ resolveBranchName(ctx, input)
9353
+ ]);
9354
+ if (input.paths && input.paths.length > 0) {
9355
+ const r = await runGit(["add", "--", ...input.paths], ctx.cwd);
9356
+ if (r.exitCode !== 0) {
9357
+ throw new Error(`git add failed: ${r.stderr.trim()}`);
9358
+ }
9359
+ }
9360
+ let tip = await remoteTip(ctx, branch);
9361
+ if (tip === null) {
9362
+ const baseSha = await gitText(["rev-parse", "HEAD"], ctx.cwd);
9363
+ await createRef(ctx, repo, branch, baseSha);
9364
+ tip = baseSha;
9365
+ } else {
9366
+ await runGit(["fetch", "--no-tags", "origin", branch], ctx.cwd);
9367
+ }
9368
+ const changes = await buildFileChanges(ctx, tip);
9369
+ if (changes.additions.length === 0 && changes.deletions.length === 0) {
9370
+ throw new Error("No staged changes to commit. Stage files with `git add` first (or pass `paths`).");
9371
+ }
9372
+ const chunks = chunkFileChanges(changes, DEFAULT_MAX_PAYLOAD_BYTES);
9373
+ const body2 = [input.body, buildPostHogTrailers(ctx.taskId).join("\n")].filter(Boolean).join("\n\n");
9374
+ const commits = [];
9375
+ let expectedHeadOid = tip;
9376
+ for (let i2 = 0; i2 < chunks.length; i2++) {
9377
+ const headline = chunks.length > 1 ? `${input.message} \u2014 part ${i2 + 1}/${chunks.length}` : input.message;
9378
+ const commit = await createCommitOnBranch(ctx, repo, branch, expectedHeadOid, headline, body2, chunks[i2]);
9379
+ commits.push({ sha: commit.oid, url: commit.url });
9380
+ expectedHeadOid = commit.oid;
9381
+ }
9382
+ await syncLocalCheckout(ctx, branch, expectedHeadOid);
9383
+ return { branch, commits };
9384
+ }
9385
+
8374
9386
  // src/utils/common.ts
8375
9387
  async function withTimeout(operation, timeoutMs) {
8376
9388
  const timeoutPromise = new Promise(
8377
- (resolve6) => setTimeout(() => resolve6({ result: "timeout" }), timeoutMs)
9389
+ (resolve7) => setTimeout(() => resolve7({ result: "timeout" }), timeoutMs)
8378
9390
  );
8379
9391
  const operationPromise = operation.then((value) => ({
8380
9392
  result: "success",
@@ -8384,6 +9396,12 @@ async function withTimeout(operation, timeoutMs) {
8384
9396
  }
8385
9397
  var IS_ROOT = typeof process !== "undefined" && (process.geteuid?.() ?? process.getuid?.()) === 0;
8386
9398
  var ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
9399
+ function isCloudRun(meta) {
9400
+ return !!process.env.IS_SANDBOX || !!meta?.taskRunId;
9401
+ }
9402
+ function resolveGithubToken() {
9403
+ return readGithubTokenFromEnv();
9404
+ }
8387
9405
  function unreachable(value, logger) {
8388
9406
  let valueAsString;
8389
9407
  try {
@@ -8574,8 +9592,82 @@ var BaseAcpAgent = class {
8574
9592
  }
8575
9593
  };
8576
9594
 
9595
+ // src/adapters/signed-commit-shared.ts
9596
+ import { z } from "zod";
9597
+
9598
+ // src/adapters/local-tools/registry.ts
9599
+ var LOCAL_TOOLS_MCP_NAME = "posthog-local";
9600
+ function defineLocalTool(def) {
9601
+ return def;
9602
+ }
9603
+ function qualifiedLocalToolName(toolName) {
9604
+ return `mcp__${LOCAL_TOOLS_MCP_NAME}__${toolName}`;
9605
+ }
9606
+
9607
+ // src/adapters/signed-commit-shared.ts
9608
+ var SIGNED_COMMIT_TOOL_NAME = "git_signed_commit";
9609
+ var SIGNED_COMMIT_QUALIFIED_TOOL_NAME = qualifiedLocalToolName(
9610
+ SIGNED_COMMIT_TOOL_NAME
9611
+ );
9612
+ 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.";
9613
+ var signedCommitToolSchema = {
9614
+ message: z.string().describe("Commit headline (first line)."),
9615
+ body: z.string().optional().describe("Optional extended commit body."),
9616
+ branch: z.string().optional().describe(
9617
+ "Target branch; defaults to the current branch. Use a posthog-code/ prefix for new branches."
9618
+ ),
9619
+ paths: z.array(z.string()).optional().describe(
9620
+ "Files to stage before committing; defaults to already-staged files."
9621
+ )
9622
+ };
9623
+ function formatSignedCommitResult(result) {
9624
+ const list = result.commits.map((c) => `- ${c.sha} ${c.url}`).join("\n");
9625
+ return `Created ${result.commits.length} signed commit(s) on ${result.branch}:
9626
+ ${list}`;
9627
+ }
9628
+ async function runSignedCommitTool(ctx, args2) {
9629
+ try {
9630
+ const result = await createSignedCommit(ctx, args2);
9631
+ return {
9632
+ content: [{ type: "text", text: formatSignedCommitResult(result) }]
9633
+ };
9634
+ } catch (err2) {
9635
+ const message = err2 instanceof Error ? err2.message : String(err2);
9636
+ return {
9637
+ content: [
9638
+ { type: "text", text: `${SIGNED_COMMIT_TOOL_NAME} failed: ${message}` }
9639
+ ],
9640
+ isError: true
9641
+ };
9642
+ }
9643
+ }
9644
+
9645
+ // src/adapters/local-tools/tools/signed-commit.ts
9646
+ var signedCommitTool = defineLocalTool({
9647
+ name: SIGNED_COMMIT_TOOL_NAME,
9648
+ description: SIGNED_COMMIT_TOOL_DESCRIPTION,
9649
+ schema: signedCommitToolSchema,
9650
+ alwaysLoad: true,
9651
+ isEnabled: (ctx, meta) => isCloudRun(meta) && !!ctx.token,
9652
+ handler: (ctx, args2) => runSignedCommitTool(
9653
+ { cwd: ctx.cwd, token: ctx.token ?? "", taskId: ctx.taskId },
9654
+ args2
9655
+ )
9656
+ });
9657
+
9658
+ // src/adapters/local-tools/index.ts
9659
+ var LOCAL_TOOLS = [signedCommitTool];
9660
+ function enabledLocalTools(ctx, meta) {
9661
+ return LOCAL_TOOLS.filter((t) => t.isEnabled(ctx, meta));
9662
+ }
9663
+
9664
+ // src/adapters/session-meta.ts
9665
+ function resolveTaskId(meta) {
9666
+ return meta?.taskId ?? meta?.persistence?.taskId;
9667
+ }
9668
+
8577
9669
  // src/adapters/claude/conversion/acp-to-sdk.ts
8578
- import * as path5 from "path";
9670
+ import * as path6 from "path";
8579
9671
  import { fileURLToPath as fileURLToPath2 } from "url";
8580
9672
  var PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
8581
9673
  var COMMON_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -8605,7 +9697,7 @@ function sdkText(value) {
8605
9697
  function formatUriAsLink(uri) {
8606
9698
  try {
8607
9699
  if (uri.startsWith("zed://")) {
8608
- const name2 = path5.basename(uri) || uri;
9700
+ const name2 = path6.basename(uri) || uri;
8609
9701
  return `[@${name2}](${uri})`;
8610
9702
  }
8611
9703
  return uri;
@@ -8614,7 +9706,7 @@ function formatUriAsLink(uri) {
8614
9706
  }
8615
9707
  }
8616
9708
  function readToolGuidanceForPath(filePath) {
8617
- const ext = path5.extname(filePath).slice(1).toLowerCase();
9709
+ const ext = path6.extname(filePath).slice(1).toLowerCase();
8618
9710
  if (PDF_EXTENSIONS.has(ext)) {
8619
9711
  return 'Optional `pages` string (e.g. "1-5") per Read call instead of loading the entire PDF.';
8620
9712
  }
@@ -8626,7 +9718,7 @@ function readToolGuidanceForPath(filePath) {
8626
9718
  function workspacePromptFromFileUri(uri) {
8627
9719
  try {
8628
9720
  const filePath = fileURLToPath2(uri);
8629
- const name2 = path5.basename(filePath) || filePath;
9721
+ const name2 = path6.basename(filePath) || filePath;
8630
9722
  return [
8631
9723
  "Attached workspace file \u2014 use Read with required `file_path`:",
8632
9724
  `- file_path: ${filePath}`,
@@ -8752,8 +9844,8 @@ var ToolContentBuilder = class {
8752
9844
  this.items.push({ type: "content", content: image(data, mimeType, uri) });
8753
9845
  return this;
8754
9846
  }
8755
- diff(path16, oldText, newText) {
8756
- this.items.push({ type: "diff", path: path16, oldText, newText });
9847
+ diff(path17, oldText, newText) {
9848
+ this.items.push({ type: "diff", path: path17, oldText, newText });
8757
9849
  return this;
8758
9850
  }
8759
9851
  build() {
@@ -8972,6 +10064,60 @@ var createSubagentRewriteHook = (logger, registeredAgents) => async (input, _too
8972
10064
  }
8973
10065
  };
8974
10066
  };
10067
+ var GIT_VALUE_FLAGS = /* @__PURE__ */ new Set([
10068
+ "-C",
10069
+ "-c",
10070
+ "--git-dir",
10071
+ "--work-tree",
10072
+ "--namespace",
10073
+ "--exec-path"
10074
+ ]);
10075
+ function gitSubcommand(segment) {
10076
+ const tokens = segment.trim().split(/\s+/).filter(Boolean);
10077
+ if (tokens.length === 0) return null;
10078
+ const head = tokens[0].split("/").pop();
10079
+ if (head !== "git") return null;
10080
+ let skipNext = false;
10081
+ for (const tok of tokens.slice(1)) {
10082
+ if (skipNext) {
10083
+ skipNext = false;
10084
+ continue;
10085
+ }
10086
+ if (GIT_VALUE_FLAGS.has(tok)) {
10087
+ skipNext = true;
10088
+ continue;
10089
+ }
10090
+ if (tok.startsWith("-")) continue;
10091
+ return tok;
10092
+ }
10093
+ return null;
10094
+ }
10095
+ function blocksUnsignedGit(command) {
10096
+ if (!command.includes("git")) return false;
10097
+ return command.split(/&&|\|\||[;\n|]/).some((segment) => {
10098
+ const sub = gitSubcommand(segment);
10099
+ return sub === "commit" || sub === "push";
10100
+ });
10101
+ }
10102
+ var createSignedCommitGuardHook = (logger) => async (input, _toolUseID) => {
10103
+ if (input.hook_event_name !== "PreToolUse") return { continue: true };
10104
+ if (input.tool_name !== "Bash") return { continue: true };
10105
+ const command = input.tool_input?.command;
10106
+ if (!command || !blocksUnsignedGit(command)) {
10107
+ return { continue: true };
10108
+ }
10109
+ logger.info(
10110
+ `[SignedCommitGuard] Blocking unsigned git command: ${command}`
10111
+ );
10112
+ return {
10113
+ continue: true,
10114
+ hookSpecificOutput: {
10115
+ hookEventName: "PreToolUse",
10116
+ permissionDecision: "deny",
10117
+ 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.`
10118
+ }
10119
+ };
10120
+ };
8975
10121
  var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID) => {
8976
10122
  if (input.hook_event_name !== "PreToolUse") {
8977
10123
  return { continue: true };
@@ -9025,8 +10171,8 @@ var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID
9025
10171
  };
9026
10172
 
9027
10173
  // src/adapters/claude/conversion/tool-use-to-acp.ts
9028
- import fs3 from "fs";
9029
- import path6 from "path";
10174
+ import fs4 from "fs";
10175
+ import path7 from "path";
9030
10176
 
9031
10177
  // src/adapters/claude/mcp/tool-metadata.ts
9032
10178
  var mcpToolMetadataCache = /* @__PURE__ */ new Map();
@@ -9036,7 +10182,7 @@ function buildToolKey(serverName, toolName) {
9036
10182
  return `mcp__${serverName}__${toolName}`;
9037
10183
  }
9038
10184
  function delay(ms) {
9039
- return new Promise((resolve6) => setTimeout(resolve6, ms));
10185
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
9040
10186
  }
9041
10187
  async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
9042
10188
  let retries = 0;
@@ -9056,14 +10202,14 @@ async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefi
9056
10202
  continue;
9057
10203
  }
9058
10204
  let readOnlyCount = 0;
9059
- for (const tool of server.tools) {
9060
- const toolKey = buildToolKey(server.name, tool.name);
9061
- const readOnly = tool.annotations?.readOnly === true;
10205
+ for (const tool2 of server.tools) {
10206
+ const toolKey = buildToolKey(server.name, tool2.name);
10207
+ const readOnly = tool2.annotations?.readOnly === true;
9062
10208
  const existing = mcpToolMetadataCache.get(toolKey);
9063
10209
  mcpToolMetadataCache.set(toolKey, {
9064
10210
  readOnly,
9065
- name: tool.name,
9066
- description: tool.description,
10211
+ name: tool2.name,
10212
+ description: tool2.description,
9067
10213
  approvalState: existing?.approvalState
9068
10214
  });
9069
10215
  if (readOnly) readOnlyCount++;
@@ -9131,10 +10277,10 @@ function stripSystemReminders(value) {
9131
10277
  }
9132
10278
  function toDisplayPath(filePath, cwd) {
9133
10279
  if (!cwd) return filePath;
9134
- const resolvedCwd = path6.resolve(cwd);
9135
- const resolvedFile = path6.resolve(filePath);
9136
- if (resolvedFile.startsWith(resolvedCwd + path6.sep) || resolvedFile === resolvedCwd) {
9137
- return path6.relative(resolvedCwd, resolvedFile);
10280
+ const resolvedCwd = path7.resolve(cwd);
10281
+ const resolvedFile = path7.resolve(filePath);
10282
+ if (resolvedFile.startsWith(resolvedCwd + path7.sep) || resolvedFile === resolvedCwd) {
10283
+ return path7.relative(resolvedCwd, resolvedFile);
9138
10284
  }
9139
10285
  return filePath;
9140
10286
  }
@@ -9259,7 +10405,7 @@ function toolInfoFromToolUse(toolUse, options) {
9259
10405
  oldContent = options.cachedFileContent[writeFilePath];
9260
10406
  } else {
9261
10407
  try {
9262
- oldContent = fs3.readFileSync(writeFilePath, "utf-8");
10408
+ oldContent = fs4.readFileSync(writeFilePath, "utf-8");
9263
10409
  } catch {
9264
10410
  }
9265
10411
  }
@@ -9673,7 +10819,7 @@ function resolveFileContent(filePath, oldText, cachedFileContent) {
9673
10819
  }
9674
10820
  }
9675
10821
  try {
9676
- const content = fs3.readFileSync(filePath, "utf-8");
10822
+ const content = fs4.readFileSync(filePath, "utf-8");
9677
10823
  if (content.includes(oldText)) {
9678
10824
  return content;
9679
10825
  }
@@ -10326,20 +11472,45 @@ async function handleUserAssistantMessage(message, context) {
10326
11472
  return {};
10327
11473
  }
10328
11474
 
11475
+ // src/adapters/claude/mcp/local-tools.ts
11476
+ import {
11477
+ createSdkMcpServer,
11478
+ tool
11479
+ } from "@anthropic-ai/claude-agent-sdk";
11480
+ function createLocalToolsMcpServer(ctx, meta) {
11481
+ const tools = enabledLocalTools(ctx, meta);
11482
+ if (tools.length === 0) {
11483
+ return void 0;
11484
+ }
11485
+ return createSdkMcpServer({
11486
+ name: LOCAL_TOOLS_MCP_NAME,
11487
+ version: "1.0.0",
11488
+ tools: tools.map(
11489
+ (t) => tool(
11490
+ t.name,
11491
+ t.description,
11492
+ t.schema,
11493
+ async (args2) => t.handler(ctx, args2),
11494
+ { alwaysLoad: t.alwaysLoad ?? false }
11495
+ )
11496
+ )
11497
+ });
11498
+ }
11499
+
10329
11500
  // src/adapters/claude/plan/utils.ts
10330
- import * as os from "os";
10331
- import * as path7 from "path";
11501
+ import * as os2 from "os";
11502
+ import * as path8 from "path";
10332
11503
  function getClaudeConfigDir() {
10333
- return process.env.CLAUDE_CONFIG_DIR || path7.join(os.homedir(), ".claude");
11504
+ return process.env.CLAUDE_CONFIG_DIR || path8.join(os2.homedir(), ".claude");
10334
11505
  }
10335
11506
  function getClaudePlansDir() {
10336
- return path7.join(getClaudeConfigDir(), "plans");
11507
+ return path8.join(getClaudeConfigDir(), "plans");
10337
11508
  }
10338
11509
  function isClaudePlanFilePath(filePath) {
10339
11510
  if (!filePath) return false;
10340
- const resolved = path7.resolve(filePath);
10341
- const plansDir = path7.resolve(getClaudePlansDir());
10342
- return resolved === plansDir || resolved.startsWith(plansDir + path7.sep);
11511
+ const resolved = path8.resolve(filePath);
11512
+ const plansDir = path8.resolve(getClaudePlansDir());
11513
+ return resolved === plansDir || resolved.startsWith(plansDir + path8.sep);
10343
11514
  }
10344
11515
  function isPlanReady(plan) {
10345
11516
  if (!plan) return false;
@@ -10370,21 +11541,21 @@ function getLatestAssistantText(notifications) {
10370
11541
  }
10371
11542
 
10372
11543
  // src/adapters/claude/questions/utils.ts
10373
- import { z } from "zod";
11544
+ import { z as z2 } from "zod";
10374
11545
  var OPTION_PREFIX = "option_";
10375
- var QuestionOptionSchema = z.object({
10376
- label: z.string(),
10377
- description: z.string().optional()
11546
+ var QuestionOptionSchema = z2.object({
11547
+ label: z2.string(),
11548
+ description: z2.string().optional()
10378
11549
  });
10379
- var QuestionItemSchema = z.object({
10380
- question: z.string(),
10381
- header: z.string().optional(),
10382
- options: z.array(QuestionOptionSchema),
10383
- multiSelect: z.boolean().optional(),
10384
- completed: z.boolean().optional()
11550
+ var QuestionItemSchema = z2.object({
11551
+ question: z2.string(),
11552
+ header: z2.string().optional(),
11553
+ options: z2.array(QuestionOptionSchema),
11554
+ multiSelect: z2.boolean().optional(),
11555
+ completed: z2.boolean().optional()
10385
11556
  });
10386
- var QuestionMetaSchema = z.object({
10387
- questions: z.array(QuestionItemSchema)
11557
+ var QuestionMetaSchema = z2.object({
11558
+ questions: z2.array(QuestionItemSchema)
10388
11559
  });
10389
11560
  function normalizeAskUserQuestionInput(input) {
10390
11561
  if (input.questions && input.questions.length > 0) {
@@ -11156,14 +12327,14 @@ function getAvailableSlashCommands(commands) {
11156
12327
  }
11157
12328
 
11158
12329
  // src/adapters/claude/session/mcp-config.ts
11159
- import * as fs4 from "fs";
11160
- import * as os2 from "os";
11161
- import * as path8 from "path";
11162
- function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os2.homedir()) {
11163
- const claudeJsonPath = path8.join(homeDir, ".claude.json");
12330
+ import * as fs5 from "fs";
12331
+ import * as os3 from "os";
12332
+ import * as path9 from "path";
12333
+ function loadUserClaudeJsonMcpServers(cwd, logger, homeDir = os3.homedir()) {
12334
+ const claudeJsonPath = path9.join(homeDir, ".claude.json");
11164
12335
  let raw;
11165
12336
  try {
11166
- raw = fs4.readFileSync(claudeJsonPath, "utf8");
12337
+ raw = fs5.readFileSync(claudeJsonPath, "utf8");
11167
12338
  } catch {
11168
12339
  return {};
11169
12340
  }
@@ -11314,9 +12485,9 @@ function resolveModelPreference(preference, options) {
11314
12485
 
11315
12486
  // src/adapters/claude/session/options.ts
11316
12487
  import { spawn } from "child_process";
11317
- import * as fs5 from "fs";
11318
- import * as os3 from "os";
11319
- import * as path9 from "path";
12488
+ import * as fs6 from "fs";
12489
+ import * as os4 from "os";
12490
+ import * as path10 from "path";
11320
12491
 
11321
12492
  // src/adapters/claude/session/instructions.ts
11322
12493
  var BRANCH_NAMING = `
@@ -11391,28 +12562,27 @@ ${bedrockFallbackHeader}` : bedrockFallbackHeader;
11391
12562
  ANTHROPIC_CUSTOM_HEADERS: customHeaders
11392
12563
  };
11393
12564
  }
11394
- function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents) {
12565
+ function buildHooks(userHooks, onModeChange, settingsManager, logger, enrichmentDeps, enrichedReadCache, registeredAgents, cloudMode) {
11395
12566
  const postToolUseHooks = [createPostToolUseHook({ onModeChange })];
11396
12567
  if (enrichmentDeps && enrichedReadCache) {
11397
12568
  postToolUseHooks.push(
11398
12569
  createReadEnrichmentHook(enrichmentDeps, enrichedReadCache)
11399
12570
  );
11400
12571
  }
12572
+ const preToolUseHooks = [
12573
+ createPreToolUseHook(settingsManager, logger),
12574
+ createSubagentRewriteHook(logger, registeredAgents)
12575
+ ];
12576
+ if (cloudMode) {
12577
+ preToolUseHooks.push(createSignedCommitGuardHook(logger));
12578
+ }
11401
12579
  return {
11402
12580
  ...userHooks,
11403
12581
  PostToolUse: [
11404
12582
  ...userHooks?.PostToolUse || [],
11405
12583
  { hooks: postToolUseHooks }
11406
12584
  ],
11407
- PreToolUse: [
11408
- ...userHooks?.PreToolUse || [],
11409
- {
11410
- hooks: [
11411
- createPreToolUseHook(settingsManager, logger),
11412
- createSubagentRewriteHook(logger, registeredAgents)
11413
- ]
11414
- }
11415
- ]
12585
+ PreToolUse: [...userHooks?.PreToolUse || [], { hooks: preToolUseHooks }]
11416
12586
  };
11417
12587
  }
11418
12588
  var PH_EXPLORE_AGENT = {
@@ -11524,12 +12694,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger)
11524
12694
  };
11525
12695
  }
11526
12696
  function ensureLocalSettings(cwd) {
11527
- const claudeDir = path9.join(cwd, ".claude");
11528
- const localSettingsPath = path9.join(claudeDir, "settings.local.json");
12697
+ const claudeDir = path10.join(cwd, ".claude");
12698
+ const localSettingsPath = path10.join(claudeDir, "settings.local.json");
11529
12699
  try {
11530
- if (!fs5.existsSync(localSettingsPath)) {
11531
- fs5.mkdirSync(claudeDir, { recursive: true });
11532
- fs5.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
12700
+ if (!fs6.existsSync(localSettingsPath)) {
12701
+ fs6.mkdirSync(claudeDir, { recursive: true });
12702
+ fs6.writeFileSync(localSettingsPath, "{}\n", { flag: "wx" });
11533
12703
  }
11534
12704
  } catch {
11535
12705
  }
@@ -11570,7 +12740,8 @@ function buildSessionOptions(params) {
11570
12740
  params.logger,
11571
12741
  params.enrichmentDeps,
11572
12742
  params.enrichedReadCache,
11573
- registeredAgentNames
12743
+ registeredAgentNames,
12744
+ params.cloudMode ?? false
11574
12745
  ),
11575
12746
  outputFormat: params.outputFormat,
11576
12747
  abortController: getAbortController(
@@ -11605,18 +12776,18 @@ function buildSessionOptions(params) {
11605
12776
  return options;
11606
12777
  }
11607
12778
  function clearStatsigCache() {
11608
- const statsigPath = path9.join(
11609
- process.env.CLAUDE_CONFIG_DIR || path9.join(os3.homedir(), ".claude"),
12779
+ const statsigPath = path10.join(
12780
+ process.env.CLAUDE_CONFIG_DIR || path10.join(os4.homedir(), ".claude"),
11610
12781
  "statsig"
11611
12782
  );
11612
- fs5.rm(statsigPath, { recursive: true, force: true }, () => {
12783
+ fs6.rm(statsigPath, { recursive: true, force: true }, () => {
11613
12784
  });
11614
12785
  }
11615
12786
 
11616
12787
  // src/adapters/claude/session/settings.ts
11617
- import * as fs8 from "fs";
11618
- import * as os4 from "os";
11619
- import * as path12 from "path";
12788
+ import * as fs9 from "fs";
12789
+ import * as os5 from "os";
12790
+ import * as path13 from "path";
11620
12791
  import { minimatch } from "minimatch";
11621
12792
 
11622
12793
  // src/utils/async-mutex.ts
@@ -11628,8 +12799,8 @@ var AsyncMutex = class {
11628
12799
  this.locked = true;
11629
12800
  return;
11630
12801
  }
11631
- return new Promise((resolve6) => {
11632
- this.queue.push(resolve6);
12802
+ return new Promise((resolve7) => {
12803
+ this.queue.push(resolve7);
11633
12804
  });
11634
12805
  }
11635
12806
  release() {
@@ -11650,14 +12821,14 @@ var AsyncMutex = class {
11650
12821
 
11651
12822
  // ../git/dist/queries.js
11652
12823
  import { createReadStream } from "fs";
11653
- import * as fs7 from "fs/promises";
11654
- import * as path11 from "path";
12824
+ import * as fs8 from "fs/promises";
12825
+ import * as path12 from "path";
11655
12826
 
11656
12827
  // ../../node_modules/simple-git/dist/esm/index.js
11657
- var import_file_exists = __toESM(require_dist(), 1);
12828
+ var import_file_exists = __toESM(require_dist2(), 1);
11658
12829
  var import_debug = __toESM(require_src(), 1);
11659
- var import_promise_deferred = __toESM(require_dist2(), 1);
11660
- var import_promise_deferred2 = __toESM(require_dist2(), 1);
12830
+ var import_promise_deferred = __toESM(require_dist3(), 1);
12831
+ var import_promise_deferred2 = __toESM(require_dist3(), 1);
11661
12832
  import { Buffer as Buffer2 } from "buffer";
11662
12833
  import { spawn as spawn2 } from "child_process";
11663
12834
  import { normalize } from "path";
@@ -11690,8 +12861,8 @@ function pathspec(...paths) {
11690
12861
  cache.set(key, paths);
11691
12862
  return key;
11692
12863
  }
11693
- function isPathSpec(path16) {
11694
- return path16 instanceof String && cache.has(path16);
12864
+ function isPathSpec(path17) {
12865
+ return path17 instanceof String && cache.has(path17);
11695
12866
  }
11696
12867
  function toPaths(pathSpec) {
11697
12868
  return cache.get(pathSpec) || [];
@@ -11780,8 +12951,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
11780
12951
  function forEachLineWithContent(input, callback) {
11781
12952
  return toLinesWithContent(input, true).map((line) => callback(line));
11782
12953
  }
11783
- function folderExists(path16) {
11784
- return (0, import_file_exists.exists)(path16, import_file_exists.FOLDER);
12954
+ function folderExists(path17) {
12955
+ return (0, import_file_exists.exists)(path17, import_file_exists.FOLDER);
11785
12956
  }
11786
12957
  function append(target, item) {
11787
12958
  if (Array.isArray(target)) {
@@ -12185,8 +13356,8 @@ function checkIsRepoRootTask() {
12185
13356
  commands,
12186
13357
  format: "utf-8",
12187
13358
  onError,
12188
- parser(path16) {
12189
- return /^\.(git)?$/.test(path16.trim());
13359
+ parser(path17) {
13360
+ return /^\.(git)?$/.test(path17.trim());
12190
13361
  }
12191
13362
  };
12192
13363
  }
@@ -12620,11 +13791,11 @@ function parseGrep(grep) {
12620
13791
  const paths = /* @__PURE__ */ new Set();
12621
13792
  const results = {};
12622
13793
  forEachLineWithContent(grep, (input) => {
12623
- const [path16, line, preview] = input.split(NULL);
12624
- paths.add(path16);
12625
- (results[path16] = results[path16] || []).push({
13794
+ const [path17, line, preview] = input.split(NULL);
13795
+ paths.add(path17);
13796
+ (results[path17] = results[path17] || []).push({
12626
13797
  line: asNumber(line),
12627
- path: path16,
13798
+ path: path17,
12628
13799
  preview
12629
13800
  });
12630
13801
  });
@@ -13389,14 +14560,14 @@ var init_hash_object = __esm({
13389
14560
  init_task();
13390
14561
  }
13391
14562
  });
13392
- function parseInit(bare, path16, text2) {
14563
+ function parseInit(bare, path17, text2) {
13393
14564
  const response = String(text2).trim();
13394
14565
  let result;
13395
14566
  if (result = initResponseRegex.exec(response)) {
13396
- return new InitSummary(bare, path16, false, result[1]);
14567
+ return new InitSummary(bare, path17, false, result[1]);
13397
14568
  }
13398
14569
  if (result = reInitResponseRegex.exec(response)) {
13399
- return new InitSummary(bare, path16, true, result[1]);
14570
+ return new InitSummary(bare, path17, true, result[1]);
13400
14571
  }
13401
14572
  let gitDir = "";
13402
14573
  const tokens = response.split(" ");
@@ -13407,7 +14578,7 @@ function parseInit(bare, path16, text2) {
13407
14578
  break;
13408
14579
  }
13409
14580
  }
13410
- return new InitSummary(bare, path16, /^re/i.test(response), gitDir);
14581
+ return new InitSummary(bare, path17, /^re/i.test(response), gitDir);
13411
14582
  }
13412
14583
  var InitSummary;
13413
14584
  var initResponseRegex;
@@ -13416,9 +14587,9 @@ var init_InitSummary = __esm({
13416
14587
  "src/lib/responses/InitSummary.ts"() {
13417
14588
  "use strict";
13418
14589
  InitSummary = class {
13419
- constructor(bare, path16, existing, gitDir) {
14590
+ constructor(bare, path17, existing, gitDir) {
13420
14591
  this.bare = bare;
13421
- this.path = path16;
14592
+ this.path = path17;
13422
14593
  this.existing = existing;
13423
14594
  this.gitDir = gitDir;
13424
14595
  }
@@ -13430,7 +14601,7 @@ var init_InitSummary = __esm({
13430
14601
  function hasBareCommand(command) {
13431
14602
  return command.includes(bareCommand);
13432
14603
  }
13433
- function initTask(bare = false, path16, customArgs) {
14604
+ function initTask(bare = false, path17, customArgs) {
13434
14605
  const commands = ["init", ...customArgs];
13435
14606
  if (bare && !hasBareCommand(commands)) {
13436
14607
  commands.splice(1, 0, bareCommand);
@@ -13439,7 +14610,7 @@ function initTask(bare = false, path16, customArgs) {
13439
14610
  commands,
13440
14611
  format: "utf-8",
13441
14612
  parser(text2) {
13442
- return parseInit(commands.includes("--bare"), path16, text2);
14613
+ return parseInit(commands.includes("--bare"), path17, text2);
13443
14614
  }
13444
14615
  };
13445
14616
  }
@@ -14255,12 +15426,12 @@ var init_FileStatusSummary = __esm({
14255
15426
  "use strict";
14256
15427
  fromPathRegex = /^(.+)\0(.+)$/;
14257
15428
  FileStatusSummary = class {
14258
- constructor(path16, index, working_dir) {
14259
- this.path = path16;
15429
+ constructor(path17, index, working_dir) {
15430
+ this.path = path17;
14260
15431
  this.index = index;
14261
15432
  this.working_dir = working_dir;
14262
15433
  if (index === "R" || working_dir === "R") {
14263
- const detail = fromPathRegex.exec(path16) || [null, path16, path16];
15434
+ const detail = fromPathRegex.exec(path17) || [null, path17, path17];
14264
15435
  this.from = detail[2] || "";
14265
15436
  this.path = detail[1] || "";
14266
15437
  }
@@ -14291,14 +15462,14 @@ function splitLine(result, lineStr) {
14291
15462
  default:
14292
15463
  return;
14293
15464
  }
14294
- function data(index, workingDir, path16) {
15465
+ function data(index, workingDir, path17) {
14295
15466
  const raw = `${index}${workingDir}`;
14296
15467
  const handler = parsers6.get(raw);
14297
15468
  if (handler) {
14298
- handler(result, path16);
15469
+ handler(result, path17);
14299
15470
  }
14300
15471
  if (raw !== "##" && raw !== "!!") {
14301
- result.files.push(new FileStatusSummary(path16, index, workingDir));
15472
+ result.files.push(new FileStatusSummary(path17, index, workingDir));
14302
15473
  }
14303
15474
  }
14304
15475
  }
@@ -14611,9 +15782,9 @@ var init_simple_git_api = __esm({
14611
15782
  next
14612
15783
  );
14613
15784
  }
14614
- hashObject(path16, write) {
15785
+ hashObject(path17, write) {
14615
15786
  return this._runTask(
14616
- hashObjectTask(path16, write === true),
15787
+ hashObjectTask(path17, write === true),
14617
15788
  trailingFunctionArgument(arguments)
14618
15789
  );
14619
15790
  }
@@ -14966,8 +16137,8 @@ var init_branch = __esm({
14966
16137
  }
14967
16138
  });
14968
16139
  function toPath(input) {
14969
- const path16 = input.trim().replace(/^["']|["']$/g, "");
14970
- return path16 && normalize(path16);
16140
+ const path17 = input.trim().replace(/^["']|["']$/g, "");
16141
+ return path17 && normalize(path17);
14971
16142
  }
14972
16143
  var parseCheckIgnore;
14973
16144
  var init_CheckIgnore = __esm({
@@ -15281,8 +16452,8 @@ __export(sub_module_exports, {
15281
16452
  subModuleTask: () => subModuleTask,
15282
16453
  updateSubModuleTask: () => updateSubModuleTask
15283
16454
  });
15284
- function addSubModuleTask(repo, path16) {
15285
- return subModuleTask(["add", repo, path16]);
16455
+ function addSubModuleTask(repo, path17) {
16456
+ return subModuleTask(["add", repo, path17]);
15286
16457
  }
15287
16458
  function initSubModuleTask(customArgs) {
15288
16459
  return subModuleTask(["init", ...customArgs]);
@@ -15612,8 +16783,8 @@ var require_git = __commonJS2({
15612
16783
  }
15613
16784
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
15614
16785
  };
15615
- Git2.prototype.submoduleAdd = function(repo, path16, then) {
15616
- return this._runTask(addSubModuleTask2(repo, path16), trailingFunctionArgument2(arguments));
16786
+ Git2.prototype.submoduleAdd = function(repo, path17, then) {
16787
+ return this._runTask(addSubModuleTask2(repo, path17), trailingFunctionArgument2(arguments));
15617
16788
  };
15618
16789
  Git2.prototype.submoduleUpdate = function(args2, then) {
15619
16790
  return this._runTask(
@@ -16220,23 +17391,23 @@ function createGitClient(baseDir, options) {
16220
17391
  }
16221
17392
 
16222
17393
  // ../git/dist/lock-detector.js
16223
- import { execFile } from "child_process";
16224
- import fs6 from "fs/promises";
16225
- import path10 from "path";
17394
+ import { execFile as execFile4 } from "child_process";
17395
+ import fs7 from "fs/promises";
17396
+ import path11 from "path";
16226
17397
  import { promisify } from "util";
16227
- var execFileAsync = promisify(execFile);
17398
+ var execFileAsync = promisify(execFile4);
16228
17399
  async function getIndexLockPath(repoPath) {
16229
17400
  try {
16230
17401
  const { stdout } = await execFileAsync("git", ["rev-parse", "--git-path", "index.lock"], { cwd: repoPath });
16231
- return path10.resolve(repoPath, stdout.trim());
17402
+ return path11.resolve(repoPath, stdout.trim());
16232
17403
  } catch {
16233
- return path10.join(repoPath, ".git", "index.lock");
17404
+ return path11.join(repoPath, ".git", "index.lock");
16234
17405
  }
16235
17406
  }
16236
17407
  async function getLockInfo(repoPath) {
16237
17408
  const lockPath = await getIndexLockPath(repoPath);
16238
17409
  try {
16239
- const stat3 = await fs6.stat(lockPath);
17410
+ const stat3 = await fs7.stat(lockPath);
16240
17411
  return {
16241
17412
  path: lockPath,
16242
17413
  ageMs: Date.now() - stat3.mtimeMs
@@ -16247,7 +17418,7 @@ async function getLockInfo(repoPath) {
16247
17418
  }
16248
17419
  async function removeLock(repoPath) {
16249
17420
  const lockPath = await getIndexLockPath(repoPath);
16250
- await fs6.rm(lockPath, { force: true });
17421
+ await fs7.rm(lockPath, { force: true });
16251
17422
  }
16252
17423
  async function isLocked(repoPath) {
16253
17424
  return await getLockInfo(repoPath) !== null;
@@ -16274,10 +17445,10 @@ var AsyncReaderWriterLock = class {
16274
17445
  this.readers++;
16275
17446
  return;
16276
17447
  }
16277
- return new Promise((resolve6) => {
17448
+ return new Promise((resolve7) => {
16278
17449
  this.readQueue.push(() => {
16279
17450
  this.readers++;
16280
- resolve6();
17451
+ resolve7();
16281
17452
  });
16282
17453
  });
16283
17454
  }
@@ -16291,11 +17462,11 @@ var AsyncReaderWriterLock = class {
16291
17462
  return;
16292
17463
  }
16293
17464
  this.writerWaiting = true;
16294
- return new Promise((resolve6) => {
17465
+ return new Promise((resolve7) => {
16295
17466
  this.writeQueue.push(() => {
16296
17467
  this.writerWaiting = this.writeQueue.length > 0;
16297
17468
  this.writer = true;
16298
- resolve6();
17469
+ resolve7();
16299
17470
  });
16300
17471
  });
16301
17472
  }
@@ -16504,13 +17675,13 @@ function parseRule(rule) {
16504
17675
  function normalizePath(filePath, cwd) {
16505
17676
  let resolved = filePath;
16506
17677
  if (resolved.startsWith("~/")) {
16507
- resolved = path12.join(os4.homedir(), resolved.slice(2));
17678
+ resolved = path13.join(os5.homedir(), resolved.slice(2));
16508
17679
  } else if (resolved.startsWith("./")) {
16509
- resolved = path12.join(cwd, resolved.slice(2));
16510
- } else if (!path12.isAbsolute(resolved)) {
16511
- resolved = path12.join(cwd, resolved);
17680
+ resolved = path13.join(cwd, resolved.slice(2));
17681
+ } else if (!path13.isAbsolute(resolved)) {
17682
+ resolved = path13.join(cwd, resolved);
16512
17683
  }
16513
- return path12.normalize(resolved).replace(/\\/g, "/");
17684
+ return path13.normalize(resolved).replace(/\\/g, "/");
16514
17685
  }
16515
17686
  function matchesGlob(pattern, filePath, cwd) {
16516
17687
  const normalizedPattern = normalizePath(pattern, cwd);
@@ -16557,11 +17728,11 @@ function formatRule(rule) {
16557
17728
  }
16558
17729
  async function writeFileAtomic(filePath, data) {
16559
17730
  const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
16560
- await fs8.promises.writeFile(tmpPath, data);
17731
+ await fs9.promises.writeFile(tmpPath, data);
16561
17732
  try {
16562
- await fs8.promises.rename(tmpPath, filePath);
17733
+ await fs9.promises.rename(tmpPath, filePath);
16563
17734
  } catch (error) {
16564
- await fs8.promises.rm(tmpPath, { force: true });
17735
+ await fs9.promises.rm(tmpPath, { force: true });
16565
17736
  throw error;
16566
17737
  }
16567
17738
  }
@@ -16570,7 +17741,7 @@ async function loadSettingsFile(filePath) {
16570
17741
  return {};
16571
17742
  }
16572
17743
  try {
16573
- const content = await fs8.promises.readFile(filePath, "utf-8");
17744
+ const content = await fs9.promises.readFile(filePath, "utf-8");
16574
17745
  return JSON.parse(content);
16575
17746
  } catch (error) {
16576
17747
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -16585,7 +17756,7 @@ async function loadSettingsFile(filePath) {
16585
17756
  }
16586
17757
  async function readSettingsFileForUpdate(filePath) {
16587
17758
  try {
16588
- const content = await fs8.promises.readFile(filePath, "utf-8");
17759
+ const content = await fs9.promises.readFile(filePath, "utf-8");
16589
17760
  return JSON.parse(content);
16590
17761
  } catch (error) {
16591
17762
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -16631,11 +17802,11 @@ var SettingsManager = class {
16631
17802
  return this.initPromise;
16632
17803
  }
16633
17804
  getUserSettingsPath() {
16634
- const configDir = process.env.CLAUDE_CONFIG_DIR || path12.join(os4.homedir(), ".claude");
16635
- return path12.join(configDir, "settings.json");
17805
+ const configDir = process.env.CLAUDE_CONFIG_DIR || path13.join(os5.homedir(), ".claude");
17806
+ return path13.join(configDir, "settings.json");
16636
17807
  }
16637
17808
  getProjectSettingsPath() {
16638
- return path12.join(this.cwd, ".claude", "settings.json");
17809
+ return path13.join(this.cwd, ".claude", "settings.json");
16639
17810
  }
16640
17811
  /**
16641
17812
  * Local settings are anchored to the primary worktree so every worktree of
@@ -16643,7 +17814,7 @@ var SettingsManager = class {
16643
17814
  * avoids re-prompting for the same permission in every worktree.
16644
17815
  */
16645
17816
  getLocalSettingsPath() {
16646
- return path12.join(this.repoRoot, ".claude", "settings.local.json");
17817
+ return path13.join(this.repoRoot, ".claude", "settings.local.json");
16647
17818
  }
16648
17819
  async loadAllSettings() {
16649
17820
  this.repoRoot = await resolveMainRepoPath(this.cwd);
@@ -16701,8 +17872,8 @@ var SettingsManager = class {
16701
17872
  merged.model = settings.model;
16702
17873
  }
16703
17874
  if (settings.posthogApprovedExecTools) {
16704
- for (const tool of settings.posthogApprovedExecTools) {
16705
- posthogApprovedExecTools.add(tool);
17875
+ for (const tool2 of settings.posthogApprovedExecTools) {
17876
+ posthogApprovedExecTools.add(tool2);
16706
17877
  }
16707
17878
  }
16708
17879
  }
@@ -16770,7 +17941,7 @@ var SettingsManager = class {
16770
17941
  }
16771
17942
  permissions.allow = Array.from(current2);
16772
17943
  const next = { ...existing, permissions };
16773
- await fs8.promises.mkdir(path12.dirname(filePath), { recursive: true });
17944
+ await fs9.promises.mkdir(path13.dirname(filePath), { recursive: true });
16774
17945
  await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
16775
17946
  `);
16776
17947
  this.localSettings = next;
@@ -16803,7 +17974,7 @@ var SettingsManager = class {
16803
17974
  ...existing,
16804
17975
  posthogApprovedExecTools: Array.from(current2)
16805
17976
  };
16806
- await fs8.promises.mkdir(path12.dirname(filePath), { recursive: true });
17977
+ await fs9.promises.mkdir(path13.dirname(filePath), { recursive: true });
16807
17978
  await writeFileAtomic(filePath, `${JSON.stringify(next, null, 2)}
16808
17979
  `);
16809
17980
  this.localSettings = next;
@@ -16909,7 +18080,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
16909
18080
  };
16910
18081
  }
16911
18082
  async newSession(params) {
16912
- if (fs9.existsSync(path13.resolve(os5.homedir(), ".claude.json.backup")) && !fs9.existsSync(path13.resolve(os5.homedir(), ".claude.json"))) {
18083
+ if (fs10.existsSync(path14.resolve(os6.homedir(), ".claude.json.backup")) && !fs10.existsSync(path14.resolve(os6.homedir(), ".claude.json"))) {
16913
18084
  throw RequestError2.authRequired();
16914
18085
  }
16915
18086
  const response = await this.createSession(params, {
@@ -17007,8 +18178,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17007
18178
  if (this.session.promptRunning) {
17008
18179
  this.session.input.push(userMessage);
17009
18180
  const order = this.session.nextPendingOrder++;
17010
- const cancelled = await new Promise((resolve6) => {
17011
- this.session.pendingMessages.set(promptUuid, { resolve: resolve6, order });
18181
+ const cancelled = await new Promise((resolve7) => {
18182
+ this.session.pendingMessages.set(promptUuid, { resolve: resolve7, order });
17012
18183
  });
17013
18184
  if (cancelled) {
17014
18185
  return { stopReason: "cancelled" };
@@ -17530,7 +18701,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17530
18701
  const { resume, forkSession } = creationOpts;
17531
18702
  const isResume = !!resume;
17532
18703
  const meta = params._meta;
17533
- const taskId = meta?.persistence?.taskId;
18704
+ const taskId = resolveTaskId(meta);
18705
+ const cloudRun = isCloudRun(meta);
17534
18706
  const effort = meta?.claudeCode?.options?.effort;
17535
18707
  let sessionId;
17536
18708
  if (forkSession) {
@@ -17545,6 +18717,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17545
18717
  await settingsManager.initialize();
17546
18718
  const earlyModelId = settingsManager.getSettings().model || meta?.model || "";
17547
18719
  const mcpServers = supportsMcpInjection(earlyModelId) ? parseMcpServers(params) : {};
18720
+ const localToolsServer = createLocalToolsMcpServer(
18721
+ { cwd, token: resolveGithubToken(), taskId },
18722
+ meta
18723
+ );
18724
+ if (localToolsServer) {
18725
+ mcpServers[LOCAL_TOOLS_MCP_NAME] = localToolsServer;
18726
+ } else if (cloudRun) {
18727
+ this.logger.warn(
18728
+ "Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
18729
+ );
18730
+ }
17548
18731
  const systemPrompt = buildSystemPrompt(meta?.systemPrompt);
17549
18732
  if (meta?.mcpToolApprovals) {
17550
18733
  setMcpToolApprovalStates(meta.mcpToolApprovals);
@@ -17580,7 +18763,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17580
18763
  onProcessExited: this.options?.onProcessExited,
17581
18764
  effort,
17582
18765
  enrichmentDeps: this.enrichment?.deps,
17583
- enrichedReadCache: this.enrichedReadCache
18766
+ enrichedReadCache: this.enrichedReadCache,
18767
+ cloudMode: cloudRun
17584
18768
  });
17585
18769
  const abortController = options.abortController;
17586
18770
  const q = query({ prompt: input, options });
@@ -17912,7 +19096,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17912
19096
  */
17913
19097
  deferBackgroundFetches(q) {
17914
19098
  Promise.all([
17915
- new Promise((resolve6) => setTimeout(resolve6, 10)).then(
19099
+ new Promise((resolve7) => setTimeout(resolve7, 10)).then(
17916
19100
  () => this.sendAvailableCommandsUpdate()
17917
19101
  ),
17918
19102
  fetchMcpToolMetadata(q, this.logger).then(() => {
@@ -18190,9 +19374,9 @@ function resetUsage(state) {
18190
19374
  }
18191
19375
 
18192
19376
  // src/adapters/codex/settings.ts
18193
- import * as fs10 from "fs";
18194
- import * as os6 from "os";
18195
- import * as path14 from "path";
19377
+ import * as fs11 from "fs";
19378
+ import * as os7 from "os";
19379
+ import * as path15 from "path";
18196
19380
  var CodexSettingsManager = class {
18197
19381
  cwd;
18198
19382
  settings = { mcpServerNames: [] };
@@ -18203,12 +19387,12 @@ var CodexSettingsManager = class {
18203
19387
  async initialize() {
18204
19388
  }
18205
19389
  getConfigPath() {
18206
- return path14.join(os6.homedir(), ".codex", "config.toml");
19390
+ return path15.join(os7.homedir(), ".codex", "config.toml");
18207
19391
  }
18208
19392
  loadSettings() {
18209
19393
  const configPath = this.getConfigPath();
18210
19394
  try {
18211
- const content = fs10.readFileSync(configPath, "utf-8");
19395
+ const content = fs11.readFileSync(configPath, "utf-8");
18212
19396
  this.settings = parseCodexToml(content, this.cwd);
18213
19397
  } catch {
18214
19398
  this.settings = { mcpServerNames: [] };
@@ -18266,7 +19450,7 @@ function parseCodexToml(content, cwd) {
18266
19450
  // src/adapters/codex/spawn.ts
18267
19451
  import { spawn as spawn4 } from "child_process";
18268
19452
  import { existsSync as existsSync4 } from "fs";
18269
- import { delimiter, dirname as dirname5 } from "path";
19453
+ import { delimiter, dirname as dirname6 } from "path";
18270
19454
  function buildConfigArgs(options) {
18271
19455
  const args2 = [];
18272
19456
  args2.push("-c", `features.remote_models=false`);
@@ -18317,7 +19501,7 @@ function spawnCodexProcess(options) {
18317
19501
  }
18318
19502
  const { command, args: args2 } = findCodexBinary(options);
18319
19503
  if (options.binaryPath && existsSync4(options.binaryPath)) {
18320
- const binDir = dirname5(options.binaryPath);
19504
+ const binDir = dirname6(options.binaryPath);
18321
19505
  env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
18322
19506
  }
18323
19507
  logger.info("Spawning codex-acp process", {
@@ -18422,8 +19606,7 @@ function getCurrentPermissionMode(currentModeId, fallbackMode) {
18422
19606
  var STRUCTURED_OUTPUT_INSTRUCTIONS = `
18423
19607
 
18424
19608
  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.`;
18425
- function resolveStructuredOutputMcpScript() {
18426
- const rel = "adapters/codex/structured-output-mcp-server.js";
19609
+ function resolveBundledMcpScript(rel) {
18427
19610
  let dir = import.meta.dirname ?? __dirname;
18428
19611
  for (let i2 = 0; i2 < 5; i2++) {
18429
19612
  const candidate = resolvePath(dir, rel);
@@ -18435,7 +19618,9 @@ function resolveStructuredOutputMcpScript() {
18435
19618
  );
18436
19619
  }
18437
19620
  function buildStructuredOutputMcpServer(jsonSchema) {
18438
- const scriptPath = resolveStructuredOutputMcpScript();
19621
+ const scriptPath = resolveBundledMcpScript(
19622
+ "adapters/codex/structured-output-mcp-server.js"
19623
+ );
18439
19624
  const schemaBase64 = Buffer.from(JSON.stringify(jsonSchema)).toString(
18440
19625
  "base64"
18441
19626
  );
@@ -18446,6 +19631,30 @@ function buildStructuredOutputMcpServer(jsonSchema) {
18446
19631
  env: [{ name: "POSTHOG_OUTPUT_SCHEMA", value: schemaBase64 }]
18447
19632
  };
18448
19633
  }
19634
+ function buildLocalToolsMcpServer(ctx, enabledNames) {
19635
+ const scriptPath = resolveBundledMcpScript(
19636
+ "adapters/codex/local-tools-mcp-server.js"
19637
+ );
19638
+ const ctxBase64 = Buffer.from(JSON.stringify(ctx)).toString("base64");
19639
+ const env = [
19640
+ { name: "POSTHOG_LOCAL_TOOLS_CTX", value: ctxBase64 },
19641
+ { name: "POSTHOG_LOCAL_TOOLS_ENABLED", value: enabledNames.join(",") }
19642
+ ];
19643
+ if (ctx.token) {
19644
+ env.push(
19645
+ ...Object.entries(ghTokenEnv(ctx.token)).map(([name2, value]) => ({
19646
+ name: name2,
19647
+ value
19648
+ }))
19649
+ );
19650
+ }
19651
+ return {
19652
+ name: LOCAL_TOOLS_MCP_NAME,
19653
+ command: process.execPath,
19654
+ args: [scriptPath],
19655
+ env
19656
+ };
19657
+ }
18449
19658
  var CodexAcpAgent = class extends BaseAcpAgent {
18450
19659
  adapterName = "codex";
18451
19660
  codexProcess;
@@ -18533,14 +19742,17 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18533
19742
  async newSession(params) {
18534
19743
  const meta = params._meta;
18535
19744
  const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
18536
- const injectedParams = this.applyStructuredOutput(params, meta);
19745
+ const injectedParams = this.applyLocalTools(
19746
+ this.applyStructuredOutput(params, meta),
19747
+ meta
19748
+ );
18537
19749
  const response = await this.codexConnection.newSession(injectedParams);
18538
19750
  response.configOptions = normalizeCodexConfigOptions(
18539
19751
  response.configOptions
18540
19752
  );
18541
19753
  this.sessionState = createSessionState(response.sessionId, params.cwd, {
18542
19754
  taskRunId: meta?.taskRunId,
18543
- taskId: meta?.taskId ?? meta?.persistence?.taskId,
19755
+ taskId: resolveTaskId(meta),
18544
19756
  modeId: response.modes?.currentModeId ?? "auto",
18545
19757
  modelId: response.models?.currentModelId,
18546
19758
  permissionMode: requestedPermissionMode
@@ -18567,7 +19779,10 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18567
19779
  }
18568
19780
  async loadSession(params) {
18569
19781
  const meta = params._meta;
18570
- const injectedParams = this.applyStructuredOutput(params, meta);
19782
+ const injectedParams = this.applyLocalTools(
19783
+ this.applyStructuredOutput(params, meta),
19784
+ meta
19785
+ );
18571
19786
  const response = await this.codexConnection.loadSession(injectedParams);
18572
19787
  response.configOptions = normalizeCodexConfigOptions(
18573
19788
  response.configOptions
@@ -18578,7 +19793,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18578
19793
  );
18579
19794
  this.sessionState = createSessionState(params.sessionId, params.cwd, {
18580
19795
  taskRunId: meta?.taskRunId,
18581
- taskId: meta?.taskId ?? meta?.persistence?.taskId,
19796
+ taskId: resolveTaskId(meta),
18582
19797
  modeId: response.modes?.currentModeId ?? "auto",
18583
19798
  permissionMode: currentPermissionMode
18584
19799
  });
@@ -18595,13 +19810,16 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18595
19810
  }
18596
19811
  async unstable_resumeSession(params) {
18597
19812
  const meta = params._meta;
18598
- const injectedParams = this.applyStructuredOutput(
18599
- {
18600
- sessionId: params.sessionId,
18601
- cwd: params.cwd,
18602
- mcpServers: params.mcpServers ?? [],
18603
- _meta: params._meta
18604
- },
19813
+ const injectedParams = this.applyLocalTools(
19814
+ this.applyStructuredOutput(
19815
+ {
19816
+ sessionId: params.sessionId,
19817
+ cwd: params.cwd,
19818
+ mcpServers: params.mcpServers ?? [],
19819
+ _meta: params._meta
19820
+ },
19821
+ meta
19822
+ ),
18605
19823
  meta
18606
19824
  );
18607
19825
  const loadResponse = await this.codexConnection.loadSession(injectedParams);
@@ -18614,7 +19832,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18614
19832
  );
18615
19833
  this.sessionState = createSessionState(params.sessionId, params.cwd, {
18616
19834
  taskRunId: meta?.taskRunId,
18617
- taskId: meta?.taskId ?? meta?.persistence?.taskId,
19835
+ taskId: resolveTaskId(meta),
18618
19836
  modeId: loadResponse.modes?.currentModeId ?? "auto",
18619
19837
  permissionMode: currentPermissionMode
18620
19838
  });
@@ -18635,12 +19853,15 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18635
19853
  }
18636
19854
  async unstable_forkSession(params) {
18637
19855
  const meta = params._meta;
18638
- const injectedParams = this.applyStructuredOutput(
18639
- {
18640
- cwd: params.cwd,
18641
- mcpServers: params.mcpServers ?? [],
18642
- _meta: params._meta
18643
- },
19856
+ const injectedParams = this.applyLocalTools(
19857
+ this.applyStructuredOutput(
19858
+ {
19859
+ cwd: params.cwd,
19860
+ mcpServers: params.mcpServers ?? [],
19861
+ _meta: params._meta
19862
+ },
19863
+ meta
19864
+ ),
18644
19865
  meta
18645
19866
  );
18646
19867
  const newResponse = await this.codexConnection.newSession(injectedParams);
@@ -18650,7 +19871,7 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18650
19871
  const requestedPermissionMode = toCodexPermissionMode(meta?.permissionMode);
18651
19872
  this.sessionState = createSessionState(newResponse.sessionId, params.cwd, {
18652
19873
  taskRunId: meta?.taskRunId,
18653
- taskId: meta?.taskId ?? meta?.persistence?.taskId,
19874
+ taskId: resolveTaskId(meta),
18654
19875
  modeId: newResponse.modes?.currentModeId ?? "auto",
18655
19876
  permissionMode: requestedPermissionMode
18656
19877
  });
@@ -18687,6 +19908,41 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18687
19908
  }
18688
19909
  };
18689
19910
  }
19911
+ /**
19912
+ * Injects the stdio general local-tools MCP server. Tools self-gate via the
19913
+ * registry (e.g. signed-commit is cloud-only and needs a GH token), so the
19914
+ * server is only injected when at least one tool's gate passes. Their
19915
+ * instructions already live in the shared cloud system prompt, so only the
19916
+ * server needs injecting here.
19917
+ */
19918
+ applyLocalTools(request, meta) {
19919
+ const cwd = request.cwd;
19920
+ if (!cwd) {
19921
+ return request;
19922
+ }
19923
+ const ctx = {
19924
+ cwd,
19925
+ token: resolveGithubToken(),
19926
+ taskId: resolveTaskId(meta)
19927
+ };
19928
+ const tools = enabledLocalTools(ctx, meta);
19929
+ if (tools.length === 0) {
19930
+ if (isCloudRun(meta)) {
19931
+ this.logger.warn(
19932
+ "Cloud run registered no local tools \u2014 missing GH_TOKEN/GITHUB_TOKEN? signed commits unavailable"
19933
+ );
19934
+ }
19935
+ return request;
19936
+ }
19937
+ const mcpServer = buildLocalToolsMcpServer(
19938
+ ctx,
19939
+ tools.map((t) => t.name)
19940
+ );
19941
+ return {
19942
+ ...request,
19943
+ mcpServers: [...request.mcpServers ?? [], mcpServer]
19944
+ };
19945
+ }
18690
19946
  async applyInitialPermissionMode(sessionId, permissionMode, currentModeId) {
18691
19947
  if (!permissionMode) {
18692
19948
  return;
@@ -19267,9 +20523,9 @@ var PostHogAPIClient = class {
19267
20523
  };
19268
20524
 
19269
20525
  // src/session-log-writer.ts
19270
- import fs11 from "fs";
20526
+ import fs12 from "fs";
19271
20527
  import fsp from "fs/promises";
19272
- import path15 from "path";
20528
+ import path16 from "path";
19273
20529
  var SessionLogWriter = class _SessionLogWriter {
19274
20530
  static FLUSH_DEBOUNCE_MS = 500;
19275
20531
  static FLUSH_MAX_INTERVAL_MS = 5e3;
@@ -19305,13 +20561,13 @@ var SessionLogWriter = class _SessionLogWriter {
19305
20561
  this.sessions.set(sessionId, { context, currentTurnMessages: [] });
19306
20562
  this.lastFlushAttemptTime.set(sessionId, Date.now());
19307
20563
  if (this.localCachePath) {
19308
- const sessionDir = path15.join(
20564
+ const sessionDir = path16.join(
19309
20565
  this.localCachePath,
19310
20566
  "sessions",
19311
20567
  context.runId
19312
20568
  );
19313
20569
  try {
19314
- fs11.mkdirSync(sessionDir, { recursive: true });
20570
+ fs12.mkdirSync(sessionDir, { recursive: true });
19315
20571
  } catch (error) {
19316
20572
  this.logger.warn("Failed to create local cache directory", {
19317
20573
  sessionDir,
@@ -19563,14 +20819,14 @@ var SessionLogWriter = class _SessionLogWriter {
19563
20819
  if (!this.localCachePath) return;
19564
20820
  const session = this.sessions.get(sessionId);
19565
20821
  if (!session) return;
19566
- const logPath = path15.join(
20822
+ const logPath = path16.join(
19567
20823
  this.localCachePath,
19568
20824
  "sessions",
19569
20825
  session.context.runId,
19570
20826
  "logs.ndjson"
19571
20827
  );
19572
20828
  try {
19573
- fs11.appendFileSync(logPath, `${JSON.stringify(entry)}
20829
+ fs12.appendFileSync(logPath, `${JSON.stringify(entry)}
19574
20830
  `);
19575
20831
  } catch (error) {
19576
20832
  this.logger.warn("Failed to write to local cache", {
@@ -19582,13 +20838,13 @@ var SessionLogWriter = class _SessionLogWriter {
19582
20838
  }
19583
20839
  }
19584
20840
  static async cleanupOldSessions(localCachePath) {
19585
- const sessionsDir = path15.join(localCachePath, "sessions");
20841
+ const sessionsDir = path16.join(localCachePath, "sessions");
19586
20842
  let deleted = 0;
19587
20843
  try {
19588
20844
  const entries = await fsp.readdir(sessionsDir);
19589
20845
  const now = Date.now();
19590
20846
  for (const entry of entries) {
19591
- const entryPath = path15.join(sessionsDir, entry);
20847
+ const entryPath = path16.join(sessionsDir, entry);
19592
20848
  try {
19593
20849
  const stats = await fsp.stat(entryPath);
19594
20850
  if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
@@ -19742,4 +20998,17 @@ var Agent = class {
19742
20998
  export {
19743
20999
  Agent
19744
21000
  };
21001
+ /*! Bundled license information:
21002
+
21003
+ git-url-parse/lib/index.js:
21004
+ (*!
21005
+ * buildToken
21006
+ * Builds OAuth token prefix (helper function)
21007
+ *
21008
+ * @name buildToken
21009
+ * @function
21010
+ * @param {GitUrl} obj The parsed Git url object.
21011
+ * @return {String} token prefix
21012
+ *)
21013
+ */
19745
21014
  //# sourceMappingURL=agent.js.map