@posthog/agent 2.3.363 → 2.3.370
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +1073 -192
- package/dist/agent.js.map +1 -1
- package/dist/posthog-api.d.ts +2 -1
- package/dist/posthog-api.js +5 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.js +1002 -121
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +990 -109
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/enrichment/file-enricher.test.ts +137 -3
- package/src/enrichment/file-enricher.ts +96 -5
- package/src/posthog-api.ts +11 -3
- package/src/utils/gateway.ts +7 -0
|
@@ -809,15 +809,15 @@ var require_src2 = __commonJS({
|
|
|
809
809
|
var fs_1 = __require("fs");
|
|
810
810
|
var debug_1 = __importDefault(require_src());
|
|
811
811
|
var log = debug_1.default("@kwsites/file-exists");
|
|
812
|
-
function check(path15,
|
|
812
|
+
function check(path15, isFile2, isDirectory) {
|
|
813
813
|
log(`checking %s`, path15);
|
|
814
814
|
try {
|
|
815
|
-
const
|
|
816
|
-
if (
|
|
815
|
+
const stat2 = fs_1.statSync(path15);
|
|
816
|
+
if (stat2.isFile() && isFile2) {
|
|
817
817
|
log(`[OK] path represents a file`);
|
|
818
818
|
return true;
|
|
819
819
|
}
|
|
820
|
-
if (
|
|
820
|
+
if (stat2.isDirectory() && isDirectory) {
|
|
821
821
|
log(`[OK] path represents a directory`);
|
|
822
822
|
return true;
|
|
823
823
|
}
|
|
@@ -947,10 +947,10 @@ var require_tree_sitter = __commonJS({
|
|
|
947
947
|
};
|
|
948
948
|
readAsync = (filename, binary2 = true) => {
|
|
949
949
|
filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
|
|
950
|
-
return new Promise((
|
|
950
|
+
return new Promise((resolve6, reject) => {
|
|
951
951
|
fs.readFile(filename, binary2 ? void 0 : "utf8", (err2, data) => {
|
|
952
952
|
if (err2) reject(err2);
|
|
953
|
-
else
|
|
953
|
+
else resolve6(binary2 ? data.buffer : data);
|
|
954
954
|
});
|
|
955
955
|
});
|
|
956
956
|
};
|
|
@@ -991,13 +991,13 @@ var require_tree_sitter = __commonJS({
|
|
|
991
991
|
}
|
|
992
992
|
readAsync = (url) => {
|
|
993
993
|
if (isFileURI(url)) {
|
|
994
|
-
return new Promise((reject,
|
|
994
|
+
return new Promise((reject, resolve6) => {
|
|
995
995
|
var xhr = new XMLHttpRequest();
|
|
996
996
|
xhr.open("GET", url, true);
|
|
997
997
|
xhr.responseType = "arraybuffer";
|
|
998
998
|
xhr.onload = () => {
|
|
999
999
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
1000
|
-
|
|
1000
|
+
resolve6(xhr.response);
|
|
1001
1001
|
}
|
|
1002
1002
|
reject(xhr.status);
|
|
1003
1003
|
};
|
|
@@ -1957,8 +1957,8 @@ var require_tree_sitter = __commonJS({
|
|
|
1957
1957
|
}
|
|
1958
1958
|
var libFile = locateFile(libName2);
|
|
1959
1959
|
if (flags2.loadAsync) {
|
|
1960
|
-
return new Promise(function(
|
|
1961
|
-
asyncLoad(libFile,
|
|
1960
|
+
return new Promise(function(resolve6, reject) {
|
|
1961
|
+
asyncLoad(libFile, resolve6, reject);
|
|
1962
1962
|
});
|
|
1963
1963
|
}
|
|
1964
1964
|
if (!readBinary) {
|
|
@@ -3785,7 +3785,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
3785
3785
|
|
|
3786
3786
|
// src/server/agent-server.ts
|
|
3787
3787
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
|
|
3788
|
-
import { basename as basename2, join as
|
|
3788
|
+
import { basename as basename2, join as join12 } from "path";
|
|
3789
3789
|
import { pathToFileURL } from "url";
|
|
3790
3790
|
import {
|
|
3791
3791
|
ClientSideConnection as ClientSideConnection2,
|
|
@@ -8374,10 +8374,10 @@ async function getIndexLockPath(repoPath) {
|
|
|
8374
8374
|
async function getLockInfo(repoPath) {
|
|
8375
8375
|
const lockPath = await getIndexLockPath(repoPath);
|
|
8376
8376
|
try {
|
|
8377
|
-
const
|
|
8377
|
+
const stat2 = await fs2.stat(lockPath);
|
|
8378
8378
|
return {
|
|
8379
8379
|
path: lockPath,
|
|
8380
|
-
ageMs: Date.now() -
|
|
8380
|
+
ageMs: Date.now() - stat2.mtimeMs
|
|
8381
8381
|
};
|
|
8382
8382
|
} catch {
|
|
8383
8383
|
return null;
|
|
@@ -8412,10 +8412,10 @@ var AsyncReaderWriterLock = class {
|
|
|
8412
8412
|
this.readers++;
|
|
8413
8413
|
return;
|
|
8414
8414
|
}
|
|
8415
|
-
return new Promise((
|
|
8415
|
+
return new Promise((resolve6) => {
|
|
8416
8416
|
this.readQueue.push(() => {
|
|
8417
8417
|
this.readers++;
|
|
8418
|
-
|
|
8418
|
+
resolve6();
|
|
8419
8419
|
});
|
|
8420
8420
|
});
|
|
8421
8421
|
}
|
|
@@ -8429,11 +8429,11 @@ var AsyncReaderWriterLock = class {
|
|
|
8429
8429
|
return;
|
|
8430
8430
|
}
|
|
8431
8431
|
this.writerWaiting = true;
|
|
8432
|
-
return new Promise((
|
|
8432
|
+
return new Promise((resolve6) => {
|
|
8433
8433
|
this.writeQueue.push(() => {
|
|
8434
8434
|
this.writerWaiting = this.writeQueue.length > 0;
|
|
8435
8435
|
this.writer = true;
|
|
8436
|
-
|
|
8436
|
+
resolve6();
|
|
8437
8437
|
});
|
|
8438
8438
|
});
|
|
8439
8439
|
}
|
|
@@ -8605,7 +8605,7 @@ import { z as z4 } from "zod";
|
|
|
8605
8605
|
// package.json
|
|
8606
8606
|
var package_default = {
|
|
8607
8607
|
name: "@posthog/agent",
|
|
8608
|
-
version: "2.3.
|
|
8608
|
+
version: "2.3.370",
|
|
8609
8609
|
repository: "https://github.com/PostHog/code",
|
|
8610
8610
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8611
8611
|
exports: {
|
|
@@ -8860,17 +8860,17 @@ var Pushable = class {
|
|
|
8860
8860
|
resolvers = [];
|
|
8861
8861
|
done = false;
|
|
8862
8862
|
push(item) {
|
|
8863
|
-
const
|
|
8864
|
-
if (
|
|
8865
|
-
|
|
8863
|
+
const resolve6 = this.resolvers.shift();
|
|
8864
|
+
if (resolve6) {
|
|
8865
|
+
resolve6({ value: item, done: false });
|
|
8866
8866
|
} else {
|
|
8867
8867
|
this.queue.push(item);
|
|
8868
8868
|
}
|
|
8869
8869
|
}
|
|
8870
8870
|
end() {
|
|
8871
8871
|
this.done = true;
|
|
8872
|
-
for (const
|
|
8873
|
-
|
|
8872
|
+
for (const resolve6 of this.resolvers) {
|
|
8873
|
+
resolve6({ value: void 0, done: true });
|
|
8874
8874
|
}
|
|
8875
8875
|
this.resolvers = [];
|
|
8876
8876
|
}
|
|
@@ -8887,8 +8887,8 @@ var Pushable = class {
|
|
|
8887
8887
|
done: true
|
|
8888
8888
|
});
|
|
8889
8889
|
}
|
|
8890
|
-
return new Promise((
|
|
8891
|
-
this.resolvers.push(
|
|
8890
|
+
return new Promise((resolve6) => {
|
|
8891
|
+
this.resolvers.push(resolve6);
|
|
8892
8892
|
});
|
|
8893
8893
|
}
|
|
8894
8894
|
};
|
|
@@ -9002,20 +9002,20 @@ function nodeReadableToWebReadable(nodeStream) {
|
|
|
9002
9002
|
function nodeWritableToWebWritable(nodeStream) {
|
|
9003
9003
|
return new WritableStream2({
|
|
9004
9004
|
write(chunk) {
|
|
9005
|
-
return new Promise((
|
|
9005
|
+
return new Promise((resolve6, reject) => {
|
|
9006
9006
|
const ok = nodeStream.write(Buffer.from(chunk), (err2) => {
|
|
9007
9007
|
if (err2) reject(err2);
|
|
9008
9008
|
});
|
|
9009
9009
|
if (ok) {
|
|
9010
|
-
|
|
9010
|
+
resolve6();
|
|
9011
9011
|
} else {
|
|
9012
|
-
nodeStream.once("drain",
|
|
9012
|
+
nodeStream.once("drain", resolve6);
|
|
9013
9013
|
}
|
|
9014
9014
|
});
|
|
9015
9015
|
},
|
|
9016
9016
|
close() {
|
|
9017
|
-
return new Promise((
|
|
9018
|
-
nodeStream.end(
|
|
9017
|
+
return new Promise((resolve6) => {
|
|
9018
|
+
nodeStream.end(resolve6);
|
|
9019
9019
|
});
|
|
9020
9020
|
},
|
|
9021
9021
|
abort(reason) {
|
|
@@ -9046,11 +9046,13 @@ import * as path4 from "path";
|
|
|
9046
9046
|
|
|
9047
9047
|
// ../enricher/dist/index.js
|
|
9048
9048
|
var import_web_tree_sitter = __toESM(require_tree_sitter(), 1);
|
|
9049
|
-
import {
|
|
9049
|
+
import { statSync } from "fs";
|
|
9050
9050
|
import * as path3 from "path";
|
|
9051
|
+
import { existsSync } from "fs";
|
|
9052
|
+
import * as path22 from "path";
|
|
9051
9053
|
import { fileURLToPath } from "url";
|
|
9052
9054
|
import * as fs4 from "fs/promises";
|
|
9053
|
-
import * as
|
|
9055
|
+
import * as path32 from "path";
|
|
9054
9056
|
function getCapture(captures, name2) {
|
|
9055
9057
|
const found = captures.find((c) => c.name === name2);
|
|
9056
9058
|
return found ? found.node : null;
|
|
@@ -9165,6 +9167,22 @@ function walkNodes(root, type, callback) {
|
|
|
9165
9167
|
};
|
|
9166
9168
|
visit(root);
|
|
9167
9169
|
}
|
|
9170
|
+
var JSX_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
9171
|
+
"jsx_element",
|
|
9172
|
+
"jsx_fragment",
|
|
9173
|
+
"jsx_self_closing_element",
|
|
9174
|
+
"jsx_opening_element",
|
|
9175
|
+
"jsx_closing_element",
|
|
9176
|
+
"jsx_attribute"
|
|
9177
|
+
]);
|
|
9178
|
+
function isInsideJsx(node) {
|
|
9179
|
+
let cur = node.parent;
|
|
9180
|
+
while (cur) {
|
|
9181
|
+
if (JSX_NODE_TYPES.has(cur.type)) return true;
|
|
9182
|
+
cur = cur.parent;
|
|
9183
|
+
}
|
|
9184
|
+
return false;
|
|
9185
|
+
}
|
|
9168
9186
|
var JS_CAPTURE_METHODS = /* @__PURE__ */ new Set(["capture"]);
|
|
9169
9187
|
var JS_FLAG_METHODS = /* @__PURE__ */ new Set([
|
|
9170
9188
|
"getFeatureFlag",
|
|
@@ -9350,6 +9368,33 @@ var JS_QUERIES = {
|
|
|
9350
9368
|
object: (_) @client
|
|
9351
9369
|
property: (property_identifier) @method)
|
|
9352
9370
|
arguments: (arguments . (_) @first_arg)) @call
|
|
9371
|
+
`,
|
|
9372
|
+
imports: `
|
|
9373
|
+
(import_statement
|
|
9374
|
+
(import_clause
|
|
9375
|
+
(identifier) @default_name)
|
|
9376
|
+
source: (string (string_fragment) @source)) @stmt
|
|
9377
|
+
|
|
9378
|
+
(import_statement
|
|
9379
|
+
(import_clause
|
|
9380
|
+
(named_imports
|
|
9381
|
+
(import_specifier
|
|
9382
|
+
name: (identifier) @imported_name) @spec))
|
|
9383
|
+
source: (string (string_fragment) @source)) @stmt
|
|
9384
|
+
|
|
9385
|
+
(import_statement
|
|
9386
|
+
(import_clause
|
|
9387
|
+
(named_imports
|
|
9388
|
+
(import_specifier
|
|
9389
|
+
name: (identifier) @imported_name
|
|
9390
|
+
alias: (identifier) @local_name) @spec))
|
|
9391
|
+
source: (string (string_fragment) @source)) @stmt
|
|
9392
|
+
|
|
9393
|
+
(import_statement
|
|
9394
|
+
(import_clause
|
|
9395
|
+
(namespace_import
|
|
9396
|
+
(identifier) @namespace_name))
|
|
9397
|
+
source: (string (string_fragment) @source)) @stmt
|
|
9353
9398
|
`
|
|
9354
9399
|
};
|
|
9355
9400
|
var PY_QUERIES = {
|
|
@@ -9426,6 +9471,31 @@ var PY_QUERIES = {
|
|
|
9426
9471
|
object: (_) @client
|
|
9427
9472
|
attribute: (identifier) @method)
|
|
9428
9473
|
arguments: (argument_list . (_) @first_arg)) @call
|
|
9474
|
+
`,
|
|
9475
|
+
imports: `
|
|
9476
|
+
(import_from_statement
|
|
9477
|
+
module_name: (dotted_name) @source
|
|
9478
|
+
name: (dotted_name) @imported_name) @stmt
|
|
9479
|
+
|
|
9480
|
+
(import_from_statement
|
|
9481
|
+
module_name: (dotted_name) @source
|
|
9482
|
+
name: (aliased_import
|
|
9483
|
+
name: (dotted_name) @imported_name
|
|
9484
|
+
alias: (identifier) @local_name)) @stmt
|
|
9485
|
+
|
|
9486
|
+
(import_from_statement
|
|
9487
|
+
module_name: (relative_import
|
|
9488
|
+
(import_prefix) @relative_prefix
|
|
9489
|
+
(dotted_name)? @relative_name)
|
|
9490
|
+
name: (dotted_name) @imported_name) @stmt
|
|
9491
|
+
|
|
9492
|
+
(import_from_statement
|
|
9493
|
+
module_name: (relative_import
|
|
9494
|
+
(import_prefix) @relative_prefix
|
|
9495
|
+
(dotted_name)? @relative_name)
|
|
9496
|
+
name: (aliased_import
|
|
9497
|
+
name: (dotted_name) @imported_name
|
|
9498
|
+
alias: (identifier) @local_name)) @stmt
|
|
9429
9499
|
`
|
|
9430
9500
|
};
|
|
9431
9501
|
var GO_QUERIES = {
|
|
@@ -9817,7 +9887,7 @@ function buildConstantMap(pm, lang, tree) {
|
|
|
9817
9887
|
}
|
|
9818
9888
|
var POSTHOG_CLASS_NAMES2 = /* @__PURE__ */ new Set(["PostHog", "Posthog"]);
|
|
9819
9889
|
var GO_CONSTRUCTOR_NAMES2 = /* @__PURE__ */ new Set(["New", "NewWithConfig"]);
|
|
9820
|
-
async function findPostHogCalls(pm, source, languageId) {
|
|
9890
|
+
async function findPostHogCalls(pm, source, languageId, context) {
|
|
9821
9891
|
const ready = await pm.ensureReady(languageId);
|
|
9822
9892
|
if (!ready) {
|
|
9823
9893
|
return [];
|
|
@@ -9846,6 +9916,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
9846
9916
|
const clientNode = getCapture(match.captures, "client");
|
|
9847
9917
|
const methodNode = getCapture(match.captures, "method");
|
|
9848
9918
|
const keyNode = getCapture(match.captures, "key");
|
|
9919
|
+
const callNode = getCapture(match.captures, "call");
|
|
9849
9920
|
if (!clientNode || !methodNode || !keyNode) {
|
|
9850
9921
|
continue;
|
|
9851
9922
|
}
|
|
@@ -9871,7 +9942,8 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
9871
9942
|
key: cleanStringValue(keyNode.text),
|
|
9872
9943
|
line: keyNode.startPosition.row,
|
|
9873
9944
|
keyStartCol: keyNode.startPosition.column,
|
|
9874
|
-
keyEndCol: keyNode.endPosition.column
|
|
9945
|
+
keyEndCol: keyNode.endPosition.column,
|
|
9946
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
9875
9947
|
});
|
|
9876
9948
|
}
|
|
9877
9949
|
}
|
|
@@ -9926,6 +9998,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
9926
9998
|
const methodNode = getCapture(match.captures, "method");
|
|
9927
9999
|
const propNameNode = getCapture(match.captures, "prop_name");
|
|
9928
10000
|
const keyNode = getCapture(match.captures, "key");
|
|
10001
|
+
const callNode = getCapture(match.captures, "call");
|
|
9929
10002
|
if (!clientNode || !methodNode || !propNameNode || !keyNode) {
|
|
9930
10003
|
continue;
|
|
9931
10004
|
}
|
|
@@ -9948,7 +10021,8 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
9948
10021
|
key: cleanStringValue(keyNode.text),
|
|
9949
10022
|
line: keyNode.startPosition.row,
|
|
9950
10023
|
keyStartCol: keyNode.startPosition.column,
|
|
9951
|
-
keyEndCol: keyNode.endPosition.column
|
|
10024
|
+
keyEndCol: keyNode.endPosition.column,
|
|
10025
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
9952
10026
|
});
|
|
9953
10027
|
}
|
|
9954
10028
|
}
|
|
@@ -10045,6 +10119,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10045
10119
|
for (const match of matches) {
|
|
10046
10120
|
const funcNode = getCapture(match.captures, "func_name");
|
|
10047
10121
|
const keyNode = getCapture(match.captures, "key");
|
|
10122
|
+
const callNode = getCapture(match.captures, "call");
|
|
10048
10123
|
if (!funcNode || !keyNode) {
|
|
10049
10124
|
continue;
|
|
10050
10125
|
}
|
|
@@ -10055,7 +10130,8 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10055
10130
|
key: cleanStringValue(keyNode.text),
|
|
10056
10131
|
line: keyNode.startPosition.row,
|
|
10057
10132
|
keyStartCol: keyNode.startPosition.column,
|
|
10058
|
-
keyEndCol: keyNode.endPosition.column
|
|
10133
|
+
keyEndCol: keyNode.endPosition.column,
|
|
10134
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
10059
10135
|
});
|
|
10060
10136
|
}
|
|
10061
10137
|
}
|
|
@@ -10069,6 +10145,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10069
10145
|
for (const match of matches) {
|
|
10070
10146
|
const funcNode = getCapture(match.captures, "func_name");
|
|
10071
10147
|
const keyNode = getCapture(match.captures, "key");
|
|
10148
|
+
const callNode = getCapture(match.captures, "call");
|
|
10072
10149
|
if (!funcNode || !keyNode) {
|
|
10073
10150
|
continue;
|
|
10074
10151
|
}
|
|
@@ -10078,7 +10155,8 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10078
10155
|
key: cleanStringValue(keyNode.text),
|
|
10079
10156
|
line: keyNode.startPosition.row,
|
|
10080
10157
|
keyStartCol: keyNode.startPosition.column,
|
|
10081
|
-
keyEndCol: keyNode.endPosition.column
|
|
10158
|
+
keyEndCol: keyNode.endPosition.column,
|
|
10159
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
10082
10160
|
});
|
|
10083
10161
|
}
|
|
10084
10162
|
}
|
|
@@ -10093,6 +10171,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10093
10171
|
const clientNode = getCapture(match.captures, "client");
|
|
10094
10172
|
const methodNode = getCapture(match.captures, "method");
|
|
10095
10173
|
const argNode = getCapture(match.captures, "arg_id");
|
|
10174
|
+
const callNode = getCapture(match.captures, "call");
|
|
10096
10175
|
if (!clientNode || !methodNode || !argNode) {
|
|
10097
10176
|
continue;
|
|
10098
10177
|
}
|
|
@@ -10122,7 +10201,8 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10122
10201
|
key: resolved,
|
|
10123
10202
|
line,
|
|
10124
10203
|
keyStartCol: argNode.startPosition.column,
|
|
10125
|
-
keyEndCol: argNode.endPosition.column
|
|
10204
|
+
keyEndCol: argNode.endPosition.column,
|
|
10205
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
10126
10206
|
});
|
|
10127
10207
|
}
|
|
10128
10208
|
}
|
|
@@ -10135,6 +10215,7 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10135
10215
|
const clientNode = getCapture(match.captures, "client");
|
|
10136
10216
|
const methodNode = getCapture(match.captures, "method");
|
|
10137
10217
|
const firstArgNode = getCapture(match.captures, "first_arg");
|
|
10218
|
+
const callNode = getCapture(match.captures, "call");
|
|
10138
10219
|
if (!clientNode || !methodNode || !firstArgNode) {
|
|
10139
10220
|
continue;
|
|
10140
10221
|
}
|
|
@@ -10159,13 +10240,167 @@ async function findPostHogCalls(pm, source, languageId) {
|
|
|
10159
10240
|
line,
|
|
10160
10241
|
keyStartCol: firstArgNode.startPosition.column,
|
|
10161
10242
|
keyEndCol: firstArgNode.endPosition.column,
|
|
10162
|
-
dynamic: true
|
|
10243
|
+
dynamic: true,
|
|
10244
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
10163
10245
|
});
|
|
10164
10246
|
matchedLines.add(line);
|
|
10165
10247
|
}
|
|
10166
10248
|
}
|
|
10249
|
+
if (context?.wrappersByLocalName?.size) {
|
|
10250
|
+
synthesizeBareWrapperCalls(
|
|
10251
|
+
pm,
|
|
10252
|
+
lang,
|
|
10253
|
+
tree,
|
|
10254
|
+
languageId,
|
|
10255
|
+
context.wrappersByLocalName,
|
|
10256
|
+
constantMap,
|
|
10257
|
+
calls,
|
|
10258
|
+
matchedLines
|
|
10259
|
+
);
|
|
10260
|
+
}
|
|
10261
|
+
if (context?.namespaceWrappers?.size) {
|
|
10262
|
+
synthesizeNamespaceWrapperCalls(
|
|
10263
|
+
pm,
|
|
10264
|
+
lang,
|
|
10265
|
+
tree,
|
|
10266
|
+
languageId,
|
|
10267
|
+
context.namespaceWrappers,
|
|
10268
|
+
constantMap,
|
|
10269
|
+
calls,
|
|
10270
|
+
matchedLines
|
|
10271
|
+
);
|
|
10272
|
+
}
|
|
10167
10273
|
return calls;
|
|
10168
10274
|
}
|
|
10275
|
+
var WRAPPER_BARE_CALL_QUERIES = {
|
|
10276
|
+
javascript: `(call_expression function: (identifier) @func_name arguments: (arguments) @args) @call`,
|
|
10277
|
+
javascriptreact: `(call_expression function: (identifier) @func_name arguments: (arguments) @args) @call`,
|
|
10278
|
+
typescript: `(call_expression function: (identifier) @func_name arguments: (arguments) @args) @call`,
|
|
10279
|
+
typescriptreact: `(call_expression function: (identifier) @func_name arguments: (arguments) @args) @call`,
|
|
10280
|
+
python: `(call function: (identifier) @func_name arguments: (argument_list) @args) @call`
|
|
10281
|
+
};
|
|
10282
|
+
var WRAPPER_NAMESPACE_CALL_QUERIES = {
|
|
10283
|
+
javascript: `(call_expression function: (member_expression object: (identifier) @ns property: (property_identifier) @method) arguments: (arguments) @args) @call`,
|
|
10284
|
+
javascriptreact: `(call_expression function: (member_expression object: (identifier) @ns property: (property_identifier) @method) arguments: (arguments) @args) @call`,
|
|
10285
|
+
typescript: `(call_expression function: (member_expression object: (identifier) @ns property: (property_identifier) @method) arguments: (arguments) @args) @call`,
|
|
10286
|
+
typescriptreact: `(call_expression function: (member_expression object: (identifier) @ns property: (property_identifier) @method) arguments: (arguments) @args) @call`,
|
|
10287
|
+
python: `(call function: (attribute object: (identifier) @ns attribute: (identifier) @method) arguments: (argument_list) @args) @call`
|
|
10288
|
+
};
|
|
10289
|
+
function synthesizeBareWrapperCalls(pm, lang, tree, languageId, wrappers, constantMap, calls, matchedLines) {
|
|
10290
|
+
const queryStr = WRAPPER_BARE_CALL_QUERIES[languageId];
|
|
10291
|
+
if (!queryStr) return;
|
|
10292
|
+
const query2 = pm.getQuery(lang, queryStr);
|
|
10293
|
+
if (!query2) return;
|
|
10294
|
+
for (const match of query2.matches(tree.rootNode)) {
|
|
10295
|
+
const funcNode = getCapture(match.captures, "func_name");
|
|
10296
|
+
const argsNode = getCapture(match.captures, "args");
|
|
10297
|
+
const callNode = getCapture(match.captures, "call");
|
|
10298
|
+
if (!funcNode || !argsNode) continue;
|
|
10299
|
+
const wrapper = wrappers.get(funcNode.text);
|
|
10300
|
+
if (!wrapper) continue;
|
|
10301
|
+
pushWrapperCall(
|
|
10302
|
+
wrapper,
|
|
10303
|
+
funcNode,
|
|
10304
|
+
argsNode,
|
|
10305
|
+
callNode,
|
|
10306
|
+
constantMap,
|
|
10307
|
+
calls,
|
|
10308
|
+
matchedLines
|
|
10309
|
+
);
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10312
|
+
function synthesizeNamespaceWrapperCalls(pm, lang, tree, languageId, namespaceWrappers, constantMap, calls, matchedLines) {
|
|
10313
|
+
const queryStr = WRAPPER_NAMESPACE_CALL_QUERIES[languageId];
|
|
10314
|
+
if (!queryStr) return;
|
|
10315
|
+
const query2 = pm.getQuery(lang, queryStr);
|
|
10316
|
+
if (!query2) return;
|
|
10317
|
+
for (const match of query2.matches(tree.rootNode)) {
|
|
10318
|
+
const nsNode = getCapture(match.captures, "ns");
|
|
10319
|
+
const methodNode = getCapture(match.captures, "method");
|
|
10320
|
+
const argsNode = getCapture(match.captures, "args");
|
|
10321
|
+
const callNode = getCapture(match.captures, "call");
|
|
10322
|
+
if (!nsNode || !methodNode || !argsNode) continue;
|
|
10323
|
+
const nsWrappers = namespaceWrappers.get(nsNode.text);
|
|
10324
|
+
if (!nsWrappers) continue;
|
|
10325
|
+
const wrapper = nsWrappers.get(methodNode.text);
|
|
10326
|
+
if (!wrapper) continue;
|
|
10327
|
+
pushWrapperCall(
|
|
10328
|
+
wrapper,
|
|
10329
|
+
methodNode,
|
|
10330
|
+
argsNode,
|
|
10331
|
+
callNode,
|
|
10332
|
+
constantMap,
|
|
10333
|
+
calls,
|
|
10334
|
+
matchedLines
|
|
10335
|
+
);
|
|
10336
|
+
}
|
|
10337
|
+
}
|
|
10338
|
+
function pushWrapperCall(wrapper, callerNode, argsNode, callNode, constantMap, calls, matchedLines) {
|
|
10339
|
+
let line = callerNode.startPosition.row;
|
|
10340
|
+
let keyStartCol = callerNode.startPosition.column;
|
|
10341
|
+
let keyEndCol = callerNode.endPosition.column;
|
|
10342
|
+
let key = "";
|
|
10343
|
+
let dynamic = false;
|
|
10344
|
+
if (wrapper.classification.kind === "fixed-key") {
|
|
10345
|
+
key = wrapper.classification.key;
|
|
10346
|
+
} else {
|
|
10347
|
+
const positional = argsNode.namedChildren.filter(
|
|
10348
|
+
(c) => c.type !== "comment" && c.type !== "keyword_argument"
|
|
10349
|
+
);
|
|
10350
|
+
const arg = positional[wrapper.classification.paramIndex];
|
|
10351
|
+
if (!arg) return;
|
|
10352
|
+
line = arg.startPosition.row;
|
|
10353
|
+
keyStartCol = arg.startPosition.column;
|
|
10354
|
+
keyEndCol = arg.endPosition.column;
|
|
10355
|
+
if (arg.type === "string") {
|
|
10356
|
+
const fragment = arg.namedChildren.find(
|
|
10357
|
+
(c) => c.type === "string_fragment" || c.type === "string_content"
|
|
10358
|
+
);
|
|
10359
|
+
if (fragment) {
|
|
10360
|
+
key = fragment.text;
|
|
10361
|
+
} else {
|
|
10362
|
+
dynamic = true;
|
|
10363
|
+
}
|
|
10364
|
+
} else if (arg.type === "template_string") {
|
|
10365
|
+
const fragments = arg.namedChildren.filter(
|
|
10366
|
+
(c) => c.type === "string_fragment"
|
|
10367
|
+
);
|
|
10368
|
+
const hasInterp = arg.namedChildren.some(
|
|
10369
|
+
(c) => c.type === "template_substitution"
|
|
10370
|
+
);
|
|
10371
|
+
if (!hasInterp && fragments.length === 1) {
|
|
10372
|
+
key = fragments[0].text;
|
|
10373
|
+
} else {
|
|
10374
|
+
dynamic = true;
|
|
10375
|
+
}
|
|
10376
|
+
} else if (arg.type === "interpreted_string_literal") {
|
|
10377
|
+
key = arg.text.slice(1, -1);
|
|
10378
|
+
} else if (arg.type === "identifier") {
|
|
10379
|
+
const resolved = constantMap.get(arg.text);
|
|
10380
|
+
if (resolved) {
|
|
10381
|
+
key = resolved;
|
|
10382
|
+
} else {
|
|
10383
|
+
dynamic = true;
|
|
10384
|
+
}
|
|
10385
|
+
} else {
|
|
10386
|
+
dynamic = true;
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
if (matchedLines.has(line) && dynamic) {
|
|
10390
|
+
return;
|
|
10391
|
+
}
|
|
10392
|
+
calls.push({
|
|
10393
|
+
method: wrapper.posthogMethod,
|
|
10394
|
+
key,
|
|
10395
|
+
line,
|
|
10396
|
+
keyStartCol,
|
|
10397
|
+
keyEndCol,
|
|
10398
|
+
dynamic: dynamic ? true : void 0,
|
|
10399
|
+
viaWrapper: wrapper.name,
|
|
10400
|
+
inJsx: callNode ? isInsideJsx(callNode) : void 0
|
|
10401
|
+
});
|
|
10402
|
+
matchedLines.add(line);
|
|
10403
|
+
}
|
|
10169
10404
|
async function findInitCalls(pm, source, languageId) {
|
|
10170
10405
|
const ready = await pm.ensureReady(languageId);
|
|
10171
10406
|
if (!ready) {
|
|
@@ -10578,6 +10813,7 @@ async function findFunctions(pm, source, languageId) {
|
|
|
10578
10813
|
}
|
|
10579
10814
|
const params = singleParamNode ? [singleParamNode.text] : paramsNode ? extractParams(paramsNode.text) : [];
|
|
10580
10815
|
const bodyLine = bodyNode.startPosition.row;
|
|
10816
|
+
const bodyEndLine = bodyNode.endPosition.row;
|
|
10581
10817
|
const nextLineIdx = bodyLine + 1;
|
|
10582
10818
|
const lines = text2.split("\n");
|
|
10583
10819
|
const nextLine = nextLineIdx < lines.length ? lines[nextLineIdx] : "";
|
|
@@ -10587,6 +10823,7 @@ async function findFunctions(pm, source, languageId) {
|
|
|
10587
10823
|
params,
|
|
10588
10824
|
isComponent: /^[A-Z]/.test(name2),
|
|
10589
10825
|
bodyLine,
|
|
10826
|
+
bodyEndLine,
|
|
10590
10827
|
bodyIndent
|
|
10591
10828
|
});
|
|
10592
10829
|
}
|
|
@@ -10644,6 +10881,157 @@ async function findFlagAssignments(pm, source, languageId) {
|
|
|
10644
10881
|
}
|
|
10645
10882
|
return assignments;
|
|
10646
10883
|
}
|
|
10884
|
+
var JS_EXTENSION_PROBES = [
|
|
10885
|
+
".ts",
|
|
10886
|
+
".tsx",
|
|
10887
|
+
".mts",
|
|
10888
|
+
".cts",
|
|
10889
|
+
".js",
|
|
10890
|
+
".jsx",
|
|
10891
|
+
".mjs",
|
|
10892
|
+
".cjs"
|
|
10893
|
+
];
|
|
10894
|
+
var PY_EXTENSION_PROBES = [".py"];
|
|
10895
|
+
function isRelativeSpecifier(spec) {
|
|
10896
|
+
return spec.startsWith("./") || spec.startsWith("../") || spec === ".";
|
|
10897
|
+
}
|
|
10898
|
+
function resolveJsPath(callerAbsPath, specifier) {
|
|
10899
|
+
if (!isRelativeSpecifier(specifier)) return null;
|
|
10900
|
+
const dir = path3.dirname(callerAbsPath);
|
|
10901
|
+
const base = path3.resolve(dir, specifier);
|
|
10902
|
+
if (JS_EXTENSION_PROBES.includes(path3.extname(specifier))) {
|
|
10903
|
+
return isFile(base) ? base : null;
|
|
10904
|
+
}
|
|
10905
|
+
if (isFile(base)) return base;
|
|
10906
|
+
for (const ext of JS_EXTENSION_PROBES) {
|
|
10907
|
+
const candidate = base + ext;
|
|
10908
|
+
if (isFile(candidate)) return candidate;
|
|
10909
|
+
}
|
|
10910
|
+
for (const ext of JS_EXTENSION_PROBES) {
|
|
10911
|
+
const candidate = path3.join(base, `index${ext}`);
|
|
10912
|
+
if (isFile(candidate)) return candidate;
|
|
10913
|
+
}
|
|
10914
|
+
return null;
|
|
10915
|
+
}
|
|
10916
|
+
function isFile(p) {
|
|
10917
|
+
try {
|
|
10918
|
+
return statSync(p).isFile();
|
|
10919
|
+
} catch {
|
|
10920
|
+
return false;
|
|
10921
|
+
}
|
|
10922
|
+
}
|
|
10923
|
+
function resolvePythonModule(callerAbsPath, relativePrefix, moduleName) {
|
|
10924
|
+
if (!relativePrefix) return null;
|
|
10925
|
+
const dots = relativePrefix.length;
|
|
10926
|
+
const levelsUp = dots - 1;
|
|
10927
|
+
let baseDir = path3.dirname(callerAbsPath);
|
|
10928
|
+
for (let i2 = 0; i2 < levelsUp; i2++) {
|
|
10929
|
+
baseDir = path3.dirname(baseDir);
|
|
10930
|
+
}
|
|
10931
|
+
if (!moduleName) {
|
|
10932
|
+
const init2 = path3.join(baseDir, "__init__.py");
|
|
10933
|
+
return isFile(init2) ? init2 : null;
|
|
10934
|
+
}
|
|
10935
|
+
const parts2 = moduleName.split(".");
|
|
10936
|
+
const joined = path3.join(baseDir, ...parts2);
|
|
10937
|
+
for (const ext of PY_EXTENSION_PROBES) {
|
|
10938
|
+
const candidate = joined + ext;
|
|
10939
|
+
if (isFile(candidate)) return candidate;
|
|
10940
|
+
}
|
|
10941
|
+
const pkgInit = path3.join(joined, "__init__.py");
|
|
10942
|
+
if (isFile(pkgInit)) return pkgInit;
|
|
10943
|
+
return null;
|
|
10944
|
+
}
|
|
10945
|
+
async function findImports(pm, source, languageId, callerAbsPath) {
|
|
10946
|
+
const ready = await pm.ensureReady(languageId);
|
|
10947
|
+
if (!ready) return [];
|
|
10948
|
+
const { lang, family } = ready;
|
|
10949
|
+
if (!family.queries.imports) return [];
|
|
10950
|
+
const tree = pm.parse(source, lang);
|
|
10951
|
+
if (!tree) return [];
|
|
10952
|
+
const query2 = pm.getQuery(lang, family.queries.imports);
|
|
10953
|
+
if (!query2) return [];
|
|
10954
|
+
const edges = [];
|
|
10955
|
+
const isPython = languageId === "python";
|
|
10956
|
+
for (const match of query2.matches(tree.rootNode)) {
|
|
10957
|
+
if (isPython) {
|
|
10958
|
+
pushPythonEdge(match.captures, callerAbsPath, edges);
|
|
10959
|
+
} else {
|
|
10960
|
+
pushJsEdge(match.captures, callerAbsPath, edges);
|
|
10961
|
+
}
|
|
10962
|
+
}
|
|
10963
|
+
return dedupe(edges);
|
|
10964
|
+
}
|
|
10965
|
+
function pushJsEdge(captures, callerAbsPath, out2) {
|
|
10966
|
+
const sourceNode = getCapture(captures, "source");
|
|
10967
|
+
if (!sourceNode) return;
|
|
10968
|
+
const specifier = sourceNode.text;
|
|
10969
|
+
if (!isRelativeSpecifier(specifier)) return;
|
|
10970
|
+
const resolvedAbsPath = resolveJsPath(callerAbsPath, specifier);
|
|
10971
|
+
const defaultNode = getCapture(captures, "default_name");
|
|
10972
|
+
if (defaultNode) {
|
|
10973
|
+
out2.push({
|
|
10974
|
+
localName: defaultNode.text,
|
|
10975
|
+
importedName: "default",
|
|
10976
|
+
isDefault: true,
|
|
10977
|
+
resolvedAbsPath
|
|
10978
|
+
});
|
|
10979
|
+
return;
|
|
10980
|
+
}
|
|
10981
|
+
const namespaceNode = getCapture(captures, "namespace_name");
|
|
10982
|
+
if (namespaceNode) {
|
|
10983
|
+
out2.push({
|
|
10984
|
+
localName: namespaceNode.text,
|
|
10985
|
+
importedName: "*",
|
|
10986
|
+
isNamespace: true,
|
|
10987
|
+
resolvedAbsPath
|
|
10988
|
+
});
|
|
10989
|
+
return;
|
|
10990
|
+
}
|
|
10991
|
+
const importedNode = getCapture(captures, "imported_name");
|
|
10992
|
+
if (importedNode) {
|
|
10993
|
+
const localNode = getCapture(captures, "local_name");
|
|
10994
|
+
out2.push({
|
|
10995
|
+
localName: (localNode ?? importedNode).text,
|
|
10996
|
+
importedName: importedNode.text,
|
|
10997
|
+
resolvedAbsPath
|
|
10998
|
+
});
|
|
10999
|
+
}
|
|
11000
|
+
}
|
|
11001
|
+
function pushPythonEdge(captures, callerAbsPath, out2) {
|
|
11002
|
+
const importedNode = getCapture(captures, "imported_name");
|
|
11003
|
+
if (!importedNode) return;
|
|
11004
|
+
const relativePrefix = getCapture(captures, "relative_prefix");
|
|
11005
|
+
const relativeName = getCapture(captures, "relative_name");
|
|
11006
|
+
const sourceNode = getCapture(captures, "source");
|
|
11007
|
+
let resolvedAbsPath = null;
|
|
11008
|
+
if (relativePrefix) {
|
|
11009
|
+
resolvedAbsPath = resolvePythonModule(
|
|
11010
|
+
callerAbsPath,
|
|
11011
|
+
relativePrefix.text,
|
|
11012
|
+
relativeName ? relativeName.text : null
|
|
11013
|
+
);
|
|
11014
|
+
} else if (sourceNode) {
|
|
11015
|
+
resolvedAbsPath = resolvePythonModule(callerAbsPath, ".", sourceNode.text);
|
|
11016
|
+
}
|
|
11017
|
+
const localNode = getCapture(captures, "local_name");
|
|
11018
|
+
out2.push({
|
|
11019
|
+
localName: (localNode ?? importedNode).text,
|
|
11020
|
+
importedName: importedNode.text,
|
|
11021
|
+
resolvedAbsPath
|
|
11022
|
+
});
|
|
11023
|
+
}
|
|
11024
|
+
function dedupe(edges) {
|
|
11025
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11026
|
+
const out2 = [];
|
|
11027
|
+
for (const e of edges) {
|
|
11028
|
+
const key = `${e.localName}|${e.importedName}|${e.resolvedAbsPath ?? ""}|${e.isDefault ? "d" : ""}|${e.isNamespace ? "n" : ""}`;
|
|
11029
|
+
if (seen.has(key)) continue;
|
|
11030
|
+
seen.add(key);
|
|
11031
|
+
out2.push(e);
|
|
11032
|
+
}
|
|
11033
|
+
return out2;
|
|
11034
|
+
}
|
|
10647
11035
|
var noop = {
|
|
10648
11036
|
warn() {
|
|
10649
11037
|
}
|
|
@@ -10659,17 +11047,18 @@ var DEFAULT_CONFIG = {
|
|
|
10659
11047
|
};
|
|
10660
11048
|
function resolveGrammarsDir() {
|
|
10661
11049
|
const thisFile = fileURLToPath(import.meta.url);
|
|
10662
|
-
const dir =
|
|
11050
|
+
const dir = path22.dirname(thisFile);
|
|
10663
11051
|
const candidates = [
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
11052
|
+
path22.join(dir, "..", "grammars"),
|
|
11053
|
+
path22.join(dir, "grammars"),
|
|
11054
|
+
path22.join(dir, "..", "..", "grammars")
|
|
10667
11055
|
];
|
|
10668
11056
|
return candidates.find((p) => existsSync(p)) ?? candidates[0];
|
|
10669
11057
|
}
|
|
10670
11058
|
var ParserManager = class {
|
|
10671
11059
|
parser = null;
|
|
10672
11060
|
languages = /* @__PURE__ */ new Map();
|
|
11061
|
+
languageKeys = /* @__PURE__ */ new WeakMap();
|
|
10673
11062
|
queryCache = /* @__PURE__ */ new Map();
|
|
10674
11063
|
maxCacheSize = 256;
|
|
10675
11064
|
initPromise = null;
|
|
@@ -10688,7 +11077,7 @@ var ParserManager = class {
|
|
|
10688
11077
|
async doInit() {
|
|
10689
11078
|
try {
|
|
10690
11079
|
await import_web_tree_sitter.default.init({
|
|
10691
|
-
locateFile: (scriptName) =>
|
|
11080
|
+
locateFile: (scriptName) => path22.join(this.wasmDir, scriptName)
|
|
10692
11081
|
});
|
|
10693
11082
|
this.parser = new import_web_tree_sitter.default();
|
|
10694
11083
|
} catch (err2) {
|
|
@@ -10715,9 +11104,10 @@ var ParserManager = class {
|
|
|
10715
11104
|
let lang = this.languages.get(family.wasm);
|
|
10716
11105
|
if (!lang) {
|
|
10717
11106
|
try {
|
|
10718
|
-
const wasmPath =
|
|
11107
|
+
const wasmPath = path22.join(this.wasmDir, family.wasm);
|
|
10719
11108
|
lang = await import_web_tree_sitter.default.Language.load(wasmPath);
|
|
10720
11109
|
this.languages.set(family.wasm, lang);
|
|
11110
|
+
this.languageKeys.set(lang, family.wasm);
|
|
10721
11111
|
} catch (err2) {
|
|
10722
11112
|
warn(`Failed to load grammar ${family.wasm}`, err2);
|
|
10723
11113
|
return null;
|
|
@@ -10736,7 +11126,8 @@ var ParserManager = class {
|
|
|
10736
11126
|
if (!queryStr.trim()) {
|
|
10737
11127
|
return null;
|
|
10738
11128
|
}
|
|
10739
|
-
const
|
|
11129
|
+
const langKey = this.languageKeys.get(lang) ?? lang.toString();
|
|
11130
|
+
const cacheKey = `${langKey}:${queryStr}`;
|
|
10740
11131
|
let query2 = this.queryCache.get(cacheKey);
|
|
10741
11132
|
if (query2) {
|
|
10742
11133
|
this.queryCache.delete(cacheKey);
|
|
@@ -10763,6 +11154,7 @@ var ParserManager = class {
|
|
|
10763
11154
|
this.parser = null;
|
|
10764
11155
|
this.initPromise = null;
|
|
10765
11156
|
this.languages.clear();
|
|
11157
|
+
this.languageKeys = /* @__PURE__ */ new WeakMap();
|
|
10766
11158
|
this.queryCache.clear();
|
|
10767
11159
|
}
|
|
10768
11160
|
};
|
|
@@ -11577,6 +11969,260 @@ function isTruthinessCheckForVar(conditionNode, varName) {
|
|
|
11577
11969
|
}
|
|
11578
11970
|
return false;
|
|
11579
11971
|
}
|
|
11972
|
+
var CONTROL_FLOW_KEYWORDS = /* @__PURE__ */ new Set([
|
|
11973
|
+
"if",
|
|
11974
|
+
"for",
|
|
11975
|
+
"while",
|
|
11976
|
+
"switch",
|
|
11977
|
+
"catch",
|
|
11978
|
+
"else"
|
|
11979
|
+
]);
|
|
11980
|
+
function getKeyArgLocator(method, family, languageId) {
|
|
11981
|
+
if (languageId === "python") {
|
|
11982
|
+
if (family.captureMethods.has(method)) {
|
|
11983
|
+
return { positionalIndex: 1, kwargName: "event" };
|
|
11984
|
+
}
|
|
11985
|
+
if (family.flagMethods.has(method)) {
|
|
11986
|
+
return { positionalIndex: 0, kwargName: "key" };
|
|
11987
|
+
}
|
|
11988
|
+
return null;
|
|
11989
|
+
}
|
|
11990
|
+
if (family.allMethods.has(method)) {
|
|
11991
|
+
return { positionalIndex: 0 };
|
|
11992
|
+
}
|
|
11993
|
+
return null;
|
|
11994
|
+
}
|
|
11995
|
+
function extractRawParams(paramsNode, singleParamNode, languageId) {
|
|
11996
|
+
if (singleParamNode) {
|
|
11997
|
+
return [singleParamNode.text];
|
|
11998
|
+
}
|
|
11999
|
+
if (!paramsNode) {
|
|
12000
|
+
return [];
|
|
12001
|
+
}
|
|
12002
|
+
const names = [];
|
|
12003
|
+
for (const child of paramsNode.namedChildren) {
|
|
12004
|
+
const n = extractParamName(child, languageId);
|
|
12005
|
+
if (n) {
|
|
12006
|
+
names.push(n);
|
|
12007
|
+
} else {
|
|
12008
|
+
names.push("");
|
|
12009
|
+
}
|
|
12010
|
+
}
|
|
12011
|
+
return names;
|
|
12012
|
+
}
|
|
12013
|
+
function extractParamName(node, languageId) {
|
|
12014
|
+
switch (node.type) {
|
|
12015
|
+
case "identifier":
|
|
12016
|
+
return node.text;
|
|
12017
|
+
case "required_parameter":
|
|
12018
|
+
case "optional_parameter": {
|
|
12019
|
+
const pat = node.childForFieldName("pattern");
|
|
12020
|
+
if (pat) return extractParamName(pat, languageId);
|
|
12021
|
+
const name2 = node.childForFieldName("name");
|
|
12022
|
+
if (name2) return extractParamName(name2, languageId);
|
|
12023
|
+
const id = node.namedChildren.find((c) => c.type === "identifier");
|
|
12024
|
+
return id?.text ?? null;
|
|
12025
|
+
}
|
|
12026
|
+
case "assignment_pattern": {
|
|
12027
|
+
const left = node.childForFieldName("left");
|
|
12028
|
+
return left ? extractParamName(left, languageId) : null;
|
|
12029
|
+
}
|
|
12030
|
+
case "typed_parameter":
|
|
12031
|
+
case "default_parameter":
|
|
12032
|
+
case "typed_default_parameter": {
|
|
12033
|
+
const name2 = node.childForFieldName("name");
|
|
12034
|
+
if (name2) return extractParamName(name2, languageId);
|
|
12035
|
+
const id = node.namedChildren.find((c) => c.type === "identifier");
|
|
12036
|
+
return id?.text ?? null;
|
|
12037
|
+
}
|
|
12038
|
+
case "parameter": {
|
|
12039
|
+
const id = node.namedChildren.find(
|
|
12040
|
+
(c) => c.type === "identifier" || c.type === "field_identifier"
|
|
12041
|
+
);
|
|
12042
|
+
return id?.text ?? null;
|
|
12043
|
+
}
|
|
12044
|
+
default: {
|
|
12045
|
+
const id = node.namedChildren.find((c) => c.type === "identifier");
|
|
12046
|
+
return id?.text ?? null;
|
|
12047
|
+
}
|
|
12048
|
+
}
|
|
12049
|
+
}
|
|
12050
|
+
function findPostHogCallInBody(body2, allClients, family, languageId, detectNested) {
|
|
12051
|
+
let found = null;
|
|
12052
|
+
const visit = (node) => {
|
|
12053
|
+
if (found) return;
|
|
12054
|
+
const call = matchPostHogCall(
|
|
12055
|
+
node,
|
|
12056
|
+
allClients,
|
|
12057
|
+
family,
|
|
12058
|
+
languageId,
|
|
12059
|
+
detectNested
|
|
12060
|
+
);
|
|
12061
|
+
if (call) {
|
|
12062
|
+
found = call;
|
|
12063
|
+
return;
|
|
12064
|
+
}
|
|
12065
|
+
for (const child of node.namedChildren) {
|
|
12066
|
+
if (found) return;
|
|
12067
|
+
visit(child);
|
|
12068
|
+
}
|
|
12069
|
+
};
|
|
12070
|
+
visit(body2);
|
|
12071
|
+
return found;
|
|
12072
|
+
}
|
|
12073
|
+
function matchPostHogCall(node, allClients, family, languageId, detectNested) {
|
|
12074
|
+
if (node.type !== "call_expression" && node.type !== "call") return null;
|
|
12075
|
+
const funcNode = node.childForFieldName("function");
|
|
12076
|
+
if (!funcNode) return null;
|
|
12077
|
+
let method = null;
|
|
12078
|
+
if (funcNode.type === "member_expression" || funcNode.type === "attribute") {
|
|
12079
|
+
const objNode = funcNode.childForFieldName("object") || funcNode.childForFieldName("operand");
|
|
12080
|
+
const propNode = funcNode.childForFieldName("property") || funcNode.childForFieldName("attribute");
|
|
12081
|
+
if (!objNode || !propNode) return null;
|
|
12082
|
+
const clientName = extractClientName(objNode, detectNested);
|
|
12083
|
+
if (!clientName || !allClients.has(clientName)) return null;
|
|
12084
|
+
method = propNode.text;
|
|
12085
|
+
} else if (funcNode.type === "selector_expression") {
|
|
12086
|
+
const opNode = funcNode.childForFieldName("operand");
|
|
12087
|
+
const fieldNode = funcNode.childForFieldName("field");
|
|
12088
|
+
if (!opNode || !fieldNode) return null;
|
|
12089
|
+
const clientName = extractClientName(opNode, detectNested);
|
|
12090
|
+
if (!clientName || !allClients.has(clientName)) return null;
|
|
12091
|
+
method = fieldNode.text;
|
|
12092
|
+
} else {
|
|
12093
|
+
return null;
|
|
12094
|
+
}
|
|
12095
|
+
if (!method || !family.allMethods.has(method)) return null;
|
|
12096
|
+
const locator = getKeyArgLocator(method, family, languageId);
|
|
12097
|
+
if (!locator) return null;
|
|
12098
|
+
const argsNode = node.childForFieldName("arguments") || node.namedChildren.find(
|
|
12099
|
+
(c) => c.type === "arguments" || c.type === "argument_list"
|
|
12100
|
+
) || null;
|
|
12101
|
+
if (!argsNode) return null;
|
|
12102
|
+
const { keyNode, kwargName } = pickKeyArg(argsNode, locator);
|
|
12103
|
+
return {
|
|
12104
|
+
method,
|
|
12105
|
+
keyArgNode: keyNode,
|
|
12106
|
+
kwargName
|
|
12107
|
+
};
|
|
12108
|
+
}
|
|
12109
|
+
function pickKeyArg(argsNode, locator) {
|
|
12110
|
+
const positional = [];
|
|
12111
|
+
let kwargHit = null;
|
|
12112
|
+
let kwargName = null;
|
|
12113
|
+
for (const child of argsNode.namedChildren) {
|
|
12114
|
+
if (child.type === "keyword_argument") {
|
|
12115
|
+
const nameNode = child.childForFieldName("name");
|
|
12116
|
+
const valueNode = child.childForFieldName("value");
|
|
12117
|
+
if (nameNode && valueNode && locator.kwargName && nameNode.text === locator.kwargName) {
|
|
12118
|
+
kwargHit = valueNode;
|
|
12119
|
+
kwargName = nameNode.text;
|
|
12120
|
+
}
|
|
12121
|
+
continue;
|
|
12122
|
+
}
|
|
12123
|
+
positional.push(child);
|
|
12124
|
+
}
|
|
12125
|
+
if (kwargHit) {
|
|
12126
|
+
return { keyNode: kwargHit, kwargName };
|
|
12127
|
+
}
|
|
12128
|
+
const positionalHit = positional[locator.positionalIndex] ?? null;
|
|
12129
|
+
return { keyNode: positionalHit, kwargName: null };
|
|
12130
|
+
}
|
|
12131
|
+
function classifyKeyArg(keyArgNode, params) {
|
|
12132
|
+
if (!keyArgNode) return null;
|
|
12133
|
+
if (keyArgNode.type === "string" || keyArgNode.type === "interpreted_string_literal") {
|
|
12134
|
+
const key = extractStringFromNode(keyArgNode);
|
|
12135
|
+
return key !== null ? { kind: "fixed-key", key } : null;
|
|
12136
|
+
}
|
|
12137
|
+
if (keyArgNode.type === "template_string") {
|
|
12138
|
+
const hasInterpolation = keyArgNode.namedChildren.some(
|
|
12139
|
+
(c) => c.type === "template_substitution"
|
|
12140
|
+
);
|
|
12141
|
+
if (hasInterpolation) return null;
|
|
12142
|
+
const key = extractStringFromNode(keyArgNode);
|
|
12143
|
+
return key !== null ? { kind: "fixed-key", key } : null;
|
|
12144
|
+
}
|
|
12145
|
+
if (keyArgNode.type === "identifier") {
|
|
12146
|
+
const idx = params.indexOf(keyArgNode.text);
|
|
12147
|
+
if (idx >= 0) return { kind: "pass-through", paramIndex: idx };
|
|
12148
|
+
return null;
|
|
12149
|
+
}
|
|
12150
|
+
return null;
|
|
12151
|
+
}
|
|
12152
|
+
function getExportStatus(nameNode, languageId) {
|
|
12153
|
+
const defNode = nameNode.parent;
|
|
12154
|
+
if (!defNode) return { isDefaultExport: false, isNamedExport: false };
|
|
12155
|
+
if (languageId === "python") {
|
|
12156
|
+
let cur2 = defNode.parent;
|
|
12157
|
+
while (cur2) {
|
|
12158
|
+
if (cur2.type === "module") {
|
|
12159
|
+
return { isDefaultExport: false, isNamedExport: true };
|
|
12160
|
+
}
|
|
12161
|
+
if (cur2.type === "function_definition" || cur2.type === "class_definition") {
|
|
12162
|
+
return { isDefaultExport: false, isNamedExport: false };
|
|
12163
|
+
}
|
|
12164
|
+
cur2 = cur2.parent;
|
|
12165
|
+
}
|
|
12166
|
+
return { isDefaultExport: false, isNamedExport: false };
|
|
12167
|
+
}
|
|
12168
|
+
let cur = defNode.parent;
|
|
12169
|
+
while (cur) {
|
|
12170
|
+
if (cur.type === "export_statement") {
|
|
12171
|
+
const hasDefault = cur.children.some((c) => c.type === "default");
|
|
12172
|
+
return { isDefaultExport: hasDefault, isNamedExport: !hasDefault };
|
|
12173
|
+
}
|
|
12174
|
+
if (cur.type === "program" || cur.type === "module") break;
|
|
12175
|
+
cur = cur.parent;
|
|
12176
|
+
}
|
|
12177
|
+
return { isDefaultExport: false, isNamedExport: false };
|
|
12178
|
+
}
|
|
12179
|
+
async function findWrappers(pm, source, languageId) {
|
|
12180
|
+
const ready = await pm.ensureReady(languageId);
|
|
12181
|
+
if (!ready) return [];
|
|
12182
|
+
const { lang, family } = ready;
|
|
12183
|
+
const tree = pm.parse(source, lang);
|
|
12184
|
+
if (!tree) return [];
|
|
12185
|
+
const functionQuery = pm.getQuery(lang, family.queries.functions);
|
|
12186
|
+
if (!functionQuery) return [];
|
|
12187
|
+
const allClients = getEffectiveClients(pm.config);
|
|
12188
|
+
const { clientAliases } = findAliases(pm, lang, tree, family);
|
|
12189
|
+
for (const a of clientAliases) allClients.add(a);
|
|
12190
|
+
const wrappers = [];
|
|
12191
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12192
|
+
for (const match of functionQuery.matches(tree.rootNode)) {
|
|
12193
|
+
const nameNode = getCapture(match.captures, "func_name");
|
|
12194
|
+
const paramsNode = getCapture(match.captures, "func_params");
|
|
12195
|
+
const singleParamNode = getCapture(match.captures, "func_single_param");
|
|
12196
|
+
const bodyNode = getCapture(match.captures, "func_body");
|
|
12197
|
+
if (!nameNode || !bodyNode) continue;
|
|
12198
|
+
const name2 = nameNode.text;
|
|
12199
|
+
if (CONTROL_FLOW_KEYWORDS.has(name2)) continue;
|
|
12200
|
+
if (seen.has(name2)) continue;
|
|
12201
|
+
const params = extractRawParams(paramsNode, singleParamNode, languageId);
|
|
12202
|
+
const call = findPostHogCallInBody(
|
|
12203
|
+
bodyNode,
|
|
12204
|
+
allClients,
|
|
12205
|
+
family,
|
|
12206
|
+
languageId,
|
|
12207
|
+
pm.config.detectNestedClients
|
|
12208
|
+
);
|
|
12209
|
+
if (!call) continue;
|
|
12210
|
+
const classification = classifyKeyArg(call.keyArgNode, params);
|
|
12211
|
+
if (!classification) continue;
|
|
12212
|
+
const methodKind = family.captureMethods.has(call.method) ? "capture" : "flag";
|
|
12213
|
+
const posthogMethod = call.method === "Enqueue" ? "capture" : call.method;
|
|
12214
|
+
const exportStatus = getExportStatus(nameNode, languageId);
|
|
12215
|
+
seen.add(name2);
|
|
12216
|
+
wrappers.push({
|
|
12217
|
+
name: name2,
|
|
12218
|
+
methodKind,
|
|
12219
|
+
posthogMethod,
|
|
12220
|
+
classification,
|
|
12221
|
+
...exportStatus
|
|
12222
|
+
});
|
|
12223
|
+
}
|
|
12224
|
+
return wrappers;
|
|
12225
|
+
}
|
|
11580
12226
|
var PostHogDetector = class {
|
|
11581
12227
|
pm = new ParserManager();
|
|
11582
12228
|
updateConfig(config) {
|
|
@@ -11588,8 +12234,8 @@ var PostHogDetector = class {
|
|
|
11588
12234
|
get supportedLanguages() {
|
|
11589
12235
|
return this.pm.supportedLanguages;
|
|
11590
12236
|
}
|
|
11591
|
-
async findPostHogCalls(source, languageId) {
|
|
11592
|
-
return findPostHogCalls(this.pm, source, languageId);
|
|
12237
|
+
async findPostHogCalls(source, languageId, context) {
|
|
12238
|
+
return findPostHogCalls(this.pm, source, languageId, context);
|
|
11593
12239
|
}
|
|
11594
12240
|
async findInitCalls(source, languageId) {
|
|
11595
12241
|
return findInitCalls(this.pm, source, languageId);
|
|
@@ -11603,6 +12249,12 @@ var PostHogDetector = class {
|
|
|
11603
12249
|
async findFlagAssignments(source, languageId) {
|
|
11604
12250
|
return findFlagAssignments(this.pm, source, languageId);
|
|
11605
12251
|
}
|
|
12252
|
+
async findWrappers(source, languageId) {
|
|
12253
|
+
return findWrappers(this.pm, source, languageId);
|
|
12254
|
+
}
|
|
12255
|
+
async findImports(source, languageId, callerAbsPath) {
|
|
12256
|
+
return findImports(this.pm, source, languageId, callerAbsPath);
|
|
12257
|
+
}
|
|
11606
12258
|
dispose() {
|
|
11607
12259
|
this.pm.dispose();
|
|
11608
12260
|
}
|
|
@@ -11707,18 +12359,32 @@ function commentPrefix(languageId) {
|
|
|
11707
12359
|
}
|
|
11708
12360
|
function formatFlagComment(flag) {
|
|
11709
12361
|
const parts2 = [`Flag: "${flag.flagKey}"`];
|
|
11710
|
-
if (flag.flag) {
|
|
11711
|
-
parts2.push(
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
12362
|
+
if (!flag.flag) {
|
|
12363
|
+
parts2.push("not in PostHog");
|
|
12364
|
+
return parts2.join(" \u2014 ");
|
|
12365
|
+
}
|
|
12366
|
+
parts2.push(flag.flagType);
|
|
12367
|
+
parts2.push(flag.flag.active ? "active" : "inactive");
|
|
12368
|
+
if (flag.rollout !== null) {
|
|
12369
|
+
parts2.push(`${flag.rollout}% rolled out`);
|
|
12370
|
+
}
|
|
12371
|
+
if (flag.evaluationStats) {
|
|
12372
|
+
const evals = flag.evaluationStats.evaluations.toLocaleString();
|
|
12373
|
+
const users = flag.evaluationStats.uniqueUsers.toLocaleString();
|
|
12374
|
+
const days = flag.evaluationStats.windowDays;
|
|
12375
|
+
parts2.push(`${evals} evals / ${users} users (${days}d)`);
|
|
12376
|
+
} else if (flag.evaluationStatsError) {
|
|
12377
|
+
parts2.push("eval stats unavailable");
|
|
12378
|
+
}
|
|
12379
|
+
if (flag.experiment) {
|
|
12380
|
+
const status = flag.experiment.end_date ? "complete" : "running";
|
|
12381
|
+
parts2.push(`Experiment: "${flag.experiment.name}" (${status})`);
|
|
12382
|
+
}
|
|
12383
|
+
if (flag.staleness) {
|
|
12384
|
+
parts2.push(`STALE (${flag.staleness})`);
|
|
12385
|
+
}
|
|
12386
|
+
if (flag.url) {
|
|
12387
|
+
parts2.push(flag.url);
|
|
11722
12388
|
}
|
|
11723
12389
|
return parts2.join(" \u2014 ");
|
|
11724
12390
|
}
|
|
@@ -11739,21 +12405,25 @@ function formatEventComment(event) {
|
|
|
11739
12405
|
return parts2.join(" \u2014 ");
|
|
11740
12406
|
}
|
|
11741
12407
|
function buildCommentBody(item, enrichedFlags, enrichedEvents) {
|
|
12408
|
+
let body2 = null;
|
|
11742
12409
|
if (item.type === "flag") {
|
|
11743
12410
|
const flag = enrichedFlags.get(item.name);
|
|
11744
|
-
|
|
11745
|
-
|
|
11746
|
-
}
|
|
11747
|
-
if (item.type === "event") {
|
|
12411
|
+
body2 = flag ? formatFlagComment(flag) : null;
|
|
12412
|
+
} else if (item.type === "event") {
|
|
11748
12413
|
const event = enrichedEvents.get(item.name);
|
|
11749
|
-
if (event)
|
|
11750
|
-
|
|
11751
|
-
|
|
12414
|
+
if (event) {
|
|
12415
|
+
body2 = formatEventComment(event);
|
|
12416
|
+
} else if (item.detail) {
|
|
12417
|
+
body2 = `Event: ${item.detail}`;
|
|
12418
|
+
}
|
|
12419
|
+
} else if (item.type === "init") {
|
|
12420
|
+
body2 = `Init: token "${item.name}"`;
|
|
11752
12421
|
}
|
|
11753
|
-
if (
|
|
11754
|
-
|
|
12422
|
+
if (!body2) return null;
|
|
12423
|
+
if (item.viaWrapper) {
|
|
12424
|
+
body2 = `${body2} (via ${item.viaWrapper})`;
|
|
11755
12425
|
}
|
|
11756
|
-
return
|
|
12426
|
+
return body2;
|
|
11757
12427
|
}
|
|
11758
12428
|
function formatComments(source, languageId, items, enrichedFlags, enrichedEvents) {
|
|
11759
12429
|
const prefix = commentPrefix(languageId);
|
|
@@ -11764,7 +12434,7 @@ function formatComments(source, languageId, items, enrichedFlags, enrichedEvents
|
|
|
11764
12434
|
const targetLine = item.line + offset;
|
|
11765
12435
|
const body2 = buildCommentBody(item, enrichedFlags, enrichedEvents);
|
|
11766
12436
|
if (!body2) continue;
|
|
11767
|
-
const comment = `${prefix} [PostHog] ${body2}`;
|
|
12437
|
+
const comment = item.inJsx ? `{/* [PostHog] ${body2} */}` : `${prefix} [PostHog] ${body2}`;
|
|
11768
12438
|
const indent = lines[targetLine]?.match(/^(\s*)/)?.[1] ?? "";
|
|
11769
12439
|
lines.splice(targetLine, 0, `${indent}${comment}`);
|
|
11770
12440
|
offset++;
|
|
@@ -11778,15 +12448,32 @@ function formatInlineComments(source, languageId, items, enrichedFlags, enriched
|
|
|
11778
12448
|
for (const item of items) {
|
|
11779
12449
|
const body2 = buildCommentBody(item, enrichedFlags, enrichedEvents);
|
|
11780
12450
|
if (!body2) continue;
|
|
11781
|
-
const
|
|
11782
|
-
|
|
11783
|
-
byLine.set(item.line,
|
|
12451
|
+
const entry = byLine.get(item.line) ?? { jsxBodies: [], nonJsxBodies: [] };
|
|
12452
|
+
(item.inJsx ? entry.jsxBodies : entry.nonJsxBodies).push(body2);
|
|
12453
|
+
byLine.set(item.line, entry);
|
|
11784
12454
|
}
|
|
11785
|
-
|
|
12455
|
+
const leadingInserts = [];
|
|
12456
|
+
for (const [lineIdx, { jsxBodies, nonJsxBodies }] of byLine) {
|
|
11786
12457
|
if (lineIdx < 0 || lineIdx >= lines.length) continue;
|
|
11787
|
-
|
|
12458
|
+
if (jsxBodies.length > 0 && nonJsxBodies.length > 0) {
|
|
12459
|
+
const joined2 = [...nonJsxBodies, ...jsxBodies].join(" | ");
|
|
12460
|
+
const indent = lines[lineIdx]?.match(/^(\s*)/)?.[1] ?? "";
|
|
12461
|
+
leadingInserts.push({
|
|
12462
|
+
atLine: lineIdx,
|
|
12463
|
+
text: `${indent}{/* [PostHog] ${joined2} */}`
|
|
12464
|
+
});
|
|
12465
|
+
continue;
|
|
12466
|
+
}
|
|
12467
|
+
const isJsx = jsxBodies.length > 0;
|
|
12468
|
+
const bodies = isJsx ? jsxBodies : nonJsxBodies;
|
|
12469
|
+
const joined = bodies.join(" | ");
|
|
12470
|
+
const suffix = isJsx ? ` {/* [PostHog] ${joined} */}` : ` ${prefix} [PostHog] ${joined}`;
|
|
11788
12471
|
lines[lineIdx] = `${lines[lineIdx]}${suffix}`;
|
|
11789
12472
|
}
|
|
12473
|
+
leadingInserts.sort((a, b) => b.atLine - a.atLine);
|
|
12474
|
+
for (const { atLine, text: text2 } of leadingInserts) {
|
|
12475
|
+
lines.splice(atLine, 0, text2);
|
|
12476
|
+
}
|
|
11790
12477
|
return lines.join("\n");
|
|
11791
12478
|
}
|
|
11792
12479
|
var EnrichedResult = class {
|
|
@@ -11809,6 +12496,7 @@ var EnrichedResult = class {
|
|
|
11809
12496
|
let entry = flagMap.get(check.flagKey);
|
|
11810
12497
|
if (!entry) {
|
|
11811
12498
|
const flag = this.context.flags?.get(check.flagKey);
|
|
12499
|
+
const url = this.context.flagUrls?.get(check.flagKey) ?? null;
|
|
11812
12500
|
entry = {
|
|
11813
12501
|
flagKey: check.flagKey,
|
|
11814
12502
|
occurrences: [],
|
|
@@ -11824,7 +12512,10 @@ var EnrichedResult = class {
|
|
|
11824
12512
|
variants: flag ? extractVariants(flag) : [],
|
|
11825
12513
|
experiment: experiments.find(
|
|
11826
12514
|
(e) => e.feature_flag_key === check.flagKey
|
|
11827
|
-
)
|
|
12515
|
+
),
|
|
12516
|
+
url,
|
|
12517
|
+
evaluationStats: this.context.flagEvaluationStats?.get(check.flagKey),
|
|
12518
|
+
evaluationStatsError: this.context.flagEvaluationStatsError ?? false
|
|
11828
12519
|
};
|
|
11829
12520
|
flagMap.set(check.flagKey, entry);
|
|
11830
12521
|
}
|
|
@@ -11882,6 +12573,10 @@ var EnrichedResult = class {
|
|
|
11882
12573
|
enriched.flagType = flag.flagType;
|
|
11883
12574
|
enriched.staleness = flag.staleness;
|
|
11884
12575
|
enriched.rollout = flag.rollout;
|
|
12576
|
+
enriched.active = flag.flag?.active;
|
|
12577
|
+
enriched.url = flag.url;
|
|
12578
|
+
enriched.evaluations = flag.evaluationStats?.evaluations;
|
|
12579
|
+
enriched.evaluationUsers = flag.evaluationStats?.uniqueUsers;
|
|
11885
12580
|
if (flag.experiment) {
|
|
11886
12581
|
enriched.experimentName = flag.experiment.name;
|
|
11887
12582
|
enriched.experimentStatus = flag.experiment.end_date ? "complete" : "running";
|
|
@@ -11948,8 +12643,8 @@ var PostHogApi = class {
|
|
|
11948
12643
|
get signal() {
|
|
11949
12644
|
return AbortSignal.timeout(this.config.timeoutMs ?? 1e4);
|
|
11950
12645
|
}
|
|
11951
|
-
async get(
|
|
11952
|
-
const res = await fetch(`${this.baseUrl}${
|
|
12646
|
+
async get(path42) {
|
|
12647
|
+
const res = await fetch(`${this.baseUrl}${path42}`, {
|
|
11953
12648
|
headers: {
|
|
11954
12649
|
Authorization: `Bearer ${this.config.apiKey}`,
|
|
11955
12650
|
"Content-Type": "application/json"
|
|
@@ -11958,13 +12653,13 @@ var PostHogApi = class {
|
|
|
11958
12653
|
});
|
|
11959
12654
|
if (!res.ok) {
|
|
11960
12655
|
throw new Error(
|
|
11961
|
-
`PostHog API error: ${res.status} ${res.statusText} on GET ${
|
|
12656
|
+
`PostHog API error: ${res.status} ${res.statusText} on GET ${path42}`
|
|
11962
12657
|
);
|
|
11963
12658
|
}
|
|
11964
12659
|
return res.json();
|
|
11965
12660
|
}
|
|
11966
|
-
async post(
|
|
11967
|
-
const res = await fetch(`${this.baseUrl}${
|
|
12661
|
+
async post(path42, body2) {
|
|
12662
|
+
const res = await fetch(`${this.baseUrl}${path42}`, {
|
|
11968
12663
|
method: "POST",
|
|
11969
12664
|
headers: {
|
|
11970
12665
|
Authorization: `Bearer ${this.config.apiKey}`,
|
|
@@ -11975,7 +12670,7 @@ var PostHogApi = class {
|
|
|
11975
12670
|
});
|
|
11976
12671
|
if (!res.ok) {
|
|
11977
12672
|
throw new Error(
|
|
11978
|
-
`PostHog API error: ${res.status} ${res.statusText} on POST ${
|
|
12673
|
+
`PostHog API error: ${res.status} ${res.statusText} on POST ${path42}`
|
|
11979
12674
|
);
|
|
11980
12675
|
}
|
|
11981
12676
|
return res.json();
|
|
@@ -11993,11 +12688,11 @@ var PostHogApi = class {
|
|
|
11993
12688
|
return data.results;
|
|
11994
12689
|
}
|
|
11995
12690
|
async getEventDefinitions(names) {
|
|
11996
|
-
let
|
|
12691
|
+
let path42 = "/event_definitions/?limit=500";
|
|
11997
12692
|
if (names && names.length > 0) {
|
|
11998
|
-
|
|
12693
|
+
path42 += `&search=${encodeURIComponent(names.join(","))}`;
|
|
11999
12694
|
}
|
|
12000
|
-
const data = await this.get(
|
|
12695
|
+
const data = await this.get(path42);
|
|
12001
12696
|
return data.results;
|
|
12002
12697
|
}
|
|
12003
12698
|
async getEventStats(eventNames, daysBack = 30) {
|
|
@@ -12033,6 +12728,35 @@ var PostHogApi = class {
|
|
|
12033
12728
|
}
|
|
12034
12729
|
return stats;
|
|
12035
12730
|
}
|
|
12731
|
+
async getFlagEvaluationStats(flagKeys, daysBack = 7) {
|
|
12732
|
+
if (flagKeys.length === 0) {
|
|
12733
|
+
return /* @__PURE__ */ new Map();
|
|
12734
|
+
}
|
|
12735
|
+
const days = Math.max(1, Math.min(365, Math.floor(daysBack)));
|
|
12736
|
+
const query2 = `
|
|
12737
|
+
SELECT
|
|
12738
|
+
properties.$feature_flag AS flag_key,
|
|
12739
|
+
count() AS evaluations,
|
|
12740
|
+
count(DISTINCT person_id) AS unique_users
|
|
12741
|
+
FROM events
|
|
12742
|
+
WHERE event = '$feature_flag_called'
|
|
12743
|
+
AND properties.$feature_flag IN {flagKeys}
|
|
12744
|
+
AND timestamp >= now() - INTERVAL ${days} DAY
|
|
12745
|
+
GROUP BY flag_key
|
|
12746
|
+
`;
|
|
12747
|
+
const data = await this.post("/query/", {
|
|
12748
|
+
query: {
|
|
12749
|
+
kind: "HogQLQuery",
|
|
12750
|
+
query: query2,
|
|
12751
|
+
values: { flagKeys }
|
|
12752
|
+
}
|
|
12753
|
+
});
|
|
12754
|
+
const stats = /* @__PURE__ */ new Map();
|
|
12755
|
+
for (const [flagKey, evaluations, uniqueUsers] of data.results) {
|
|
12756
|
+
stats.set(flagKey, { evaluations, uniqueUsers, windowDays: days });
|
|
12757
|
+
}
|
|
12758
|
+
return stats;
|
|
12759
|
+
}
|
|
12036
12760
|
};
|
|
12037
12761
|
var CAPTURE_METHODS = /* @__PURE__ */ new Set(["capture", "Enqueue"]);
|
|
12038
12762
|
var ParseResult = class {
|
|
@@ -12056,14 +12780,18 @@ var ParseResult = class {
|
|
|
12056
12780
|
return this.calls.filter((c) => CAPTURE_METHODS.has(c.method)).map((c) => ({
|
|
12057
12781
|
name: c.key,
|
|
12058
12782
|
line: c.line,
|
|
12059
|
-
dynamic: c.dynamic ?? false
|
|
12783
|
+
dynamic: c.dynamic ?? false,
|
|
12784
|
+
viaWrapper: c.viaWrapper,
|
|
12785
|
+
inJsx: c.inJsx
|
|
12060
12786
|
}));
|
|
12061
12787
|
}
|
|
12062
12788
|
get flagChecks() {
|
|
12063
12789
|
return this.calls.filter((c) => !CAPTURE_METHODS.has(c.method)).map((c) => ({
|
|
12064
12790
|
method: c.method,
|
|
12065
12791
|
flagKey: c.key,
|
|
12066
|
-
line: c.line
|
|
12792
|
+
line: c.line,
|
|
12793
|
+
viaWrapper: c.viaWrapper,
|
|
12794
|
+
inJsx: c.inJsx
|
|
12067
12795
|
}));
|
|
12068
12796
|
}
|
|
12069
12797
|
get flagKeys() {
|
|
@@ -12091,7 +12819,9 @@ var ParseResult = class {
|
|
|
12091
12819
|
line: call.line,
|
|
12092
12820
|
name: call.key,
|
|
12093
12821
|
method: call.method,
|
|
12094
|
-
detail: call.dynamic ? "dynamic event name" : void 0
|
|
12822
|
+
detail: call.dynamic ? "dynamic event name" : void 0,
|
|
12823
|
+
viaWrapper: call.viaWrapper,
|
|
12824
|
+
inJsx: call.inJsx
|
|
12095
12825
|
});
|
|
12096
12826
|
}
|
|
12097
12827
|
return items.sort((a, b) => a.line - b.line);
|
|
@@ -12104,14 +12834,22 @@ var ParseResult = class {
|
|
|
12104
12834
|
flagKeys.length > 0 ? api.getFeatureFlags() : Promise.resolve([]),
|
|
12105
12835
|
flagKeys.length > 0 ? api.getExperiments() : Promise.resolve([]),
|
|
12106
12836
|
eventNames.length > 0 ? api.getEventDefinitions(eventNames) : Promise.resolve([]),
|
|
12107
|
-
eventNames.length > 0 ? api.getEventStats(eventNames) : Promise.resolve(/* @__PURE__ */ new Map())
|
|
12837
|
+
eventNames.length > 0 ? api.getEventStats(eventNames) : Promise.resolve(/* @__PURE__ */ new Map()),
|
|
12838
|
+
flagKeys.length > 0 ? api.getFlagEvaluationStats(flagKeys, 7) : Promise.resolve(/* @__PURE__ */ new Map())
|
|
12108
12839
|
]);
|
|
12109
|
-
const [
|
|
12840
|
+
const [
|
|
12841
|
+
flagsResult,
|
|
12842
|
+
experimentsResult,
|
|
12843
|
+
eventDefsResult,
|
|
12844
|
+
eventStatsResult,
|
|
12845
|
+
flagEvalStatsResult
|
|
12846
|
+
] = settled;
|
|
12110
12847
|
const labels = [
|
|
12111
12848
|
"getFeatureFlags",
|
|
12112
12849
|
"getExperiments",
|
|
12113
12850
|
"getEventDefinitions",
|
|
12114
|
-
"getEventStats"
|
|
12851
|
+
"getEventStats",
|
|
12852
|
+
"getFlagEvaluationStats"
|
|
12115
12853
|
];
|
|
12116
12854
|
settled.forEach((r, i2) => {
|
|
12117
12855
|
if (r.status === "rejected") {
|
|
@@ -12122,6 +12860,8 @@ var ParseResult = class {
|
|
|
12122
12860
|
const allExperiments = experimentsResult.status === "fulfilled" ? experimentsResult.value : [];
|
|
12123
12861
|
const allEventDefs = eventDefsResult.status === "fulfilled" ? eventDefsResult.value : [];
|
|
12124
12862
|
const eventStats = eventStatsResult.status === "fulfilled" ? eventStatsResult.value : /* @__PURE__ */ new Map();
|
|
12863
|
+
const flagEvaluationStats = flagEvalStatsResult.status === "fulfilled" ? flagEvalStatsResult.value : /* @__PURE__ */ new Map();
|
|
12864
|
+
const flagEvaluationStatsError = flagEvalStatsResult.status === "rejected";
|
|
12125
12865
|
const flagKeySet = new Set(flagKeys);
|
|
12126
12866
|
const flags2 = new Map(
|
|
12127
12867
|
allFlags.filter((f) => flagKeySet.has(f.key)).map((f) => [f.key, f])
|
|
@@ -12132,18 +12872,34 @@ var ParseResult = class {
|
|
|
12132
12872
|
const eventDefinitions = new Map(
|
|
12133
12873
|
allEventDefs.filter((d) => eventNames.includes(d.name)).map((d) => [d.name, d])
|
|
12134
12874
|
);
|
|
12875
|
+
const host = config.host.replace(/\/$/, "");
|
|
12876
|
+
const flagUrls = /* @__PURE__ */ new Map();
|
|
12877
|
+
for (const [key, flag] of flags2) {
|
|
12878
|
+
flagUrls.set(
|
|
12879
|
+
key,
|
|
12880
|
+
`${host}/project/${config.projectId}/feature_flags/${flag.id}`
|
|
12881
|
+
);
|
|
12882
|
+
}
|
|
12135
12883
|
return new EnrichedResult(this, {
|
|
12136
12884
|
flags: flags2,
|
|
12137
12885
|
experiments,
|
|
12138
12886
|
eventDefinitions,
|
|
12139
|
-
eventStats
|
|
12887
|
+
eventStats,
|
|
12888
|
+
flagEvaluationStats,
|
|
12889
|
+
flagEvaluationStatsError,
|
|
12890
|
+
flagUrls
|
|
12140
12891
|
});
|
|
12141
12892
|
}
|
|
12142
12893
|
};
|
|
12894
|
+
var MAX_WRAPPER_SOURCE_BYTES = 1e6;
|
|
12895
|
+
var WRAPPER_CACHE_MAX = 1024;
|
|
12896
|
+
var POSTHOG_LITERAL_REGEX = /posthog/i;
|
|
12143
12897
|
var PostHogEnricher = class {
|
|
12144
12898
|
detector = new PostHogDetector();
|
|
12899
|
+
wrapperCache = /* @__PURE__ */ new Map();
|
|
12145
12900
|
updateConfig(config) {
|
|
12146
12901
|
this.detector.updateConfig(config);
|
|
12902
|
+
this.wrapperCache.clear();
|
|
12147
12903
|
}
|
|
12148
12904
|
isSupported(langId) {
|
|
12149
12905
|
return this.detector.isSupported(langId);
|
|
@@ -12151,9 +12907,9 @@ var PostHogEnricher = class {
|
|
|
12151
12907
|
get supportedLanguages() {
|
|
12152
12908
|
return this.detector.supportedLanguages;
|
|
12153
12909
|
}
|
|
12154
|
-
async parse(source, languageId) {
|
|
12910
|
+
async parse(source, languageId, context) {
|
|
12155
12911
|
const results = await Promise.allSettled([
|
|
12156
|
-
this.detector.findPostHogCalls(source, languageId),
|
|
12912
|
+
this.detector.findPostHogCalls(source, languageId, context),
|
|
12157
12913
|
this.detector.findInitCalls(source, languageId),
|
|
12158
12914
|
this.detector.findFlagAssignments(source, languageId),
|
|
12159
12915
|
this.detector.findVariantBranches(source, languageId),
|
|
@@ -12184,7 +12940,7 @@ var PostHogEnricher = class {
|
|
|
12184
12940
|
);
|
|
12185
12941
|
}
|
|
12186
12942
|
async parseFile(filePath) {
|
|
12187
|
-
const ext =
|
|
12943
|
+
const ext = path32.extname(filePath).toLowerCase();
|
|
12188
12944
|
const languageId = EXT_TO_LANG_ID[ext];
|
|
12189
12945
|
if (!languageId) {
|
|
12190
12946
|
throw new Error(`Unsupported file extension: ${ext}`);
|
|
@@ -12192,8 +12948,70 @@ var PostHogEnricher = class {
|
|
|
12192
12948
|
const source = await fs4.readFile(filePath, "utf-8");
|
|
12193
12949
|
return this.parse(source, languageId);
|
|
12194
12950
|
}
|
|
12951
|
+
/**
|
|
12952
|
+
* Parse a file for wrapper definitions (functions that directly call PostHog SDK methods).
|
|
12953
|
+
* Results are cached per absolute path + mtime so subsequent calls within the same session
|
|
12954
|
+
* are cheap. Returns [] for unsupported extensions, unreadable files, or files larger than
|
|
12955
|
+
* `MAX_WRAPPER_SOURCE_BYTES`.
|
|
12956
|
+
*/
|
|
12957
|
+
async getWrappersForFile(absPath) {
|
|
12958
|
+
const ext = path32.extname(absPath).toLowerCase();
|
|
12959
|
+
const languageId = EXT_TO_LANG_ID[ext];
|
|
12960
|
+
if (!languageId || !this.isSupported(languageId)) {
|
|
12961
|
+
return this.setWrapperCache(absPath, 0, []);
|
|
12962
|
+
}
|
|
12963
|
+
let mtimeMs = 0;
|
|
12964
|
+
try {
|
|
12965
|
+
const stat2 = await fs4.stat(absPath);
|
|
12966
|
+
mtimeMs = stat2.mtimeMs;
|
|
12967
|
+
if (stat2.size > MAX_WRAPPER_SOURCE_BYTES) {
|
|
12968
|
+
return this.setWrapperCache(absPath, mtimeMs, []);
|
|
12969
|
+
}
|
|
12970
|
+
} catch {
|
|
12971
|
+
return this.setWrapperCache(absPath, 0, []);
|
|
12972
|
+
}
|
|
12973
|
+
const cached = this.wrapperCache.get(absPath);
|
|
12974
|
+
if (cached && cached.mtimeMs === mtimeMs) {
|
|
12975
|
+
this.touchCache(absPath);
|
|
12976
|
+
return cached.wrappers;
|
|
12977
|
+
}
|
|
12978
|
+
let source;
|
|
12979
|
+
try {
|
|
12980
|
+
source = await fs4.readFile(absPath, "utf-8");
|
|
12981
|
+
} catch {
|
|
12982
|
+
return this.setWrapperCache(absPath, mtimeMs, []);
|
|
12983
|
+
}
|
|
12984
|
+
if (!POSTHOG_LITERAL_REGEX.test(source)) {
|
|
12985
|
+
return this.setWrapperCache(absPath, mtimeMs, []);
|
|
12986
|
+
}
|
|
12987
|
+
const wrappers = await this.detector.findWrappers(source, languageId);
|
|
12988
|
+
return this.setWrapperCache(absPath, mtimeMs, wrappers);
|
|
12989
|
+
}
|
|
12990
|
+
async findImportsInSource(source, languageId, callerAbsPath) {
|
|
12991
|
+
return this.detector.findImports(source, languageId, callerAbsPath);
|
|
12992
|
+
}
|
|
12993
|
+
clearWrapperCache() {
|
|
12994
|
+
this.wrapperCache.clear();
|
|
12995
|
+
}
|
|
12195
12996
|
dispose() {
|
|
12196
12997
|
this.detector.dispose();
|
|
12998
|
+
this.wrapperCache.clear();
|
|
12999
|
+
}
|
|
13000
|
+
setWrapperCache(absPath, mtimeMs, wrappers) {
|
|
13001
|
+
if (this.wrapperCache.size >= WRAPPER_CACHE_MAX) {
|
|
13002
|
+
const oldest = this.wrapperCache.keys().next().value;
|
|
13003
|
+
if (oldest !== void 0) {
|
|
13004
|
+
this.wrapperCache.delete(oldest);
|
|
13005
|
+
}
|
|
13006
|
+
}
|
|
13007
|
+
this.wrapperCache.set(absPath, { mtimeMs, wrappers });
|
|
13008
|
+
return wrappers;
|
|
13009
|
+
}
|
|
13010
|
+
touchCache(absPath) {
|
|
13011
|
+
const entry = this.wrapperCache.get(absPath);
|
|
13012
|
+
if (!entry) return;
|
|
13013
|
+
this.wrapperCache.delete(absPath);
|
|
13014
|
+
this.wrapperCache.set(absPath, entry);
|
|
12197
13015
|
}
|
|
12198
13016
|
};
|
|
12199
13017
|
|
|
@@ -12207,14 +13025,25 @@ function createEnrichment(apiConfig, logger) {
|
|
|
12207
13025
|
};
|
|
12208
13026
|
}
|
|
12209
13027
|
var MAX_ENRICHMENT_BYTES = 1e6;
|
|
13028
|
+
var MAX_RELATIVE_IMPORTS = 64;
|
|
13029
|
+
var RELATIVE_IMPORT_REGEX = /(?:^|\n)\s*(?:import\b[^\n]*['"]\.{1,2}\/|from\s+\.)/;
|
|
13030
|
+
var POSTHOG_LITERAL_REGEX2 = /posthog/i;
|
|
12210
13031
|
async function enrichFileForAgent(deps, filePath, content) {
|
|
12211
13032
|
if (!content || content.length > MAX_ENRICHMENT_BYTES) return null;
|
|
12212
|
-
if (!/posthog/i.test(content)) return null;
|
|
12213
13033
|
const ext = path4.extname(filePath).toLowerCase();
|
|
12214
13034
|
const langId = EXT_TO_LANG_ID[ext];
|
|
12215
13035
|
if (!langId || !deps.enricher.isSupported(langId)) return null;
|
|
13036
|
+
const hasPostHogLiteral = POSTHOG_LITERAL_REGEX2.test(content);
|
|
13037
|
+
const hasRelativeImport = RELATIVE_IMPORT_REGEX.test(content);
|
|
13038
|
+
let parseContext;
|
|
13039
|
+
if (hasRelativeImport) {
|
|
13040
|
+
const absPath = path4.resolve(filePath);
|
|
13041
|
+
const ctx = await buildWrapperContext(deps, content, langId, absPath);
|
|
13042
|
+
if (ctx) parseContext = ctx;
|
|
13043
|
+
}
|
|
13044
|
+
if (!hasPostHogLiteral && !parseContext) return null;
|
|
12216
13045
|
try {
|
|
12217
|
-
const parsed = await deps.enricher.parse(content, langId);
|
|
13046
|
+
const parsed = await deps.enricher.parse(content, langId, parseContext);
|
|
12218
13047
|
if (parsed.calls.length === 0 && parsed.initCalls.length === 0) {
|
|
12219
13048
|
return null;
|
|
12220
13049
|
}
|
|
@@ -12236,7 +13065,8 @@ async function enrichFileForAgent(deps, filePath, content) {
|
|
|
12236
13065
|
}
|
|
12237
13066
|
deps.logger?.debug("File enriched", {
|
|
12238
13067
|
filePath,
|
|
12239
|
-
calls: parsed.calls.length
|
|
13068
|
+
calls: parsed.calls.length,
|
|
13069
|
+
viaWrappers: parsed.calls.filter((c) => c.viaWrapper).length
|
|
12240
13070
|
});
|
|
12241
13071
|
return annotated;
|
|
12242
13072
|
} catch (err2) {
|
|
@@ -12245,11 +13075,62 @@ async function enrichFileForAgent(deps, filePath, content) {
|
|
|
12245
13075
|
return null;
|
|
12246
13076
|
}
|
|
12247
13077
|
}
|
|
13078
|
+
async function buildWrapperContext(deps, content, langId, absPath) {
|
|
13079
|
+
let edges;
|
|
13080
|
+
try {
|
|
13081
|
+
edges = await deps.enricher.findImportsInSource(content, langId, absPath);
|
|
13082
|
+
} catch (err2) {
|
|
13083
|
+
deps.logger?.debug("Import resolution failed", {
|
|
13084
|
+
absPath,
|
|
13085
|
+
err: err2 instanceof Error ? err2.message : String(err2)
|
|
13086
|
+
});
|
|
13087
|
+
return null;
|
|
13088
|
+
}
|
|
13089
|
+
if (!edges.length) return null;
|
|
13090
|
+
const bounded = edges.slice(0, MAX_RELATIVE_IMPORTS);
|
|
13091
|
+
const wrappersByLocalName = /* @__PURE__ */ new Map();
|
|
13092
|
+
const namespaceWrappers = /* @__PURE__ */ new Map();
|
|
13093
|
+
const resolutions = await Promise.all(
|
|
13094
|
+
bounded.map(async (edge) => {
|
|
13095
|
+
if (!edge.resolvedAbsPath) return null;
|
|
13096
|
+
const wrappers = await deps.enricher.getWrappersForFile(
|
|
13097
|
+
edge.resolvedAbsPath
|
|
13098
|
+
);
|
|
13099
|
+
if (!wrappers.length) return null;
|
|
13100
|
+
return { edge, wrappers };
|
|
13101
|
+
})
|
|
13102
|
+
);
|
|
13103
|
+
for (const entry of resolutions) {
|
|
13104
|
+
if (!entry) continue;
|
|
13105
|
+
const { edge, wrappers } = entry;
|
|
13106
|
+
if (edge.isNamespace) {
|
|
13107
|
+
const nsMap = /* @__PURE__ */ new Map();
|
|
13108
|
+
for (const w of wrappers) {
|
|
13109
|
+
if (w.isNamedExport || w.isDefaultExport) {
|
|
13110
|
+
nsMap.set(w.name, w);
|
|
13111
|
+
}
|
|
13112
|
+
}
|
|
13113
|
+
if (nsMap.size) namespaceWrappers.set(edge.localName, nsMap);
|
|
13114
|
+
continue;
|
|
13115
|
+
}
|
|
13116
|
+
if (edge.isDefault) {
|
|
13117
|
+
const target2 = wrappers.find((w) => w.isDefaultExport);
|
|
13118
|
+
if (target2) wrappersByLocalName.set(edge.localName, target2);
|
|
13119
|
+
continue;
|
|
13120
|
+
}
|
|
13121
|
+
const target = wrappers.find(
|
|
13122
|
+
(w) => w.name === edge.importedName && w.isNamedExport
|
|
13123
|
+
);
|
|
13124
|
+
if (target) wrappersByLocalName.set(edge.localName, target);
|
|
13125
|
+
}
|
|
13126
|
+
if (!wrappersByLocalName.size && !namespaceWrappers.size) return null;
|
|
13127
|
+
return { wrappersByLocalName, namespaceWrappers };
|
|
13128
|
+
}
|
|
12248
13129
|
|
|
12249
13130
|
// src/utils/common.ts
|
|
12250
13131
|
async function withTimeout(operation, timeoutMs) {
|
|
12251
13132
|
const timeoutPromise = new Promise(
|
|
12252
|
-
(
|
|
13133
|
+
(resolve6) => setTimeout(() => resolve6({ result: "timeout" }), timeoutMs)
|
|
12253
13134
|
);
|
|
12254
13135
|
const operationPromise = operation.then((value) => ({
|
|
12255
13136
|
result: "success",
|
|
@@ -12735,7 +13616,7 @@ function buildToolKey(serverName, toolName) {
|
|
|
12735
13616
|
return `mcp__${serverName}__${toolName}`;
|
|
12736
13617
|
}
|
|
12737
13618
|
function delay2(ms) {
|
|
12738
|
-
return new Promise((
|
|
13619
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
12739
13620
|
}
|
|
12740
13621
|
async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
|
|
12741
13622
|
let retries = 0;
|
|
@@ -15056,8 +15937,8 @@ var AsyncMutex = class {
|
|
|
15056
15937
|
this.locked = true;
|
|
15057
15938
|
return;
|
|
15058
15939
|
}
|
|
15059
|
-
return new Promise((
|
|
15060
|
-
this.queue.push(
|
|
15940
|
+
return new Promise((resolve6) => {
|
|
15941
|
+
this.queue.push(resolve6);
|
|
15061
15942
|
});
|
|
15062
15943
|
}
|
|
15063
15944
|
release() {
|
|
@@ -15592,8 +16473,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
15592
16473
|
if (this.session.promptRunning) {
|
|
15593
16474
|
this.session.input.push(userMessage);
|
|
15594
16475
|
const order = this.session.nextPendingOrder++;
|
|
15595
|
-
const cancelled = await new Promise((
|
|
15596
|
-
this.session.pendingMessages.set(promptUuid, { resolve:
|
|
16476
|
+
const cancelled = await new Promise((resolve6) => {
|
|
16477
|
+
this.session.pendingMessages.set(promptUuid, { resolve: resolve6, order });
|
|
15597
16478
|
});
|
|
15598
16479
|
if (cancelled) {
|
|
15599
16480
|
return { stopReason: "cancelled" };
|
|
@@ -16464,7 +17345,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
16464
17345
|
*/
|
|
16465
17346
|
deferBackgroundFetches(q) {
|
|
16466
17347
|
Promise.all([
|
|
16467
|
-
new Promise((
|
|
17348
|
+
new Promise((resolve6) => setTimeout(resolve6, 10)).then(
|
|
16468
17349
|
() => this.sendAvailableCommandsUpdate()
|
|
16469
17350
|
),
|
|
16470
17351
|
fetchMcpToolMetadata(q, this.logger).then(() => {
|
|
@@ -16746,7 +17627,7 @@ function parseCodexToml(content, cwd) {
|
|
|
16746
17627
|
// src/adapters/codex/spawn.ts
|
|
16747
17628
|
import { spawn as spawn3 } from "child_process";
|
|
16748
17629
|
import { existsSync as existsSync4 } from "fs";
|
|
16749
|
-
import { delimiter, dirname as
|
|
17630
|
+
import { delimiter, dirname as dirname5 } from "path";
|
|
16750
17631
|
function buildConfigArgs(options) {
|
|
16751
17632
|
const args2 = [];
|
|
16752
17633
|
args2.push("-c", `features.remote_models=false`);
|
|
@@ -16797,7 +17678,7 @@ function spawnCodexProcess(options) {
|
|
|
16797
17678
|
}
|
|
16798
17679
|
const { command, args: args2 } = findCodexBinary(options);
|
|
16799
17680
|
if (options.binaryPath && existsSync4(options.binaryPath)) {
|
|
16800
|
-
const binDir =
|
|
17681
|
+
const binDir = dirname5(options.binaryPath);
|
|
16801
17682
|
env.PATH = `${binDir}${delimiter}${env.PATH ?? ""}`;
|
|
16802
17683
|
}
|
|
16803
17684
|
logger.info("Spawning codex-acp process", {
|
|
@@ -17816,7 +18697,7 @@ var Saga = class {
|
|
|
17816
18697
|
|
|
17817
18698
|
// src/sagas/apply-snapshot-saga.ts
|
|
17818
18699
|
import { mkdir as mkdir4, rm as rm3, writeFile as writeFile4 } from "fs/promises";
|
|
17819
|
-
import { join as
|
|
18700
|
+
import { join as join10 } from "path";
|
|
17820
18701
|
|
|
17821
18702
|
// ../git/dist/sagas/tree.js
|
|
17822
18703
|
import { existsSync as existsSync5 } from "fs";
|
|
@@ -18104,7 +18985,7 @@ var ApplySnapshotSaga = class extends Saga {
|
|
|
18104
18985
|
archivePath = null;
|
|
18105
18986
|
async execute(input) {
|
|
18106
18987
|
const { snapshot, repositoryPath, apiClient, taskId, runId } = input;
|
|
18107
|
-
const tmpDir =
|
|
18988
|
+
const tmpDir = join10(repositoryPath, ".posthog", "tmp");
|
|
18108
18989
|
if (!snapshot.archiveUrl) {
|
|
18109
18990
|
throw new Error("Cannot apply snapshot: no archive URL");
|
|
18110
18991
|
}
|
|
@@ -18115,7 +18996,7 @@ var ApplySnapshotSaga = class extends Saga {
|
|
|
18115
18996
|
rollback: async () => {
|
|
18116
18997
|
}
|
|
18117
18998
|
});
|
|
18118
|
-
const archivePath =
|
|
18999
|
+
const archivePath = join10(tmpDir, `${snapshot.treeHash}.tar.gz`);
|
|
18119
19000
|
this.archivePath = archivePath;
|
|
18120
19001
|
await this.step({
|
|
18121
19002
|
name: "download_archive",
|
|
@@ -18164,7 +19045,7 @@ var ApplySnapshotSaga = class extends Saga {
|
|
|
18164
19045
|
// src/sagas/capture-tree-saga.ts
|
|
18165
19046
|
import { existsSync as existsSync6 } from "fs";
|
|
18166
19047
|
import { readFile as readFile4, rm as rm4 } from "fs/promises";
|
|
18167
|
-
import { join as
|
|
19048
|
+
import { join as join11 } from "path";
|
|
18168
19049
|
var CaptureTreeSaga2 = class extends Saga {
|
|
18169
19050
|
sagaName = "CaptureTreeSaga";
|
|
18170
19051
|
async execute(input) {
|
|
@@ -18176,14 +19057,14 @@ var CaptureTreeSaga2 = class extends Saga {
|
|
|
18176
19057
|
taskId,
|
|
18177
19058
|
runId
|
|
18178
19059
|
} = input;
|
|
18179
|
-
const tmpDir =
|
|
18180
|
-
if (existsSync6(
|
|
19060
|
+
const tmpDir = join11(repositoryPath, ".posthog", "tmp");
|
|
19061
|
+
if (existsSync6(join11(repositoryPath, ".gitmodules"))) {
|
|
18181
19062
|
this.log.warn(
|
|
18182
19063
|
"Repository has submodules - snapshot may not capture submodule state"
|
|
18183
19064
|
);
|
|
18184
19065
|
}
|
|
18185
19066
|
const shouldArchive = !!apiClient;
|
|
18186
|
-
const archivePath = shouldArchive ?
|
|
19067
|
+
const archivePath = shouldArchive ? join11(tmpDir, `tree-${Date.now()}.tar.gz`) : void 0;
|
|
18187
19068
|
const gitCaptureSaga = new CaptureTreeSaga(this.log);
|
|
18188
19069
|
const captureResult = await gitCaptureSaga.run({
|
|
18189
19070
|
baseDir: repositoryPath,
|
|
@@ -19425,7 +20306,7 @@ var AgentServer = class _AgentServer {
|
|
|
19425
20306
|
return app;
|
|
19426
20307
|
}
|
|
19427
20308
|
async start() {
|
|
19428
|
-
await new Promise((
|
|
20309
|
+
await new Promise((resolve6) => {
|
|
19429
20310
|
this.server = serve(
|
|
19430
20311
|
{
|
|
19431
20312
|
fetch: this.app.fetch,
|
|
@@ -19435,7 +20316,7 @@ var AgentServer = class _AgentServer {
|
|
|
19435
20316
|
this.logger.debug(
|
|
19436
20317
|
`HTTP server listening on port ${this.config.port}`
|
|
19437
20318
|
);
|
|
19438
|
-
|
|
20319
|
+
resolve6();
|
|
19439
20320
|
}
|
|
19440
20321
|
);
|
|
19441
20322
|
});
|
|
@@ -20174,7 +21055,7 @@ ${toolSummary}`);
|
|
|
20174
21055
|
throw new Error(`Failed to download artifact ${artifact.name}`);
|
|
20175
21056
|
}
|
|
20176
21057
|
const safeName = this.getSafeArtifactName(artifact.name);
|
|
20177
|
-
const artifactDir =
|
|
21058
|
+
const artifactDir = join12(
|
|
20178
21059
|
this.config.repositoryPath ?? "/tmp/workspace",
|
|
20179
21060
|
".posthog",
|
|
20180
21061
|
"attachments",
|
|
@@ -20182,7 +21063,7 @@ ${toolSummary}`);
|
|
|
20182
21063
|
artifact.id ?? safeName
|
|
20183
21064
|
);
|
|
20184
21065
|
await mkdir5(artifactDir, { recursive: true });
|
|
20185
|
-
const artifactPath =
|
|
21066
|
+
const artifactPath = join12(artifactDir, safeName);
|
|
20186
21067
|
await writeFile5(artifactPath, Buffer.from(data));
|
|
20187
21068
|
return resourceLink(pathToFileURL(artifactPath).toString(), artifact.name, {
|
|
20188
21069
|
...artifact.content_type ? { mimeType: artifact.content_type } : {},
|
|
@@ -20794,8 +21675,8 @@ ${attributionInstructions}
|
|
|
20794
21675
|
options: params.options,
|
|
20795
21676
|
toolCall: params.toolCall
|
|
20796
21677
|
});
|
|
20797
|
-
return new Promise((
|
|
20798
|
-
this.pendingPermissions.set(requestId, { resolve:
|
|
21678
|
+
return new Promise((resolve6) => {
|
|
21679
|
+
this.pendingPermissions.set(requestId, { resolve: resolve6 });
|
|
20799
21680
|
});
|
|
20800
21681
|
}
|
|
20801
21682
|
resolvePermission(requestId, optionId, customInput, answers) {
|