@neat.is/core 0.9.21-dev.20260924 → 0.10.0
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/{chunk-NFJ4W5T6.js → chunk-J3VVEB45.js} +200 -50
- package/dist/chunk-J3VVEB45.js.map +1 -0
- package/dist/{chunk-SK2FEJKB.js → chunk-KVJQQUUY.js} +186 -40
- package/dist/chunk-KVJQQUUY.js.map +1 -0
- package/dist/cli.cjs +494 -345
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +470 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +482 -189
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +225 -78
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-NFJ4W5T6.js.map +0 -1
- package/dist/chunk-SK2FEJKB.js.map +0 -1
package/dist/neatd.cjs
CHANGED
|
@@ -789,13 +789,13 @@ __export(neatd_exports, {
|
|
|
789
789
|
module.exports = __toCommonJS(neatd_exports);
|
|
790
790
|
init_cjs_shims();
|
|
791
791
|
var import_node_fs43 = require("fs");
|
|
792
|
-
var
|
|
792
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
793
793
|
var import_node_module2 = require("module");
|
|
794
794
|
|
|
795
795
|
// src/daemon.ts
|
|
796
796
|
init_cjs_shims();
|
|
797
797
|
var import_node_fs41 = require("fs");
|
|
798
|
-
var
|
|
798
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
799
799
|
var import_node_module = require("module");
|
|
800
800
|
|
|
801
801
|
// src/graph.ts
|
|
@@ -8670,7 +8670,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8670
8670
|
});
|
|
8671
8671
|
};
|
|
8672
8672
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
8673
|
-
const
|
|
8673
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8674
8674
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8675
8675
|
let ns = nsCtx;
|
|
8676
8676
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8692,7 +8692,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8692
8692
|
switch (node.type) {
|
|
8693
8693
|
case "function_definition": {
|
|
8694
8694
|
const name = node.childForFieldName("name")?.text;
|
|
8695
|
-
if (name) push("function",
|
|
8695
|
+
if (name) push("function", join2(nsCtx, name), node);
|
|
8696
8696
|
walkBody(node, nsCtx, void 0);
|
|
8697
8697
|
return;
|
|
8698
8698
|
}
|
|
@@ -8700,7 +8700,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8700
8700
|
case "trait_declaration":
|
|
8701
8701
|
case "interface_declaration": {
|
|
8702
8702
|
const name = node.childForFieldName("name")?.text;
|
|
8703
|
-
const full = name ?
|
|
8703
|
+
const full = name ? join2(nsCtx, name) : classCtx;
|
|
8704
8704
|
if (name) push("class", full, node);
|
|
8705
8705
|
walkBody(node, nsCtx, full);
|
|
8706
8706
|
return;
|
|
@@ -8709,7 +8709,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8709
8709
|
const name = node.childForFieldName("name")?.text;
|
|
8710
8710
|
if (name) {
|
|
8711
8711
|
const kind = name === "__construct" ? "constructor" : "method";
|
|
8712
|
-
push(kind,
|
|
8712
|
+
push(kind, join2(classCtx ?? nsCtx, name), node);
|
|
8713
8713
|
}
|
|
8714
8714
|
return;
|
|
8715
8715
|
}
|
|
@@ -8735,7 +8735,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8735
8735
|
endLine: node.endPosition.row + 1
|
|
8736
8736
|
});
|
|
8737
8737
|
};
|
|
8738
|
-
const
|
|
8738
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8739
8739
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8740
8740
|
let ns = nsCtx;
|
|
8741
8741
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8743,7 +8743,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8743
8743
|
if (!child) continue;
|
|
8744
8744
|
if (child.type === "file_scoped_namespace_declaration") {
|
|
8745
8745
|
const nameNode = child.childForFieldName("name");
|
|
8746
|
-
if (nameNode) ns =
|
|
8746
|
+
if (nameNode) ns = join2(nsCtx, nameNode.text);
|
|
8747
8747
|
continue;
|
|
8748
8748
|
}
|
|
8749
8749
|
visit(child, ns, classCtx);
|
|
@@ -8757,7 +8757,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8757
8757
|
switch (node.type) {
|
|
8758
8758
|
case "namespace_declaration": {
|
|
8759
8759
|
const nameNode = node.childForFieldName("name");
|
|
8760
|
-
const ns = nameNode ?
|
|
8760
|
+
const ns = nameNode ? join2(nsCtx, nameNode.text) : nsCtx;
|
|
8761
8761
|
walkBody(node, ns, classCtx);
|
|
8762
8762
|
return;
|
|
8763
8763
|
}
|
|
@@ -8766,19 +8766,19 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8766
8766
|
case "struct_declaration":
|
|
8767
8767
|
case "record_declaration": {
|
|
8768
8768
|
const name = node.childForFieldName("name")?.text;
|
|
8769
|
-
const full = name ?
|
|
8769
|
+
const full = name ? join2(classCtx ?? nsCtx, name) : classCtx;
|
|
8770
8770
|
if (name) push("class", full, node);
|
|
8771
8771
|
walkBody(node, nsCtx, full);
|
|
8772
8772
|
return;
|
|
8773
8773
|
}
|
|
8774
8774
|
case "method_declaration": {
|
|
8775
8775
|
const name = node.childForFieldName("name")?.text;
|
|
8776
|
-
if (name) push("method",
|
|
8776
|
+
if (name) push("method", join2(classCtx ?? nsCtx, name), node);
|
|
8777
8777
|
return;
|
|
8778
8778
|
}
|
|
8779
8779
|
case "constructor_declaration": {
|
|
8780
8780
|
const name = node.childForFieldName("name")?.text;
|
|
8781
|
-
if (name) push("constructor",
|
|
8781
|
+
if (name) push("constructor", join2(classCtx ?? nsCtx, name), node);
|
|
8782
8782
|
return;
|
|
8783
8783
|
}
|
|
8784
8784
|
}
|
|
@@ -8797,7 +8797,7 @@ function collectJavaSymbolDefs(root) {
|
|
|
8797
8797
|
endLine: node.endPosition.row + 1
|
|
8798
8798
|
});
|
|
8799
8799
|
};
|
|
8800
|
-
const
|
|
8800
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8801
8801
|
let pkg;
|
|
8802
8802
|
for (let i = 0; i < root.namedChildCount; i++) {
|
|
8803
8803
|
const child = root.namedChild(i);
|
|
@@ -8823,19 +8823,19 @@ function collectJavaSymbolDefs(root) {
|
|
|
8823
8823
|
case "enum_declaration":
|
|
8824
8824
|
case "record_declaration": {
|
|
8825
8825
|
const name = node.childForFieldName("name")?.text;
|
|
8826
|
-
const full = name ?
|
|
8826
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
8827
8827
|
if (name) push("class", full, node);
|
|
8828
8828
|
walkBody(node, full);
|
|
8829
8829
|
return;
|
|
8830
8830
|
}
|
|
8831
8831
|
case "method_declaration": {
|
|
8832
8832
|
const name = node.childForFieldName("name")?.text;
|
|
8833
|
-
if (name) push("method",
|
|
8833
|
+
if (name) push("method", join2(classCtx ?? pkg, name), node);
|
|
8834
8834
|
return;
|
|
8835
8835
|
}
|
|
8836
8836
|
case "constructor_declaration": {
|
|
8837
8837
|
const name = node.childForFieldName("name")?.text;
|
|
8838
|
-
if (name) push("constructor",
|
|
8838
|
+
if (name) push("constructor", join2(classCtx ?? pkg, name), node);
|
|
8839
8839
|
return;
|
|
8840
8840
|
}
|
|
8841
8841
|
}
|
|
@@ -8854,7 +8854,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8854
8854
|
endLine: node.endPosition.row + 1
|
|
8855
8855
|
});
|
|
8856
8856
|
};
|
|
8857
|
-
const
|
|
8857
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8858
8858
|
const firstChildOfType2 = (node, types) => {
|
|
8859
8859
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8860
8860
|
const child = node.namedChild(i);
|
|
@@ -8883,7 +8883,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8883
8883
|
case "class_declaration":
|
|
8884
8884
|
case "object_declaration": {
|
|
8885
8885
|
const name = nameOf(node, "type_identifier");
|
|
8886
|
-
const full = name ?
|
|
8886
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
8887
8887
|
if (name) push("class", full, node);
|
|
8888
8888
|
const body = bodyOf(node);
|
|
8889
8889
|
if (body) walkChildren(body, full);
|
|
@@ -8891,20 +8891,20 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8891
8891
|
}
|
|
8892
8892
|
case "companion_object": {
|
|
8893
8893
|
const name = nameOf(node, "type_identifier");
|
|
8894
|
-
const full = name ?
|
|
8894
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx ?? pkg;
|
|
8895
8895
|
const body = bodyOf(node);
|
|
8896
8896
|
if (body) walkChildren(body, full);
|
|
8897
8897
|
return;
|
|
8898
8898
|
}
|
|
8899
8899
|
case "function_declaration": {
|
|
8900
8900
|
const name = nameOf(node, "simple_identifier");
|
|
8901
|
-
if (name) push(classCtx ? "method" : "function",
|
|
8901
|
+
if (name) push(classCtx ? "method" : "function", join2(classCtx ?? pkg, name), node);
|
|
8902
8902
|
return;
|
|
8903
8903
|
}
|
|
8904
8904
|
case "secondary_constructor": {
|
|
8905
8905
|
if (classCtx) {
|
|
8906
8906
|
const typeName = classCtx.slice(classCtx.lastIndexOf(".") + 1);
|
|
8907
|
-
push("constructor",
|
|
8907
|
+
push("constructor", join2(classCtx, typeName), node);
|
|
8908
8908
|
}
|
|
8909
8909
|
return;
|
|
8910
8910
|
}
|
|
@@ -8924,14 +8924,14 @@ function collectRustSymbolDefs(root) {
|
|
|
8924
8924
|
endLine: node.endPosition.row + 1
|
|
8925
8925
|
});
|
|
8926
8926
|
};
|
|
8927
|
-
const
|
|
8927
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
8928
8928
|
const walkTypeBody = (body, typeCtx) => {
|
|
8929
8929
|
for (let i = 0; i < body.namedChildCount; i++) {
|
|
8930
8930
|
const child = body.namedChild(i);
|
|
8931
8931
|
if (!child) continue;
|
|
8932
8932
|
if (child.type === "function_item" || child.type === "function_signature_item") {
|
|
8933
8933
|
const name = child.childForFieldName("name")?.text;
|
|
8934
|
-
if (name) push("method",
|
|
8934
|
+
if (name) push("method", join2(typeCtx, name), child);
|
|
8935
8935
|
}
|
|
8936
8936
|
}
|
|
8937
8937
|
};
|
|
@@ -8945,7 +8945,7 @@ function collectRustSymbolDefs(root) {
|
|
|
8945
8945
|
switch (node.type) {
|
|
8946
8946
|
case "mod_item": {
|
|
8947
8947
|
const name = node.childForFieldName("name")?.text;
|
|
8948
|
-
const full = name ?
|
|
8948
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
8949
8949
|
const body = node.childForFieldName("body");
|
|
8950
8950
|
if (body) walkChildren(body, full);
|
|
8951
8951
|
return;
|
|
@@ -8953,12 +8953,12 @@ function collectRustSymbolDefs(root) {
|
|
|
8953
8953
|
case "struct_item":
|
|
8954
8954
|
case "enum_item": {
|
|
8955
8955
|
const name = node.childForFieldName("name")?.text;
|
|
8956
|
-
if (name) push("class",
|
|
8956
|
+
if (name) push("class", join2(modCtx, name), node);
|
|
8957
8957
|
return;
|
|
8958
8958
|
}
|
|
8959
8959
|
case "trait_item": {
|
|
8960
8960
|
const name = node.childForFieldName("name")?.text;
|
|
8961
|
-
const full = name ?
|
|
8961
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
8962
8962
|
if (name) push("class", full, node);
|
|
8963
8963
|
const body = node.childForFieldName("body");
|
|
8964
8964
|
if (body && full) walkTypeBody(body, full);
|
|
@@ -8966,14 +8966,14 @@ function collectRustSymbolDefs(root) {
|
|
|
8966
8966
|
}
|
|
8967
8967
|
case "impl_item": {
|
|
8968
8968
|
const typeName = node.childForFieldName("type")?.text;
|
|
8969
|
-
const full = typeName ?
|
|
8969
|
+
const full = typeName ? join2(modCtx, typeName) : modCtx;
|
|
8970
8970
|
const body = node.childForFieldName("body");
|
|
8971
8971
|
if (body && full) walkTypeBody(body, full);
|
|
8972
8972
|
return;
|
|
8973
8973
|
}
|
|
8974
8974
|
case "function_item": {
|
|
8975
8975
|
const name = node.childForFieldName("name")?.text;
|
|
8976
|
-
if (name) push("function",
|
|
8976
|
+
if (name) push("function", join2(modCtx, name), node);
|
|
8977
8977
|
return;
|
|
8978
8978
|
}
|
|
8979
8979
|
}
|
|
@@ -8992,7 +8992,7 @@ function collectCppSymbolDefs(root) {
|
|
|
8992
8992
|
endLine: node.endPosition.row + 1
|
|
8993
8993
|
});
|
|
8994
8994
|
};
|
|
8995
|
-
const
|
|
8995
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
8996
8996
|
const DECLARATOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
8997
8997
|
"function_declarator",
|
|
8998
8998
|
"pointer_declarator",
|
|
@@ -9018,7 +9018,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9018
9018
|
return void 0;
|
|
9019
9019
|
};
|
|
9020
9020
|
const classify = (nameText, prefix, enclosingClass) => {
|
|
9021
|
-
const qualname =
|
|
9021
|
+
const qualname = join2(prefix, nameText);
|
|
9022
9022
|
let className;
|
|
9023
9023
|
let memberName;
|
|
9024
9024
|
const idx = nameText.lastIndexOf("::");
|
|
@@ -9047,7 +9047,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9047
9047
|
switch (node.type) {
|
|
9048
9048
|
case "namespace_definition": {
|
|
9049
9049
|
const name = node.childForFieldName("name")?.text;
|
|
9050
|
-
const newPrefix = name ?
|
|
9050
|
+
const newPrefix = name ? join2(prefix, name) : prefix;
|
|
9051
9051
|
const body = node.childForFieldName("body");
|
|
9052
9052
|
if (body) walkChildren(body, newPrefix, void 0);
|
|
9053
9053
|
return;
|
|
@@ -9055,7 +9055,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9055
9055
|
case "class_specifier":
|
|
9056
9056
|
case "struct_specifier": {
|
|
9057
9057
|
const name = node.childForFieldName("name")?.text;
|
|
9058
|
-
const full = name ?
|
|
9058
|
+
const full = name ? join2(prefix, name) : prefix;
|
|
9059
9059
|
if (name) push("class", full, node);
|
|
9060
9060
|
const body = node.childForFieldName("body");
|
|
9061
9061
|
if (body && name) walkChildren(body, full, name);
|
|
@@ -16483,7 +16483,7 @@ var Projects = class {
|
|
|
16483
16483
|
init_cjs_shims();
|
|
16484
16484
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
16485
16485
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
16486
|
-
var
|
|
16486
|
+
var import_types101 = require("@neat.is/types");
|
|
16487
16487
|
|
|
16488
16488
|
// src/extend/index.ts
|
|
16489
16489
|
init_cjs_shims();
|
|
@@ -17713,7 +17713,7 @@ var INTENT_RULES = [
|
|
|
17713
17713
|
},
|
|
17714
17714
|
{
|
|
17715
17715
|
intent: "blast-radius",
|
|
17716
|
-
test: /\b(blast|break[\s-]?if|breaks[\s-]?if|impact|downstream|dependents?|redeploy|who\s+(?:uses|calls|depends)|what\s+depends\s+on|affect(?:s|ed)?)\b/
|
|
17716
|
+
test: /\b(blast|break[\s-]?if|breaks[\s-]?if|impact|downstream|dependents?|redeploy|who\s+(?:uses|calls|depends(?:\s+on)?)|what\s+depends\s+on|consumers?\s+of|callers?\s+of|affect(?:s|ed)?)\b/
|
|
17717
17717
|
},
|
|
17718
17718
|
{
|
|
17719
17719
|
intent: "divergence",
|
|
@@ -17725,11 +17725,11 @@ var INTENT_RULES = [
|
|
|
17725
17725
|
},
|
|
17726
17726
|
{
|
|
17727
17727
|
intent: "observed",
|
|
17728
|
-
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually
|
|
17728
|
+
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually|really\s+call\w*|observed|runtime\s+traffic|slow|latency|p95|timing)\b/
|
|
17729
17729
|
},
|
|
17730
17730
|
{
|
|
17731
17731
|
intent: "dependencies",
|
|
17732
|
-
test: /\b(depend\w*|calls?|uses?|imports?|relies\s+on|needs
|
|
17732
|
+
test: /\b(depend\w*|calls?|uses?|imports?|relies\s+on|needs?|talks?\s+to|connects?\s+to|hits?|reads?\s+from|writes?\s+to)\b/
|
|
17733
17733
|
}
|
|
17734
17734
|
];
|
|
17735
17735
|
function classifyIntent(question) {
|
|
@@ -17896,7 +17896,25 @@ var INTENT_WORDS = /* @__PURE__ */ new Set([
|
|
|
17896
17896
|
"rely",
|
|
17897
17897
|
"needs",
|
|
17898
17898
|
"need",
|
|
17899
|
-
"sync"
|
|
17899
|
+
"sync",
|
|
17900
|
+
"talk",
|
|
17901
|
+
"talks",
|
|
17902
|
+
"connect",
|
|
17903
|
+
"connects",
|
|
17904
|
+
"hit",
|
|
17905
|
+
"hits",
|
|
17906
|
+
"read",
|
|
17907
|
+
"reads",
|
|
17908
|
+
"write",
|
|
17909
|
+
"writes",
|
|
17910
|
+
"consumer",
|
|
17911
|
+
"consumers",
|
|
17912
|
+
"caller",
|
|
17913
|
+
"callers",
|
|
17914
|
+
"slow",
|
|
17915
|
+
"latency",
|
|
17916
|
+
"p95",
|
|
17917
|
+
"timing"
|
|
17900
17918
|
]);
|
|
17901
17919
|
function tokens(input) {
|
|
17902
17920
|
const spaced = input.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
@@ -17920,6 +17938,13 @@ function idBody(id) {
|
|
|
17920
17938
|
const colon = id.indexOf(":");
|
|
17921
17939
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
17922
17940
|
}
|
|
17941
|
+
var TYPE_NOUNS = [
|
|
17942
|
+
{ nouns: ["database", "db", "table"], type: import_types62.NodeType.DatabaseNode },
|
|
17943
|
+
{ nouns: ["service", "api", "backend"], type: import_types62.NodeType.ServiceNode },
|
|
17944
|
+
{ nouns: ["route", "endpoint"], type: import_types62.NodeType.RouteNode },
|
|
17945
|
+
{ nouns: ["file"], type: import_types62.NodeType.FileNode },
|
|
17946
|
+
{ nouns: ["config"], type: import_types62.NodeType.ConfigNode }
|
|
17947
|
+
];
|
|
17923
17948
|
var EMBED_MIN_SCORE = 0.35;
|
|
17924
17949
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
17925
17950
|
const qTokens = queryTokens(question);
|
|
@@ -17927,6 +17952,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17927
17952
|
const best = /* @__PURE__ */ new Map();
|
|
17928
17953
|
const consider = (cand) => {
|
|
17929
17954
|
const cur = best.get(cand.nodeId);
|
|
17955
|
+
if (cur?.via === "id" && cand.via === "embedding") return;
|
|
17930
17956
|
if (!cur || cand.score > cur.score) best.set(cand.nodeId, cand);
|
|
17931
17957
|
};
|
|
17932
17958
|
graph.forEachNode((id, attrs) => {
|
|
@@ -17936,12 +17962,12 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17936
17962
|
const body = idBody(id);
|
|
17937
17963
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
17938
17964
|
if (labelTokens.size === 0) return;
|
|
17939
|
-
let
|
|
17940
|
-
for (const t of qTokens) if (labelTokens.has(t))
|
|
17965
|
+
let matched2 = 0;
|
|
17966
|
+
for (const t of qTokens) if (labelTokens.has(t)) matched2 += 1;
|
|
17941
17967
|
const named2 = body.length >= 2 && normalized.includes(body.toLowerCase()) || name.length >= 2 && normalized.includes(name.toLowerCase());
|
|
17942
|
-
if (
|
|
17943
|
-
const coverage = qTokens.length > 0 ?
|
|
17944
|
-
const via = named2 ? "id" :
|
|
17968
|
+
if (matched2 === 0 && !named2) return;
|
|
17969
|
+
const coverage = qTokens.length > 0 ? matched2 / qTokens.length : 0;
|
|
17970
|
+
const via = named2 ? "id" : matched2 > 0 && tokens(name).some((t) => qTokens.includes(t)) ? "label" : "token";
|
|
17945
17971
|
const score = named2 ? Math.max(0.9, coverage) : Math.min(0.85, 0.3 + 0.7 * coverage);
|
|
17946
17972
|
consider({ nodeId: id, label: name, via, score: Math.min(1, score) });
|
|
17947
17973
|
});
|
|
@@ -17951,6 +17977,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17951
17977
|
if (res.provider !== "substring") {
|
|
17952
17978
|
for (const m of res.matches) {
|
|
17953
17979
|
if (m.node.type === import_types62.NodeType.FrontierNode) continue;
|
|
17980
|
+
if (!graph.hasNode(m.node.id)) continue;
|
|
17954
17981
|
const already = best.get(m.node.id);
|
|
17955
17982
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
17956
17983
|
consider({
|
|
@@ -17964,10 +17991,31 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17964
17991
|
} catch {
|
|
17965
17992
|
}
|
|
17966
17993
|
}
|
|
17967
|
-
|
|
17968
|
-
|
|
17969
|
-
|
|
17994
|
+
if (best.size === 0) {
|
|
17995
|
+
const words = new Set(tokens(question));
|
|
17996
|
+
const kind = TYPE_NOUNS.find((entry2) => entry2.nouns.some((noun) => words.has(noun)));
|
|
17997
|
+
if (kind) {
|
|
17998
|
+
const ids = graph.filterNodes((_id, attrs) => attrs.type === kind.type).sort();
|
|
17999
|
+
if (ids.length > 1) {
|
|
18000
|
+
return { matched: [], ambiguousType: { noun: kind.nouns.find((noun) => words.has(noun)), ids } };
|
|
18001
|
+
}
|
|
18002
|
+
if (ids.length === 1) {
|
|
18003
|
+
const id = ids[0];
|
|
18004
|
+
return { matched: [{ nodeId: id, label: nodeName(graph.getNodeAttributes(id)), via: "type", score: 0.6 }].slice(0, maxNodes) };
|
|
18005
|
+
}
|
|
18006
|
+
return { matched: [] };
|
|
18007
|
+
}
|
|
18008
|
+
}
|
|
18009
|
+
const viaRank = { id: 4, label: 3, token: 2, type: 1, embedding: 0 };
|
|
18010
|
+
const ranked = [...best.values()].sort(
|
|
18011
|
+
(a, b) => Number(b.via === "id") - Number(a.via === "id") || b.score - a.score || viaRank[b.via] - viaRank[a.via] || a.nodeId.localeCompare(b.nodeId)
|
|
18012
|
+
);
|
|
18013
|
+
const primary = ranked[0];
|
|
18014
|
+
const primaryType = primary && graph.getNodeAttributes(primary.nodeId).type;
|
|
18015
|
+
const matched = ranked.filter(
|
|
18016
|
+
(candidate) => !primary || primary.via !== "id" || primary.score < 0.85 || candidate === primary || graph.getNodeAttributes(candidate.nodeId).type === primaryType || candidate.via !== "embedding" && candidate.score >= primary.score - 0.2
|
|
17970
18017
|
).slice(0, maxNodes).map((s) => ({ nodeId: s.nodeId, label: s.label, via: s.via, score: Number(s.score.toFixed(3)) }));
|
|
18018
|
+
return { matched };
|
|
17971
18019
|
}
|
|
17972
18020
|
function incidentsForNode(nodeId, incidents) {
|
|
17973
18021
|
if (!incidents || incidents.length === 0) return [];
|
|
@@ -18059,6 +18107,23 @@ function buildBlastSection(graph, node) {
|
|
|
18059
18107
|
facts
|
|
18060
18108
|
};
|
|
18061
18109
|
}
|
|
18110
|
+
function buildDatabaseCallersSection(graph, node) {
|
|
18111
|
+
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18112
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types62.NodeType.ServiceNode) return false;
|
|
18113
|
+
return item.path.slice(1, -1).every((id) => {
|
|
18114
|
+
const type = graph.getNodeAttributes(id).type;
|
|
18115
|
+
return type === import_types62.NodeType.FileNode || type === import_types62.NodeType.SymbolNode;
|
|
18116
|
+
});
|
|
18117
|
+
});
|
|
18118
|
+
return {
|
|
18119
|
+
heading: `Services calling ${node} \u2014 ${callers.length}`,
|
|
18120
|
+
facts: callers.length > 0 ? callers.slice(0, MAX_FACTS_PER_SECTION).map((item) => ({
|
|
18121
|
+
text: `${item.nodeId} (distance ${item.distance})`,
|
|
18122
|
+
provenance: item.edgeProvenance,
|
|
18123
|
+
confidence: item.confidence
|
|
18124
|
+
})) : [{ text: `No inbound service callers found for ${node}.` }]
|
|
18125
|
+
};
|
|
18126
|
+
}
|
|
18062
18127
|
function buildIncidentsSection(node, incidents) {
|
|
18063
18128
|
const relevant = incidentsForNode(node, incidents);
|
|
18064
18129
|
if (relevant.length === 0) return null;
|
|
@@ -18085,6 +18150,29 @@ function divergenceLine(d) {
|
|
|
18085
18150
|
}
|
|
18086
18151
|
return `[${d.type}] ${d.source} \u2192 ${d.target} \u2014 ${d.reason}`;
|
|
18087
18152
|
}
|
|
18153
|
+
function runtimeEdgeState(graph) {
|
|
18154
|
+
let observed = false;
|
|
18155
|
+
let stale = false;
|
|
18156
|
+
graph.forEachEdge((_id, attrs) => {
|
|
18157
|
+
if (attrs.provenance === import_types62.Provenance.OBSERVED) observed = true;
|
|
18158
|
+
if (attrs.provenance === import_types62.Provenance.STALE) stale = true;
|
|
18159
|
+
});
|
|
18160
|
+
return { observed, stale };
|
|
18161
|
+
}
|
|
18162
|
+
function pendingRuntimeMessage(graph, divergences) {
|
|
18163
|
+
const count = divergences.filter((d) => d.type === "missing-observed").length;
|
|
18164
|
+
if (count === 0) return void 0;
|
|
18165
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18166
|
+
if (observed) return void 0;
|
|
18167
|
+
const prefix = stale ? "No current runtime observations \u2014 earlier runtime evidence is stale" : "No runtime observed yet";
|
|
18168
|
+
return `${prefix} \u2014 ${count} declared dependenc${count === 1 ? "y is" : "ies are"} waiting to be confirmed. Send traces (or connect a provider) and ask again.`;
|
|
18169
|
+
}
|
|
18170
|
+
function noDivergenceMessage(graph) {
|
|
18171
|
+
if (graph.order === 0) return "Graph is empty \u2014 no declared or observed dependencies to compare.";
|
|
18172
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18173
|
+
if (!observed) return stale ? "No current runtime dependency observations to compare \u2014 earlier runtime evidence is stale." : "No runtime dependency observations to compare with declared code.";
|
|
18174
|
+
return "None \u2014 declared code and observed runtime agree across the graph.";
|
|
18175
|
+
}
|
|
18088
18176
|
function buildDivergenceSection(graph, node, incidents) {
|
|
18089
18177
|
const result = computeDivergences(graph, { node, ...incidents ? { incidents } : {} });
|
|
18090
18178
|
if (result.totalAffected === 0) return null;
|
|
@@ -18101,19 +18189,28 @@ function buildDivergenceSection(graph, node, incidents) {
|
|
|
18101
18189
|
}
|
|
18102
18190
|
function buildGlobalDivergenceSection(graph, incidents) {
|
|
18103
18191
|
const result = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18192
|
+
const pending = pendingRuntimeMessage(graph, result.divergences);
|
|
18193
|
+
const visible = pending ? result.divergences.filter((d) => d.type !== "missing-observed") : result.divergences;
|
|
18194
|
+
if (visible.length === 0 && pending) {
|
|
18195
|
+
return {
|
|
18196
|
+
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18197
|
+
facts: [{ text: pending }]
|
|
18198
|
+
};
|
|
18199
|
+
}
|
|
18104
18200
|
if (result.totalAffected === 0) {
|
|
18105
18201
|
return {
|
|
18106
18202
|
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18107
|
-
facts: [{ text:
|
|
18203
|
+
facts: [{ text: noDivergenceMessage(graph) }]
|
|
18108
18204
|
};
|
|
18109
18205
|
}
|
|
18110
|
-
const facts =
|
|
18206
|
+
const facts = visible.slice(0, MAX_FACTS_PER_SECTION).map((d) => ({
|
|
18111
18207
|
text: divergenceLine(d),
|
|
18112
18208
|
confidence: d.confidence
|
|
18113
18209
|
// Composite by construction (EXTRACTED vs OBSERVED), so no single provenance.
|
|
18114
18210
|
}));
|
|
18211
|
+
if (pending && facts.length < MAX_FACTS_PER_SECTION) facts.push({ text: pending });
|
|
18115
18212
|
return {
|
|
18116
|
-
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${
|
|
18213
|
+
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${visible.length}`,
|
|
18117
18214
|
facts
|
|
18118
18215
|
};
|
|
18119
18216
|
}
|
|
@@ -18199,13 +18296,12 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18199
18296
|
});
|
|
18200
18297
|
}
|
|
18201
18298
|
const div = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18299
|
+
const pending = pendingRuntimeMessage(graph, div.divergences);
|
|
18300
|
+
const visibleCount = pending ? div.divergences.filter((d) => d.type !== "missing-observed").length : div.totalAffected;
|
|
18301
|
+
const divergenceText = visibleCount > 0 ? `${visibleCount} divergence${visibleCount === 1 ? "" : "s"} between declared code and observed runtime \u2014 ask "are there any divergences?" for the list.${pending ? ` ${pending}` : ""}` : pending ?? noDivergenceMessage(graph);
|
|
18202
18302
|
sections.push({
|
|
18203
18303
|
heading: "Divergences",
|
|
18204
|
-
facts: [
|
|
18205
|
-
{
|
|
18206
|
-
text: div.totalAffected === 0 ? "None \u2014 declared code and observed runtime agree across the graph." : `${div.totalAffected} divergence${div.totalAffected === 1 ? "" : "s"} between declared code and observed runtime \u2014 ask "are there any divergences?" for the list.`
|
|
18207
|
-
}
|
|
18208
|
-
]
|
|
18304
|
+
facts: [{ text: divergenceText }]
|
|
18209
18305
|
});
|
|
18210
18306
|
return sections;
|
|
18211
18307
|
}
|
|
@@ -18250,6 +18346,8 @@ function summarizeGlobal(intent, sections) {
|
|
|
18250
18346
|
const lead = sections[0];
|
|
18251
18347
|
switch (intent) {
|
|
18252
18348
|
case "divergence": {
|
|
18349
|
+
const pending = lead?.facts[0]?.text;
|
|
18350
|
+
if (pending?.startsWith("No runtime") || pending?.startsWith("No current runtime") || pending?.startsWith("Graph is empty")) return pending;
|
|
18253
18351
|
const none = lead?.facts[0]?.text.startsWith("None") ?? true;
|
|
18254
18352
|
return none ? "No divergences across the graph \u2014 declared code and observed runtime agree." : `${lead.heading} across the graph, highest-confidence first below.`;
|
|
18255
18353
|
}
|
|
@@ -18262,11 +18360,16 @@ function summarizeGlobal(intent, sections) {
|
|
|
18262
18360
|
return `System overview across the whole graph: ${sections.length} view${sections.length === 1 ? "" : "s"} below \u2014 shape (nodes/edges by provenance), busiest services, incidents, and divergences.`;
|
|
18263
18361
|
}
|
|
18264
18362
|
}
|
|
18265
|
-
function summarize(question, intent, matched, primary, sections, scope) {
|
|
18363
|
+
function summarize(question, intent, matched, primary, sections, scope, ambiguousType) {
|
|
18266
18364
|
if (scope === "global") {
|
|
18267
18365
|
return summarizeGlobal(intent, sections);
|
|
18268
18366
|
}
|
|
18269
18367
|
if (!primary) {
|
|
18368
|
+
if (ambiguousType) {
|
|
18369
|
+
const shown = ambiguousType.ids.slice(0, 10);
|
|
18370
|
+
const more = ambiguousType.ids.length - shown.length;
|
|
18371
|
+
return `"${ambiguousType.noun}" matches ${ambiguousType.ids.length} nodes. Name one by ID: ${shown.join(", ")}${more > 0 ? `, and ${more} more` : ""}.`;
|
|
18372
|
+
}
|
|
18270
18373
|
return `Nothing in "${question}" resolved to a node in the graph. Name a service, file, route, or table \u2014 e.g. \`ask "what does <service> depend on?"\`. For a graph-wide look, ask for an overview, divergences, or incidents.`;
|
|
18271
18374
|
}
|
|
18272
18375
|
const lead = sections[0];
|
|
@@ -18289,10 +18392,13 @@ function summarize(question, intent, matched, primary, sections, scope) {
|
|
|
18289
18392
|
core = lead ? `${lead.heading} of ${primary}.` : `${primary} has no dependents \u2014 nothing else would break if it failed.`;
|
|
18290
18393
|
break;
|
|
18291
18394
|
case "dependencies":
|
|
18292
|
-
core = lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18395
|
+
core = lead?.heading.startsWith("Services calling") ? `${lead.heading}.` : lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18293
18396
|
break;
|
|
18294
18397
|
case "observed":
|
|
18295
|
-
|
|
18398
|
+
{
|
|
18399
|
+
const observed = sections.find((s) => s.heading === "Runtime dependencies (OBSERVED)");
|
|
18400
|
+
core = observed ? `${primary} at runtime: ${observed.facts.length} OBSERVED fact${observed.facts.length === 1 ? "" : "s"}.` : `No runtime traffic OBSERVED for ${primary}.`;
|
|
18401
|
+
}
|
|
18296
18402
|
break;
|
|
18297
18403
|
case "incidents":
|
|
18298
18404
|
core = lead ? `${primary}: ${lead.heading.toLowerCase()}.` : `No incidents recorded against ${primary}.`;
|
|
@@ -18309,24 +18415,28 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18309
18415
|
const now = opts.now ?? Date.now();
|
|
18310
18416
|
const maxNodes = opts.maxNodes ?? DEFAULT_MAX_NODES;
|
|
18311
18417
|
const intent = classifyIntent(question);
|
|
18312
|
-
const
|
|
18418
|
+
const resolution = await resolveEntities(graph, question, opts.searchIndex, maxNodes);
|
|
18419
|
+
const matched = resolution.matched;
|
|
18313
18420
|
const primary = matched[0]?.nodeId;
|
|
18314
18421
|
const sections = [];
|
|
18315
18422
|
let scope;
|
|
18316
18423
|
if (primary) {
|
|
18317
18424
|
scope = "node";
|
|
18425
|
+
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types62.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
|
|
18426
|
+
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18318
18427
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18428
|
+
if (callersQuestion && kind === "blast") continue;
|
|
18319
18429
|
const s = buildSection(kind, graph, primary, opts.incidents, now);
|
|
18320
18430
|
if (s && s.facts.length > 0) sections.push(s);
|
|
18321
18431
|
}
|
|
18322
18432
|
} else {
|
|
18323
|
-
const global = buildGlobalSections(intent, graph, opts.incidents);
|
|
18433
|
+
const global = resolution.ambiguousType ? null : buildGlobalSections(intent, graph, opts.incidents);
|
|
18324
18434
|
if (global) {
|
|
18325
18435
|
scope = "global";
|
|
18326
18436
|
for (const s of global) if (s.facts.length > 0) sections.push(s);
|
|
18327
18437
|
}
|
|
18328
18438
|
}
|
|
18329
|
-
const answer = summarize(question, intent, matched, primary, sections, scope);
|
|
18439
|
+
const answer = summarize(question, intent, matched, primary, sections, scope, resolution.ambiguousType);
|
|
18330
18440
|
const provSet = /* @__PURE__ */ new Set();
|
|
18331
18441
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18332
18442
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
@@ -20154,9 +20264,9 @@ var RESOURCE_TYPES = [
|
|
|
20154
20264
|
function isFirebaseResourceType(value) {
|
|
20155
20265
|
return RESOURCE_TYPES.includes(value);
|
|
20156
20266
|
}
|
|
20157
|
-
function buildEntriesFilter(sinceIso) {
|
|
20267
|
+
function buildEntriesFilter(sinceIso, resourceTypes = RESOURCE_TYPES) {
|
|
20158
20268
|
return [
|
|
20159
|
-
|
|
20269
|
+
`resource.type = (${resourceTypes.map((t) => `"${t}"`).join(" OR ")})`,
|
|
20160
20270
|
"httpRequest:*",
|
|
20161
20271
|
`timestamp >= "${sinceIso}"`
|
|
20162
20272
|
].join(" AND ");
|
|
@@ -20165,8 +20275,8 @@ var DEFAULT_LOOKBACK_MS = 24 * 60 * 60 * 1e3;
|
|
|
20165
20275
|
var ENTRIES_LIST_URL = "https://logging.googleapis.com/v2/entries:list";
|
|
20166
20276
|
var PAGE_SIZE = 1e3;
|
|
20167
20277
|
var MAX_PAGES = 20;
|
|
20168
|
-
async function fetchHttpRequestLogEntries(creds, sinceIso) {
|
|
20169
|
-
const filter = buildEntriesFilter(sinceIso);
|
|
20278
|
+
async function fetchHttpRequestLogEntries(creds, sinceIso, resourceTypes) {
|
|
20279
|
+
const filter = buildEntriesFilter(sinceIso, resourceTypes);
|
|
20170
20280
|
const out = [];
|
|
20171
20281
|
let pageToken;
|
|
20172
20282
|
for (let page = 0; page < MAX_PAGES; page++) {
|
|
@@ -20281,7 +20391,38 @@ function mapLogEntriesToSignals(entries) {
|
|
|
20281
20391
|
|
|
20282
20392
|
// src/connectors/firebase/resolve.ts
|
|
20283
20393
|
init_cjs_shims();
|
|
20394
|
+
var import_types72 = require("@neat.is/types");
|
|
20395
|
+
|
|
20396
|
+
// src/connectors/infer-service.ts
|
|
20397
|
+
init_cjs_shims();
|
|
20284
20398
|
var import_types71 = require("@neat.is/types");
|
|
20399
|
+
function normalizeName(name) {
|
|
20400
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
20401
|
+
}
|
|
20402
|
+
function inferServiceName(graph, resourceName, method, path81) {
|
|
20403
|
+
const wantedMethod = method.toUpperCase();
|
|
20404
|
+
const wantedPath = normalizePathTemplate(path81);
|
|
20405
|
+
const services = [];
|
|
20406
|
+
const owners = /* @__PURE__ */ new Set();
|
|
20407
|
+
graph.forEachNode((_id, attrs) => {
|
|
20408
|
+
const node = attrs;
|
|
20409
|
+
if (node.type === import_types71.NodeType.ServiceNode && typeof node.name === "string") {
|
|
20410
|
+
services.push(node.name);
|
|
20411
|
+
return;
|
|
20412
|
+
}
|
|
20413
|
+
if (node.type !== import_types71.NodeType.RouteNode) return;
|
|
20414
|
+
const route = attrs;
|
|
20415
|
+
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
20416
|
+
const routeMethod = route.method.toUpperCase();
|
|
20417
|
+
if (routeMethod === "ALL" || routeMethod === wantedMethod) owners.add(route.service);
|
|
20418
|
+
});
|
|
20419
|
+
const wanted = normalizeName(resourceName);
|
|
20420
|
+
const byName = services.find((s) => normalizeName(s) === wanted);
|
|
20421
|
+
if (byName) return byName;
|
|
20422
|
+
return owners.size === 1 ? [...owners][0] : null;
|
|
20423
|
+
}
|
|
20424
|
+
|
|
20425
|
+
// src/connectors/firebase/resolve.ts
|
|
20285
20426
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
20286
20427
|
switch (resourceType) {
|
|
20287
20428
|
case "cloud_function":
|
|
@@ -20296,7 +20437,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
20296
20437
|
const entries = [];
|
|
20297
20438
|
graph.forEachNode((_id, attrs) => {
|
|
20298
20439
|
const node = attrs;
|
|
20299
|
-
if (node.type !==
|
|
20440
|
+
if (node.type !== import_types72.NodeType.RouteNode) return;
|
|
20300
20441
|
const route = attrs;
|
|
20301
20442
|
if (route.service !== serviceName) return;
|
|
20302
20443
|
entries.push({
|
|
@@ -20320,32 +20461,38 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
20320
20461
|
}
|
|
20321
20462
|
const identity = parseFirebaseTargetName(signal.targetName);
|
|
20322
20463
|
if (!identity) return null;
|
|
20323
|
-
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap);
|
|
20324
|
-
if (!serviceName) return null;
|
|
20325
20464
|
const normalizedPath = normalizePathTemplate(identity.path);
|
|
20465
|
+
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap) ?? (serviceMap.inferServices ? inferServiceName(graph, identity.resourceName, identity.method, identity.path) : null);
|
|
20466
|
+
if (!serviceName) return null;
|
|
20326
20467
|
const match = findRoute2(routeEntriesFor(graph, serviceName), identity.method, normalizedPath);
|
|
20327
20468
|
if (!match) return null;
|
|
20328
20469
|
return {
|
|
20329
20470
|
targetNodeId: match.routeNodeId,
|
|
20330
20471
|
serviceName,
|
|
20331
|
-
edgeType:
|
|
20472
|
+
edgeType: import_types72.EdgeType.CALLS
|
|
20332
20473
|
};
|
|
20333
20474
|
};
|
|
20334
20475
|
}
|
|
20335
20476
|
|
|
20336
20477
|
// src/connectors/firebase/index.ts
|
|
20337
20478
|
var FirebaseConnector = class {
|
|
20479
|
+
constructor(opts = {}) {
|
|
20480
|
+
this.opts = opts;
|
|
20481
|
+
}
|
|
20482
|
+
opts;
|
|
20338
20483
|
provider = "firebase";
|
|
20339
20484
|
async poll(ctx) {
|
|
20340
20485
|
const creds = readFirebaseCredentials(ctx.credentials);
|
|
20341
20486
|
const sinceIso = ctx.since ?? new Date(Date.now() - DEFAULT_LOOKBACK_MS).toISOString();
|
|
20342
|
-
const entries = await fetchHttpRequestLogEntries(creds, sinceIso);
|
|
20487
|
+
const entries = await fetchHttpRequestLogEntries(creds, sinceIso, this.opts.resourceTypes);
|
|
20343
20488
|
return mapLogEntriesToSignals(entries);
|
|
20344
20489
|
}
|
|
20345
20490
|
};
|
|
20346
20491
|
function createFirebaseConnector(graph, serviceMap) {
|
|
20347
20492
|
return {
|
|
20348
|
-
connector: new FirebaseConnector(
|
|
20493
|
+
connector: new FirebaseConnector(
|
|
20494
|
+
serviceMap.excludeCloudRun ? { resourceTypes: ["cloud_function", "firebase_domain"] } : {}
|
|
20495
|
+
),
|
|
20349
20496
|
resolveTarget: createFirebaseResolveTarget(graph, serviceMap)
|
|
20350
20497
|
};
|
|
20351
20498
|
}
|
|
@@ -20355,7 +20502,7 @@ init_cjs_shims();
|
|
|
20355
20502
|
|
|
20356
20503
|
// src/connectors/cloudflare/connector.ts
|
|
20357
20504
|
init_cjs_shims();
|
|
20358
|
-
var
|
|
20505
|
+
var import_types74 = require("@neat.is/types");
|
|
20359
20506
|
|
|
20360
20507
|
// src/connectors/cloudflare/client.ts
|
|
20361
20508
|
init_cjs_shims();
|
|
@@ -20519,7 +20666,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
20519
20666
|
graph.forEachNode((id, attrs) => {
|
|
20520
20667
|
if (found) return;
|
|
20521
20668
|
const a = attrs;
|
|
20522
|
-
if (a.type ===
|
|
20669
|
+
if (a.type === import_types74.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
20523
20670
|
found = id;
|
|
20524
20671
|
}
|
|
20525
20672
|
});
|
|
@@ -20531,7 +20678,7 @@ function findMatchingRouteNode(graph, serviceName, method, path81) {
|
|
|
20531
20678
|
graph.forEachNode((id, attrs) => {
|
|
20532
20679
|
if (found) return;
|
|
20533
20680
|
const a = attrs;
|
|
20534
|
-
if (a.type !==
|
|
20681
|
+
if (a.type !== import_types74.NodeType.RouteNode || a.service !== serviceName) return;
|
|
20535
20682
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
20536
20683
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
20537
20684
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -20550,11 +20697,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20550
20697
|
};
|
|
20551
20698
|
const mapping = config.workers?.[scriptName];
|
|
20552
20699
|
if (mapping) {
|
|
20553
|
-
const wholeFileId = (0,
|
|
20700
|
+
const wholeFileId = (0, import_types74.fileId)(mapping.service, mapping.entryFile);
|
|
20554
20701
|
return {
|
|
20555
20702
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
20556
20703
|
serviceName: mapping.service,
|
|
20557
|
-
edgeType:
|
|
20704
|
+
edgeType: import_types74.EdgeType.CALLS
|
|
20558
20705
|
};
|
|
20559
20706
|
}
|
|
20560
20707
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -20563,13 +20710,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20563
20710
|
return {
|
|
20564
20711
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
20565
20712
|
serviceName: fileNode.service,
|
|
20566
|
-
edgeType:
|
|
20713
|
+
edgeType: import_types74.EdgeType.CALLS
|
|
20567
20714
|
};
|
|
20568
20715
|
}
|
|
20569
20716
|
return {
|
|
20570
|
-
targetNodeId: (0,
|
|
20717
|
+
targetNodeId: (0, import_types74.infraId)("cloudflare-worker", scriptName),
|
|
20571
20718
|
serviceName: scriptName,
|
|
20572
|
-
edgeType:
|
|
20719
|
+
edgeType: import_types74.EdgeType.CALLS,
|
|
20573
20720
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
20574
20721
|
};
|
|
20575
20722
|
};
|
|
@@ -20765,14 +20912,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
20765
20912
|
|
|
20766
20913
|
// src/connectors/neon/resolve.ts
|
|
20767
20914
|
init_cjs_shims();
|
|
20768
|
-
var
|
|
20915
|
+
var import_types78 = require("@neat.is/types");
|
|
20769
20916
|
function createNeonResolveTarget(config) {
|
|
20770
20917
|
return (signal) => {
|
|
20771
20918
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
20772
20919
|
return {
|
|
20773
|
-
targetNodeId: (0,
|
|
20920
|
+
targetNodeId: (0, import_types78.infraId)("sql-table", signal.targetName),
|
|
20774
20921
|
serviceName: config.serviceName,
|
|
20775
|
-
edgeType:
|
|
20922
|
+
edgeType: import_types78.EdgeType.CALLS,
|
|
20776
20923
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
20777
20924
|
};
|
|
20778
20925
|
};
|
|
@@ -20953,14 +21100,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
20953
21100
|
|
|
20954
21101
|
// src/connectors/cloud-run/resolve.ts
|
|
20955
21102
|
init_cjs_shims();
|
|
20956
|
-
var
|
|
21103
|
+
var import_types82 = require("@neat.is/types");
|
|
20957
21104
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
20958
21105
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
20959
21106
|
let found = null;
|
|
20960
21107
|
graph.forEachNode((_id, attrs) => {
|
|
20961
21108
|
if (found) return;
|
|
20962
21109
|
const node = attrs;
|
|
20963
|
-
if (node.type !==
|
|
21110
|
+
if (node.type !== import_types82.NodeType.RouteNode) return;
|
|
20964
21111
|
const route = attrs;
|
|
20965
21112
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
20966
21113
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -20976,7 +21123,7 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20976
21123
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
20977
21124
|
if (!identity) return null;
|
|
20978
21125
|
const { serviceName: gcpServiceName, method, path: path81 } = identity;
|
|
20979
|
-
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
21126
|
+
const mappedService = config.serviceMap?.[gcpServiceName] ?? (config.inferServices ? inferServiceName(graph, gcpServiceName, method, path81) ?? void 0 : void 0);
|
|
20980
21127
|
if (mappedService) {
|
|
20981
21128
|
const routeNodeId = findMatchingRouteNode2(
|
|
20982
21129
|
graph,
|
|
@@ -20985,13 +21132,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20985
21132
|
normalizePathTemplate(path81)
|
|
20986
21133
|
);
|
|
20987
21134
|
if (routeNodeId) {
|
|
20988
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21135
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types82.EdgeType.CALLS };
|
|
20989
21136
|
}
|
|
20990
21137
|
}
|
|
20991
21138
|
return {
|
|
20992
|
-
targetNodeId: (0,
|
|
21139
|
+
targetNodeId: (0, import_types82.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
20993
21140
|
serviceName: mappedService ?? gcpServiceName,
|
|
20994
|
-
edgeType:
|
|
21141
|
+
edgeType: import_types82.EdgeType.CALLS,
|
|
20995
21142
|
ensureInfraNode: {
|
|
20996
21143
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
20997
21144
|
name: gcpServiceName,
|
|
@@ -21173,14 +21320,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
21173
21320
|
|
|
21174
21321
|
// src/connectors/gcp-lb/resolve.ts
|
|
21175
21322
|
init_cjs_shims();
|
|
21176
|
-
var
|
|
21323
|
+
var import_types86 = require("@neat.is/types");
|
|
21177
21324
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
21178
21325
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
21179
21326
|
let found = null;
|
|
21180
21327
|
graph.forEachNode((_id, attrs) => {
|
|
21181
21328
|
if (found) return;
|
|
21182
21329
|
const node = attrs;
|
|
21183
|
-
if (node.type !==
|
|
21330
|
+
if (node.type !== import_types86.NodeType.RouteNode) return;
|
|
21184
21331
|
const route = attrs;
|
|
21185
21332
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
21186
21333
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -21196,7 +21343,7 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21196
21343
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21197
21344
|
if (!identity) return null;
|
|
21198
21345
|
const { backendServiceName, method, path: path81 } = identity;
|
|
21199
|
-
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
21346
|
+
const mappedService = config.backendServiceMap?.[backendServiceName] ?? (config.inferServices ? inferServiceName(graph, backendServiceName, method, path81) ?? void 0 : void 0);
|
|
21200
21347
|
if (mappedService) {
|
|
21201
21348
|
const routeNodeId = findMatchingRouteNode3(
|
|
21202
21349
|
graph,
|
|
@@ -21205,13 +21352,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21205
21352
|
normalizePathTemplate(path81)
|
|
21206
21353
|
);
|
|
21207
21354
|
if (routeNodeId) {
|
|
21208
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21355
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types86.EdgeType.CALLS };
|
|
21209
21356
|
}
|
|
21210
21357
|
}
|
|
21211
21358
|
return {
|
|
21212
|
-
targetNodeId: (0,
|
|
21359
|
+
targetNodeId: (0, import_types86.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
21213
21360
|
serviceName: mappedService ?? backendServiceName,
|
|
21214
|
-
edgeType:
|
|
21361
|
+
edgeType: import_types86.EdgeType.CALLS,
|
|
21215
21362
|
ensureInfraNode: {
|
|
21216
21363
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
21217
21364
|
name: backendServiceName,
|
|
@@ -21252,7 +21399,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
21252
21399
|
|
|
21253
21400
|
// src/connectors/render/index.ts
|
|
21254
21401
|
init_cjs_shims();
|
|
21255
|
-
var
|
|
21402
|
+
var import_types89 = require("@neat.is/types");
|
|
21256
21403
|
|
|
21257
21404
|
// src/connectors/render/types.ts
|
|
21258
21405
|
init_cjs_shims();
|
|
@@ -21330,7 +21477,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
21330
21477
|
const out = [];
|
|
21331
21478
|
graph.forEachNode((_id, attrs) => {
|
|
21332
21479
|
const node = attrs;
|
|
21333
|
-
if (node.type !==
|
|
21480
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
21334
21481
|
const route = attrs;
|
|
21335
21482
|
if (route.service !== serviceName) return;
|
|
21336
21483
|
out.push({
|
|
@@ -21415,7 +21562,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
21415
21562
|
function createRenderResolveTarget(config) {
|
|
21416
21563
|
return (signal) => {
|
|
21417
21564
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
21418
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
21565
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types89.EdgeType.CALLS };
|
|
21419
21566
|
}
|
|
21420
21567
|
return null;
|
|
21421
21568
|
};
|
|
@@ -21553,21 +21700,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
21553
21700
|
|
|
21554
21701
|
// src/connectors/planetscale/resolve.ts
|
|
21555
21702
|
init_cjs_shims();
|
|
21556
|
-
var
|
|
21703
|
+
var import_types93 = require("@neat.is/types");
|
|
21557
21704
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
21558
21705
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
21559
21706
|
const databaseName = `${config.organization}/${config.database}`;
|
|
21560
21707
|
return (signal, _ctx) => {
|
|
21561
21708
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
21562
|
-
const tableId = (0,
|
|
21709
|
+
const tableId = (0, import_types93.infraId)("sql-table", signal.targetName);
|
|
21563
21710
|
if (graph.hasNode(tableId)) {
|
|
21564
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
21711
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types93.EdgeType.CALLS };
|
|
21565
21712
|
}
|
|
21566
|
-
const providerId = (0,
|
|
21713
|
+
const providerId = (0, import_types93.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
21567
21714
|
return {
|
|
21568
21715
|
targetNodeId: providerId,
|
|
21569
21716
|
serviceName: config.serviceName,
|
|
21570
|
-
edgeType:
|
|
21717
|
+
edgeType: import_types93.EdgeType.CALLS,
|
|
21571
21718
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
21572
21719
|
};
|
|
21573
21720
|
};
|
|
@@ -21832,7 +21979,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
21832
21979
|
|
|
21833
21980
|
// src/connectors/eas/resolve.ts
|
|
21834
21981
|
init_cjs_shims();
|
|
21835
|
-
var
|
|
21982
|
+
var import_types98 = require("@neat.is/types");
|
|
21836
21983
|
var NO_ENV2 = "unknown";
|
|
21837
21984
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
21838
21985
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -21848,8 +21995,8 @@ function configBasenamesForPhase(phase) {
|
|
|
21848
21995
|
function configNodeService(graph, configNodeId) {
|
|
21849
21996
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
21850
21997
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
21851
|
-
if (edge.type !==
|
|
21852
|
-
const parsed = (0,
|
|
21998
|
+
if (edge.type !== import_types98.EdgeType.CONFIGURED_BY) continue;
|
|
21999
|
+
const parsed = (0, import_types98.parseFileId)(edge.source);
|
|
21853
22000
|
if (parsed) return parsed.service;
|
|
21854
22001
|
}
|
|
21855
22002
|
return null;
|
|
@@ -21860,7 +22007,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
21860
22007
|
graph.forEachNode((id, attrs) => {
|
|
21861
22008
|
if (scoped) return;
|
|
21862
22009
|
const node = attrs;
|
|
21863
|
-
if (node.type !==
|
|
22010
|
+
if (node.type !== import_types98.NodeType.ConfigNode) return;
|
|
21864
22011
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
21865
22012
|
if (anyMatch === null) anyMatch = id;
|
|
21866
22013
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -21877,13 +22024,13 @@ function createEasResolveTarget(graph) {
|
|
|
21877
22024
|
if (basenames.length > 0) {
|
|
21878
22025
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
21879
22026
|
if (configNodeId) {
|
|
21880
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
22027
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types98.EdgeType.CALLS };
|
|
21881
22028
|
}
|
|
21882
22029
|
}
|
|
21883
22030
|
return {
|
|
21884
22031
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
21885
22032
|
serviceName,
|
|
21886
|
-
edgeType:
|
|
22033
|
+
edgeType: import_types98.EdgeType.CALLS
|
|
21887
22034
|
};
|
|
21888
22035
|
};
|
|
21889
22036
|
}
|
|
@@ -22371,6 +22518,9 @@ var PUSH_PROVIDER_DISPATCH = {
|
|
|
22371
22518
|
}
|
|
22372
22519
|
}
|
|
22373
22520
|
};
|
|
22521
|
+
function getPushProviderDispatch(provider) {
|
|
22522
|
+
return PUSH_PROVIDER_DISPATCH[provider];
|
|
22523
|
+
}
|
|
22374
22524
|
function isPushProvider(provider) {
|
|
22375
22525
|
return provider in PUSH_PROVIDER_DISPATCH;
|
|
22376
22526
|
}
|
|
@@ -22664,11 +22814,11 @@ function registerRoutes(scope, ctx) {
|
|
|
22664
22814
|
const candidates = req2.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
22665
22815
|
const parsed = [];
|
|
22666
22816
|
for (const c of candidates) {
|
|
22667
|
-
const r =
|
|
22817
|
+
const r = import_types101.DivergenceTypeSchema.safeParse(c);
|
|
22668
22818
|
if (!r.success) {
|
|
22669
22819
|
return reply.code(400).send({
|
|
22670
22820
|
error: `unknown divergence type "${c}"`,
|
|
22671
|
-
allowed:
|
|
22821
|
+
allowed: import_types101.DivergenceTypeSchema.options
|
|
22672
22822
|
});
|
|
22673
22823
|
}
|
|
22674
22824
|
parsed.push(r.data);
|
|
@@ -23064,7 +23214,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23064
23214
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
23065
23215
|
let violations = await log.readAll();
|
|
23066
23216
|
if (req2.query.severity) {
|
|
23067
|
-
const sev =
|
|
23217
|
+
const sev = import_types101.PolicySeveritySchema.safeParse(req2.query.severity);
|
|
23068
23218
|
if (!sev.success) {
|
|
23069
23219
|
return reply.code(400).send({
|
|
23070
23220
|
error: "invalid severity",
|
|
@@ -23103,7 +23253,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23103
23253
|
scope.post("/policies/check", async (req2, reply) => {
|
|
23104
23254
|
const proj = resolveProject(registry, req2, reply, ctx.bootstrap, ctx.singleProject);
|
|
23105
23255
|
if (!proj) return;
|
|
23106
|
-
const parsed =
|
|
23256
|
+
const parsed = import_types101.PoliciesCheckBodySchema.safeParse(req2.body ?? {});
|
|
23107
23257
|
if (!parsed.success) {
|
|
23108
23258
|
return reply.code(400).send({
|
|
23109
23259
|
error: "invalid /policies/check body",
|
|
@@ -23423,7 +23573,7 @@ init_otel();
|
|
|
23423
23573
|
|
|
23424
23574
|
// src/hang-sensor.ts
|
|
23425
23575
|
init_cjs_shims();
|
|
23426
|
-
var
|
|
23576
|
+
var import_types102 = require("@neat.is/types");
|
|
23427
23577
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
23428
23578
|
function stageHangSurfaces(graph, incidents) {
|
|
23429
23579
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -23436,7 +23586,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
23436
23586
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
23437
23587
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
23438
23588
|
if (!hop) continue;
|
|
23439
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
23589
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types102.EdgeType.CALLS)) staged++;
|
|
23440
23590
|
}
|
|
23441
23591
|
return staged;
|
|
23442
23592
|
}
|
|
@@ -23453,6 +23603,8 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
|
|
|
23453
23603
|
|
|
23454
23604
|
// src/connectors/hosted.ts
|
|
23455
23605
|
init_cjs_shims();
|
|
23606
|
+
var import_promises = require("fs/promises");
|
|
23607
|
+
var import_node_path75 = require("path");
|
|
23456
23608
|
|
|
23457
23609
|
// src/connectors/railway/target-ref.ts
|
|
23458
23610
|
init_cjs_shims();
|
|
@@ -23499,11 +23651,14 @@ function credentialRecord(provider, cred) {
|
|
|
23499
23651
|
switch (provider) {
|
|
23500
23652
|
case "supabase":
|
|
23501
23653
|
return { managementToken: cred.accessToken };
|
|
23654
|
+
case "gcp":
|
|
23655
|
+
if (!cred.projectRef) throw new Error("gcp credential delivered without a project ref");
|
|
23656
|
+
return { projectId: cred.projectRef, accessToken: cred.accessToken };
|
|
23502
23657
|
default:
|
|
23503
23658
|
return { token: cred.accessToken };
|
|
23504
23659
|
}
|
|
23505
23660
|
}
|
|
23506
|
-
function hostedOptions(provider, summary, serviceName) {
|
|
23661
|
+
function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
23507
23662
|
switch (provider) {
|
|
23508
23663
|
case "supabase": {
|
|
23509
23664
|
const ref = summary.projectRef;
|
|
@@ -23519,10 +23674,125 @@ function hostedOptions(provider, summary, serviceName) {
|
|
|
23519
23674
|
serviceNameById: { [target.serviceId]: serviceName }
|
|
23520
23675
|
};
|
|
23521
23676
|
}
|
|
23677
|
+
case "firebase": {
|
|
23678
|
+
return { inferServices: true, excludeCloudRun: true, ...firebaseServiceMap ?? {} };
|
|
23679
|
+
}
|
|
23680
|
+
case "cloud-run":
|
|
23681
|
+
case "gcp-lb":
|
|
23682
|
+
return { inferServices: true };
|
|
23522
23683
|
default:
|
|
23523
23684
|
return null;
|
|
23524
23685
|
}
|
|
23525
23686
|
}
|
|
23687
|
+
function parseFirebaseServiceMap(raw) {
|
|
23688
|
+
if (!raw) return void 0;
|
|
23689
|
+
try {
|
|
23690
|
+
const parsed = JSON.parse(raw);
|
|
23691
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
23692
|
+
const out = {};
|
|
23693
|
+
for (const key of ["functions", "cloudRun", "hosting"]) {
|
|
23694
|
+
const group = parsed[key];
|
|
23695
|
+
if (group === void 0) continue;
|
|
23696
|
+
if (!group || typeof group !== "object" || Array.isArray(group)) return void 0;
|
|
23697
|
+
const entries = Object.entries(group);
|
|
23698
|
+
if (entries.some(([, v]) => typeof v !== "string" || v.length === 0)) return void 0;
|
|
23699
|
+
out[key] = Object.fromEntries(entries);
|
|
23700
|
+
}
|
|
23701
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
23702
|
+
} catch {
|
|
23703
|
+
return void 0;
|
|
23704
|
+
}
|
|
23705
|
+
}
|
|
23706
|
+
function pushHandlesPath(projectDir) {
|
|
23707
|
+
return (0, import_node_path75.join)(projectDir, "neat-out", "connectors-hosted.json");
|
|
23708
|
+
}
|
|
23709
|
+
async function readPushHandles(projectDir) {
|
|
23710
|
+
try {
|
|
23711
|
+
const parsed = JSON.parse(await (0, import_promises.readFile)(pushHandlesPath(projectDir), "utf8"));
|
|
23712
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
23713
|
+
} catch {
|
|
23714
|
+
return {};
|
|
23715
|
+
}
|
|
23716
|
+
}
|
|
23717
|
+
async function writePushHandle(projectDir, provider, handle) {
|
|
23718
|
+
const path81 = pushHandlesPath(projectDir);
|
|
23719
|
+
const handles = await readPushHandles(projectDir);
|
|
23720
|
+
handles[provider] = handle;
|
|
23721
|
+
await (0, import_promises.mkdir)((0, import_node_path75.dirname)(path81), { recursive: true });
|
|
23722
|
+
const tmp = `${path81}.${process.pid}.tmp`;
|
|
23723
|
+
await (0, import_promises.writeFile)(tmp, `${JSON.stringify(handles, null, 2)}
|
|
23724
|
+
`, "utf8");
|
|
23725
|
+
await (0, import_promises.rename)(tmp, path81);
|
|
23726
|
+
}
|
|
23727
|
+
function pushCredentialRecord(provider, cred, deps) {
|
|
23728
|
+
switch (provider) {
|
|
23729
|
+
case "vercel":
|
|
23730
|
+
return { token: cred.accessToken, otelToken: deps.otelToken ?? deps.daemonToken };
|
|
23731
|
+
default:
|
|
23732
|
+
return { token: cred.accessToken };
|
|
23733
|
+
}
|
|
23734
|
+
}
|
|
23735
|
+
function hostedPushOptions(provider, summary, deps) {
|
|
23736
|
+
switch (provider) {
|
|
23737
|
+
case "vercel": {
|
|
23738
|
+
if (!deps.publicUrl) {
|
|
23739
|
+
return { skip: "no public URL for this daemon (NEAT_PUBLIC_URL) \u2014 a drain has nowhere to deliver" };
|
|
23740
|
+
}
|
|
23741
|
+
if (!summary.projectRef) return { skip: "no Vercel team selected yet \u2014 drains are team-scoped" };
|
|
23742
|
+
const endpoint2 = `${deps.publicUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
23743
|
+
return { options: { teamId: summary.projectRef, endpoint: endpoint2 }, endpoint: endpoint2 };
|
|
23744
|
+
}
|
|
23745
|
+
default:
|
|
23746
|
+
return { skip: "no hosted option mapping for this push provider" };
|
|
23747
|
+
}
|
|
23748
|
+
}
|
|
23749
|
+
async function provisionHostedPushProvider(summary, dispatch, input) {
|
|
23750
|
+
const { deps, projectDir, onSkip, onProvisioned } = input;
|
|
23751
|
+
const provider = summary.provider;
|
|
23752
|
+
const mapped = hostedPushOptions(provider, summary, deps);
|
|
23753
|
+
if ("skip" in mapped) {
|
|
23754
|
+
onSkip?.(provider, mapped.skip);
|
|
23755
|
+
return;
|
|
23756
|
+
}
|
|
23757
|
+
let cred;
|
|
23758
|
+
try {
|
|
23759
|
+
cred = await cpGet(
|
|
23760
|
+
`/internal/projects/${deps.projectId}/connections/${provider}/credential`,
|
|
23761
|
+
deps
|
|
23762
|
+
);
|
|
23763
|
+
} catch (err) {
|
|
23764
|
+
onSkip?.(provider, `credential delivery failed \u2014 ${err.message}`);
|
|
23765
|
+
return;
|
|
23766
|
+
}
|
|
23767
|
+
const credentials = pushCredentialRecord(provider, cred, deps);
|
|
23768
|
+
const existing = (await readPushHandles(projectDir))[provider];
|
|
23769
|
+
const alreadyProvisioned = existing !== void 0 && existing.endpoint === mapped.endpoint;
|
|
23770
|
+
const options = alreadyProvisioned ? { ...mapped.options, ...existing.options } : mapped.options;
|
|
23771
|
+
const seam = deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {};
|
|
23772
|
+
const validation = await dispatch.validate({ credentials, options, ...seam });
|
|
23773
|
+
if (!validation.ok) {
|
|
23774
|
+
onSkip?.(provider, `drain delivery test failed \u2014 ${validation.reason}`);
|
|
23775
|
+
return;
|
|
23776
|
+
}
|
|
23777
|
+
if (alreadyProvisioned) {
|
|
23778
|
+
onProvisioned?.(provider, "drain already provisioned \u2014 delivery re-validated");
|
|
23779
|
+
return;
|
|
23780
|
+
}
|
|
23781
|
+
const result = await dispatch.provision({ credentials, options, ...seam });
|
|
23782
|
+
if (!result.ok) {
|
|
23783
|
+
onSkip?.(provider, `drain provisioning failed \u2014 ${result.reason}`);
|
|
23784
|
+
return;
|
|
23785
|
+
}
|
|
23786
|
+
await writePushHandle(projectDir, provider, {
|
|
23787
|
+
endpoint: mapped.endpoint,
|
|
23788
|
+
options: result.options ?? {},
|
|
23789
|
+
provisionedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23790
|
+
});
|
|
23791
|
+
onProvisioned?.(provider, result.note);
|
|
23792
|
+
}
|
|
23793
|
+
var HOSTED_CONNECTORS_FOR = {
|
|
23794
|
+
gcp: ["firebase", "cloud-run", "gcp-lb"]
|
|
23795
|
+
};
|
|
23526
23796
|
function createHostedCredentialSource(provider, deps) {
|
|
23527
23797
|
let cached = null;
|
|
23528
23798
|
return async () => {
|
|
@@ -23551,40 +23821,50 @@ async function startHostedConnectors(input) {
|
|
|
23551
23821
|
if (!Array.isArray(connections)) return () => {
|
|
23552
23822
|
};
|
|
23553
23823
|
const stops = [];
|
|
23824
|
+
const lookupPush = input.pushDispatch ?? getPushProviderDispatch;
|
|
23554
23825
|
for (const c of connections) {
|
|
23555
|
-
const
|
|
23556
|
-
if (
|
|
23557
|
-
|
|
23826
|
+
const push = lookupPush(c.provider);
|
|
23827
|
+
if (push) {
|
|
23828
|
+
await provisionHostedPushProvider(c, push, input);
|
|
23558
23829
|
continue;
|
|
23559
23830
|
}
|
|
23560
|
-
|
|
23561
|
-
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
|
|
23568
|
-
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
|
|
23572
|
-
|
|
23573
|
-
|
|
23574
|
-
|
|
23831
|
+
const credentialSource = createHostedCredentialSource(c.provider, deps);
|
|
23832
|
+
for (const name of HOSTED_CONNECTORS_FOR[c.provider] ?? [c.provider]) {
|
|
23833
|
+
const dispatch = PROVIDER_DISPATCH[name];
|
|
23834
|
+
if (!dispatch) {
|
|
23835
|
+
onSkip?.(name, "no pull connector for this provider");
|
|
23836
|
+
continue;
|
|
23837
|
+
}
|
|
23838
|
+
if (c.needsProjectSelection || !c.projectRef) {
|
|
23839
|
+
onSkip?.(name, "no project selected yet \u2014 not pullable");
|
|
23840
|
+
continue;
|
|
23841
|
+
}
|
|
23842
|
+
const options = hostedOptions(name, c, project, input.firebaseServiceMap);
|
|
23843
|
+
if (!options) {
|
|
23844
|
+
onSkip?.(name, "no hosted option mapping for this provider");
|
|
23845
|
+
continue;
|
|
23846
|
+
}
|
|
23847
|
+
let built;
|
|
23848
|
+
try {
|
|
23849
|
+
built = dispatch.build(graph, options);
|
|
23850
|
+
} catch (err) {
|
|
23851
|
+
onSkip?.(name, err.message);
|
|
23852
|
+
continue;
|
|
23853
|
+
}
|
|
23854
|
+
stops.push(
|
|
23855
|
+
startLoop(
|
|
23856
|
+
built.connector,
|
|
23857
|
+
{ projectDir, project, credentials: {}, ...errorsPath ? { errorsPath } : {} },
|
|
23858
|
+
graph,
|
|
23859
|
+
built.resolveTarget,
|
|
23860
|
+
{
|
|
23861
|
+
connectorId: `hosted:${name}`,
|
|
23862
|
+
// The credential is fetched by the CONNECTION's provider (`gcp`), not the connector's name.
|
|
23863
|
+
refreshCredentials: credentialSource
|
|
23864
|
+
}
|
|
23865
|
+
)
|
|
23866
|
+
);
|
|
23575
23867
|
}
|
|
23576
|
-
stops.push(
|
|
23577
|
-
startLoop(
|
|
23578
|
-
built.connector,
|
|
23579
|
-
{ projectDir, project, credentials: {}, ...errorsPath ? { errorsPath } : {} },
|
|
23580
|
-
graph,
|
|
23581
|
-
built.resolveTarget,
|
|
23582
|
-
{
|
|
23583
|
-
connectorId: `hosted:${c.provider}`,
|
|
23584
|
-
refreshCredentials: createHostedCredentialSource(c.provider, deps)
|
|
23585
|
-
}
|
|
23586
|
-
)
|
|
23587
|
-
);
|
|
23588
23868
|
}
|
|
23589
23869
|
return () => {
|
|
23590
23870
|
for (const stop of stops) stop();
|
|
@@ -23598,10 +23878,18 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23598
23878
|
if (!cpUrl || !projectId || !daemonToken) return () => {
|
|
23599
23879
|
};
|
|
23600
23880
|
return startHostedConnectors({
|
|
23601
|
-
deps: {
|
|
23881
|
+
deps: {
|
|
23882
|
+
cpUrl,
|
|
23883
|
+
projectId,
|
|
23884
|
+
daemonToken,
|
|
23885
|
+
...env.NEAT_PUBLIC_URL ? { publicUrl: env.NEAT_PUBLIC_URL } : {},
|
|
23886
|
+
...env.NEAT_OTEL_TOKEN ? { otelToken: env.NEAT_OTEL_TOKEN } : {},
|
|
23887
|
+
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
23888
|
+
},
|
|
23602
23889
|
graph: input.graph,
|
|
23603
23890
|
projectDir: input.projectDir,
|
|
23604
23891
|
project: input.project,
|
|
23892
|
+
...parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) ? { firebaseServiceMap: parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) } : {},
|
|
23605
23893
|
...input.errorsPath ? { errorsPath: input.errorsPath } : {},
|
|
23606
23894
|
...input.onSkip ? { onSkip: input.onSkip } : {}
|
|
23607
23895
|
});
|
|
@@ -23610,8 +23898,8 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23610
23898
|
// src/connectors/hosted-repos.ts
|
|
23611
23899
|
init_cjs_shims();
|
|
23612
23900
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
23613
|
-
var
|
|
23614
|
-
var
|
|
23901
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
23902
|
+
var import_promises2 = require("fs/promises");
|
|
23615
23903
|
var CP_REQUEST_TIMEOUT_MS2 = 1e4;
|
|
23616
23904
|
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
23617
23905
|
var CLONE_TIMEOUT_MS = 5 * 6e4;
|
|
@@ -23681,7 +23969,9 @@ async function syncOneRepo(r, input) {
|
|
|
23681
23969
|
const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
|
|
23682
23970
|
let dir;
|
|
23683
23971
|
try {
|
|
23684
|
-
dir = await (0,
|
|
23972
|
+
dir = await (0, import_promises2.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
23973
|
+
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
23974
|
+
});
|
|
23685
23975
|
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
23686
23976
|
const extracted = await extract(graph, dir);
|
|
23687
23977
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
@@ -23699,7 +23989,7 @@ async function syncOneRepo(r, input) {
|
|
|
23699
23989
|
}).catch(() => {
|
|
23700
23990
|
});
|
|
23701
23991
|
} finally {
|
|
23702
|
-
if (dir) await (0,
|
|
23992
|
+
if (dir) await (0, import_promises2.rm)(dir, { recursive: true, force: true }).catch(() => {
|
|
23703
23993
|
});
|
|
23704
23994
|
}
|
|
23705
23995
|
}
|
|
@@ -23709,23 +23999,26 @@ async function runRepoSyncPass(input) {
|
|
|
23709
23999
|
repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
23710
24000
|
} catch (err) {
|
|
23711
24001
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
23712
|
-
return;
|
|
24002
|
+
return false;
|
|
23713
24003
|
}
|
|
23714
|
-
if (!Array.isArray(repos)) return;
|
|
24004
|
+
if (!Array.isArray(repos)) return false;
|
|
23715
24005
|
for (const r of repos) {
|
|
23716
|
-
if (!needsSync(r)) continue;
|
|
24006
|
+
if (!input.forceResync && !needsSync(r)) continue;
|
|
23717
24007
|
await syncOneRepo(r, input);
|
|
23718
24008
|
}
|
|
24009
|
+
return true;
|
|
23719
24010
|
}
|
|
23720
24011
|
async function startRepoSync(input) {
|
|
23721
24012
|
const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
|
|
23722
24013
|
let stopped = false;
|
|
23723
24014
|
let running = false;
|
|
24015
|
+
let bootResyncDone = false;
|
|
23724
24016
|
const tick = async () => {
|
|
23725
24017
|
if (stopped || running) return;
|
|
23726
24018
|
running = true;
|
|
23727
24019
|
try {
|
|
23728
|
-
await runRepoSyncPass(input);
|
|
24020
|
+
const listed = await runRepoSyncPass({ ...input, forceResync: !bootResyncDone });
|
|
24021
|
+
if (listed) bootResyncDone = true;
|
|
23729
24022
|
} finally {
|
|
23730
24023
|
running = false;
|
|
23731
24024
|
}
|
|
@@ -24109,7 +24402,7 @@ function mapWorkloadsToSignals(deployments, pods, config) {
|
|
|
24109
24402
|
|
|
24110
24403
|
// src/connectors/kubernetes/resolve.ts
|
|
24111
24404
|
init_cjs_shims();
|
|
24112
|
-
var
|
|
24405
|
+
var import_types104 = require("@neat.is/types");
|
|
24113
24406
|
var NO_ENV3 = "unknown";
|
|
24114
24407
|
function createK8sResolveTarget(graph) {
|
|
24115
24408
|
return (signal) => {
|
|
@@ -24120,28 +24413,28 @@ function createK8sResolveTarget(graph) {
|
|
|
24120
24413
|
return {
|
|
24121
24414
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
24122
24415
|
serviceName,
|
|
24123
|
-
edgeType:
|
|
24416
|
+
edgeType: import_types104.EdgeType.CALLS
|
|
24124
24417
|
};
|
|
24125
24418
|
};
|
|
24126
24419
|
}
|
|
24127
24420
|
|
|
24128
24421
|
// src/connectors/kubernetes/substrate.ts
|
|
24129
24422
|
init_cjs_shims();
|
|
24130
|
-
var
|
|
24423
|
+
var import_promises3 = require("fs/promises");
|
|
24131
24424
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
24132
|
-
var
|
|
24425
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
24133
24426
|
function defaultHome() {
|
|
24134
24427
|
const override = process.env.NEAT_HOME;
|
|
24135
|
-
if (override && override.length > 0) return
|
|
24136
|
-
return
|
|
24428
|
+
if (override && override.length > 0) return import_node_path77.default.resolve(override);
|
|
24429
|
+
return import_node_path77.default.join(import_node_os6.default.homedir(), ".neat");
|
|
24137
24430
|
}
|
|
24138
24431
|
function k8sSubstrateConfigPath(home = defaultHome()) {
|
|
24139
|
-
return
|
|
24432
|
+
return import_node_path77.default.join(home, "k8s.json");
|
|
24140
24433
|
}
|
|
24141
24434
|
async function readK8sSubstrateConfig(home = defaultHome()) {
|
|
24142
24435
|
let raw;
|
|
24143
24436
|
try {
|
|
24144
|
-
raw = await (0,
|
|
24437
|
+
raw = await (0, import_promises3.readFile)(k8sSubstrateConfigPath(home), "utf8");
|
|
24145
24438
|
} catch {
|
|
24146
24439
|
return { version: 1, deployments: [] };
|
|
24147
24440
|
}
|
|
@@ -24236,7 +24529,7 @@ init_auth();
|
|
|
24236
24529
|
// src/unrouted.ts
|
|
24237
24530
|
init_cjs_shims();
|
|
24238
24531
|
var import_node_fs40 = require("fs");
|
|
24239
|
-
var
|
|
24532
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
24240
24533
|
function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
|
|
24241
24534
|
return {
|
|
24242
24535
|
timestamp: now.toISOString(),
|
|
@@ -24246,34 +24539,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
|
|
|
24246
24539
|
};
|
|
24247
24540
|
}
|
|
24248
24541
|
async function appendUnroutedSpan(neatHome4, record) {
|
|
24249
|
-
const target =
|
|
24542
|
+
const target = import_node_path78.default.join(neatHome4, "errors.ndjson");
|
|
24250
24543
|
await import_node_fs40.promises.mkdir(neatHome4, { recursive: true });
|
|
24251
24544
|
await import_node_fs40.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
|
|
24252
24545
|
}
|
|
24253
24546
|
function unroutedErrorsPath(neatHome4) {
|
|
24254
|
-
return
|
|
24547
|
+
return import_node_path78.default.join(neatHome4, "errors.ndjson");
|
|
24255
24548
|
}
|
|
24256
24549
|
|
|
24257
24550
|
// src/daemon.ts
|
|
24258
|
-
var
|
|
24551
|
+
var import_types107 = require("@neat.is/types");
|
|
24259
24552
|
function daemonJsonPath(scanPath) {
|
|
24260
|
-
return
|
|
24553
|
+
return import_node_path79.default.join(scanPath, "neat-out", "daemon.json");
|
|
24261
24554
|
}
|
|
24262
24555
|
function daemonsDiscoveryDir(home) {
|
|
24263
24556
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
24264
|
-
return
|
|
24557
|
+
return import_node_path79.default.join(base, "daemons");
|
|
24265
24558
|
}
|
|
24266
24559
|
function daemonDiscoveryPath(project, home) {
|
|
24267
|
-
return
|
|
24560
|
+
return import_node_path79.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
24268
24561
|
}
|
|
24269
24562
|
function sanitizeDiscoveryName(project) {
|
|
24270
24563
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
24271
24564
|
}
|
|
24272
24565
|
function neatHomeFromEnv() {
|
|
24273
24566
|
const env = process.env.NEAT_HOME;
|
|
24274
|
-
if (env && env.length > 0) return
|
|
24567
|
+
if (env && env.length > 0) return import_node_path79.default.resolve(env);
|
|
24275
24568
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24276
|
-
return
|
|
24569
|
+
return import_node_path79.default.join(home, ".neat");
|
|
24277
24570
|
}
|
|
24278
24571
|
function resolveNeatVersion() {
|
|
24279
24572
|
if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
|
|
@@ -24354,11 +24647,11 @@ function teardownSlot(slot) {
|
|
|
24354
24647
|
}
|
|
24355
24648
|
}
|
|
24356
24649
|
function neatHomeFor(opts) {
|
|
24357
|
-
if (opts.neatHome && opts.neatHome.length > 0) return
|
|
24650
|
+
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path79.default.resolve(opts.neatHome);
|
|
24358
24651
|
const env = process.env.NEAT_HOME;
|
|
24359
|
-
if (env && env.length > 0) return
|
|
24652
|
+
if (env && env.length > 0) return import_node_path79.default.resolve(env);
|
|
24360
24653
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24361
|
-
return
|
|
24654
|
+
return import_node_path79.default.join(home, ".neat");
|
|
24362
24655
|
}
|
|
24363
24656
|
function routeSpanToProject(serviceName, projects) {
|
|
24364
24657
|
if (!serviceName) return DEFAULT_PROJECT;
|
|
@@ -24406,11 +24699,11 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
24406
24699
|
if (!serviceName) return true;
|
|
24407
24700
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
24408
24701
|
return graph.someNode(
|
|
24409
|
-
(_id, attrs) => attrs.type ===
|
|
24702
|
+
(_id, attrs) => attrs.type === import_types107.NodeType.ServiceNode && attrs.name === serviceName
|
|
24410
24703
|
);
|
|
24411
24704
|
}
|
|
24412
24705
|
async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
24413
|
-
const paths = pathsForProject(entry2.name,
|
|
24706
|
+
const paths = pathsForProject(entry2.name, import_node_path79.default.join(entry2.path, "neat-out"));
|
|
24414
24707
|
try {
|
|
24415
24708
|
const stat = await import_node_fs41.promises.stat(entry2.path);
|
|
24416
24709
|
if (!stat.isDirectory()) {
|
|
@@ -24564,7 +24857,7 @@ async function startDaemon(opts = {}) {
|
|
|
24564
24857
|
const projectArg = typeof opts.project === "string" && opts.project.length > 0 ? opts.project : process.env.NEAT_PROJECT && process.env.NEAT_PROJECT.length > 0 ? process.env.NEAT_PROJECT : null;
|
|
24565
24858
|
const projectPathArg = opts.projectPath && opts.projectPath.length > 0 ? opts.projectPath : process.env.NEAT_PROJECT_PATH && process.env.NEAT_PROJECT_PATH.length > 0 ? process.env.NEAT_PROJECT_PATH : null;
|
|
24566
24859
|
const singleProject = projectArg;
|
|
24567
|
-
const singleProjectPath = singleProject && projectPathArg ?
|
|
24860
|
+
const singleProjectPath = singleProject && projectPathArg ? import_node_path79.default.resolve(projectPathArg) : null;
|
|
24568
24861
|
if (singleProject && !singleProjectPath) {
|
|
24569
24862
|
throw new Error(
|
|
24570
24863
|
`neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
|
|
@@ -24579,7 +24872,7 @@ async function startDaemon(opts = {}) {
|
|
|
24579
24872
|
);
|
|
24580
24873
|
}
|
|
24581
24874
|
}
|
|
24582
|
-
const pidPath =
|
|
24875
|
+
const pidPath = import_node_path79.default.join(home, "neatd.pid");
|
|
24583
24876
|
await writeAtomically(pidPath, `${process.pid}
|
|
24584
24877
|
`);
|
|
24585
24878
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -25051,8 +25344,8 @@ async function startDaemon(opts = {}) {
|
|
|
25051
25344
|
let registryWatcher = null;
|
|
25052
25345
|
let reloadTimer = null;
|
|
25053
25346
|
if (!singleProject) try {
|
|
25054
|
-
const regDir =
|
|
25055
|
-
const regBase =
|
|
25347
|
+
const regDir = import_node_path79.default.dirname(regPath);
|
|
25348
|
+
const regBase = import_node_path79.default.basename(regPath);
|
|
25056
25349
|
registryWatcher = (0, import_node_fs41.watch)(regDir, (_eventType, filename) => {
|
|
25057
25350
|
if (filename !== null && filename !== regBase) return;
|
|
25058
25351
|
if (reloadTimer) clearTimeout(reloadTimer);
|
|
@@ -25127,7 +25420,7 @@ init_cjs_shims();
|
|
|
25127
25420
|
var import_node_child_process2 = require("child_process");
|
|
25128
25421
|
var import_node_fs42 = require("fs");
|
|
25129
25422
|
var import_node_net = __toESM(require("net"), 1);
|
|
25130
|
-
var
|
|
25423
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
25131
25424
|
var DEFAULT_WEB_PORT = 6328;
|
|
25132
25425
|
var DEFAULT_REST_PORT = 8080;
|
|
25133
25426
|
function asValidPort(value) {
|
|
@@ -25136,11 +25429,11 @@ function asValidPort(value) {
|
|
|
25136
25429
|
}
|
|
25137
25430
|
function projectRoot() {
|
|
25138
25431
|
const fromEnv = process.env.NEAT_SCAN_PATH;
|
|
25139
|
-
return
|
|
25432
|
+
return import_node_path80.default.resolve(fromEnv && fromEnv.length > 0 ? fromEnv : process.cwd());
|
|
25140
25433
|
}
|
|
25141
25434
|
async function readDaemonPorts(root) {
|
|
25142
25435
|
try {
|
|
25143
|
-
const raw = await import_node_fs42.promises.readFile(
|
|
25436
|
+
const raw = await import_node_fs42.promises.readFile(import_node_path80.default.join(root, "neat-out", "daemon.json"), "utf8");
|
|
25144
25437
|
const parsed = JSON.parse(raw);
|
|
25145
25438
|
const ports = parsed?.ports ?? {};
|
|
25146
25439
|
return { web: asValidPort(ports.web), rest: asValidPort(ports.rest) };
|
|
@@ -25185,10 +25478,10 @@ function resolveWebPackageDir() {
|
|
|
25185
25478
|
eval("require")
|
|
25186
25479
|
);
|
|
25187
25480
|
const pkgJsonPath = req.resolve("@neat.is/web/package.json");
|
|
25188
|
-
return
|
|
25481
|
+
return import_node_path80.default.dirname(pkgJsonPath);
|
|
25189
25482
|
}
|
|
25190
25483
|
function resolveStandaloneServerEntry(webDir) {
|
|
25191
|
-
return
|
|
25484
|
+
return import_node_path80.default.join(webDir, ".next/standalone/packages/web/server.js");
|
|
25192
25485
|
}
|
|
25193
25486
|
async function pickInternalPort() {
|
|
25194
25487
|
return new Promise((resolve, reject) => {
|
|
@@ -25241,7 +25534,7 @@ async function spawnWebUI(restPort, opts = {}) {
|
|
|
25241
25534
|
NEAT_API_URL: apiUrl
|
|
25242
25535
|
};
|
|
25243
25536
|
child = (0, import_node_child_process2.spawn)(process.execPath, [serverEntry], {
|
|
25244
|
-
cwd:
|
|
25537
|
+
cwd: import_node_path80.default.dirname(serverEntry),
|
|
25245
25538
|
env,
|
|
25246
25539
|
stdio: ["ignore", "inherit", "inherit"],
|
|
25247
25540
|
detached: false
|
|
@@ -25340,13 +25633,13 @@ async function waitForListening(port, timeoutMs = 15e3) {
|
|
|
25340
25633
|
|
|
25341
25634
|
// src/version-skew.ts
|
|
25342
25635
|
init_cjs_shims();
|
|
25343
|
-
var
|
|
25636
|
+
var import_promises4 = require("timers/promises");
|
|
25344
25637
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org/neat.is/latest";
|
|
25345
25638
|
var DEFAULT_TIMEOUT_MS = 2e3;
|
|
25346
25639
|
async function fetchRegistryVersion(url, timeoutMs, fetchImpl) {
|
|
25347
25640
|
const controller = new AbortController();
|
|
25348
25641
|
let timedOut = false;
|
|
25349
|
-
const timer = (0,
|
|
25642
|
+
const timer = (0, import_promises4.setTimeout)(timeoutMs).then(() => {
|
|
25350
25643
|
timedOut = true;
|
|
25351
25644
|
controller.abort();
|
|
25352
25645
|
});
|
|
@@ -25417,14 +25710,14 @@ function localVersion() {
|
|
|
25417
25710
|
}
|
|
25418
25711
|
function neatHome3() {
|
|
25419
25712
|
if (process.env.NEAT_HOME && process.env.NEAT_HOME.length > 0) {
|
|
25420
|
-
return
|
|
25713
|
+
return import_node_path81.default.resolve(process.env.NEAT_HOME);
|
|
25421
25714
|
}
|
|
25422
25715
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
25423
|
-
return
|
|
25716
|
+
return import_node_path81.default.join(home, ".neat");
|
|
25424
25717
|
}
|
|
25425
25718
|
async function readPid() {
|
|
25426
25719
|
try {
|
|
25427
|
-
const raw = await import_node_fs43.promises.readFile(
|
|
25720
|
+
const raw = await import_node_fs43.promises.readFile(import_node_path81.default.join(neatHome3(), "neatd.pid"), "utf8");
|
|
25428
25721
|
const n = Number.parseInt(raw.trim(), 10);
|
|
25429
25722
|
return Number.isFinite(n) ? n : null;
|
|
25430
25723
|
} catch {
|