@neat.is/core 0.9.21-dev.20260923 → 0.9.21
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/index.cjs
CHANGED
|
@@ -8710,7 +8710,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8710
8710
|
});
|
|
8711
8711
|
};
|
|
8712
8712
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
8713
|
-
const
|
|
8713
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8714
8714
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8715
8715
|
let ns = nsCtx;
|
|
8716
8716
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8732,7 +8732,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8732
8732
|
switch (node.type) {
|
|
8733
8733
|
case "function_definition": {
|
|
8734
8734
|
const name = node.childForFieldName("name")?.text;
|
|
8735
|
-
if (name) push("function",
|
|
8735
|
+
if (name) push("function", join2(nsCtx, name), node);
|
|
8736
8736
|
walkBody(node, nsCtx, void 0);
|
|
8737
8737
|
return;
|
|
8738
8738
|
}
|
|
@@ -8740,7 +8740,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8740
8740
|
case "trait_declaration":
|
|
8741
8741
|
case "interface_declaration": {
|
|
8742
8742
|
const name = node.childForFieldName("name")?.text;
|
|
8743
|
-
const full = name ?
|
|
8743
|
+
const full = name ? join2(nsCtx, name) : classCtx;
|
|
8744
8744
|
if (name) push("class", full, node);
|
|
8745
8745
|
walkBody(node, nsCtx, full);
|
|
8746
8746
|
return;
|
|
@@ -8749,7 +8749,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8749
8749
|
const name = node.childForFieldName("name")?.text;
|
|
8750
8750
|
if (name) {
|
|
8751
8751
|
const kind = name === "__construct" ? "constructor" : "method";
|
|
8752
|
-
push(kind,
|
|
8752
|
+
push(kind, join2(classCtx ?? nsCtx, name), node);
|
|
8753
8753
|
}
|
|
8754
8754
|
return;
|
|
8755
8755
|
}
|
|
@@ -8775,7 +8775,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8775
8775
|
endLine: node.endPosition.row + 1
|
|
8776
8776
|
});
|
|
8777
8777
|
};
|
|
8778
|
-
const
|
|
8778
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8779
8779
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8780
8780
|
let ns = nsCtx;
|
|
8781
8781
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8783,7 +8783,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8783
8783
|
if (!child) continue;
|
|
8784
8784
|
if (child.type === "file_scoped_namespace_declaration") {
|
|
8785
8785
|
const nameNode = child.childForFieldName("name");
|
|
8786
|
-
if (nameNode) ns =
|
|
8786
|
+
if (nameNode) ns = join2(nsCtx, nameNode.text);
|
|
8787
8787
|
continue;
|
|
8788
8788
|
}
|
|
8789
8789
|
visit(child, ns, classCtx);
|
|
@@ -8797,7 +8797,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8797
8797
|
switch (node.type) {
|
|
8798
8798
|
case "namespace_declaration": {
|
|
8799
8799
|
const nameNode = node.childForFieldName("name");
|
|
8800
|
-
const ns = nameNode ?
|
|
8800
|
+
const ns = nameNode ? join2(nsCtx, nameNode.text) : nsCtx;
|
|
8801
8801
|
walkBody(node, ns, classCtx);
|
|
8802
8802
|
return;
|
|
8803
8803
|
}
|
|
@@ -8806,19 +8806,19 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8806
8806
|
case "struct_declaration":
|
|
8807
8807
|
case "record_declaration": {
|
|
8808
8808
|
const name = node.childForFieldName("name")?.text;
|
|
8809
|
-
const full = name ?
|
|
8809
|
+
const full = name ? join2(classCtx ?? nsCtx, name) : classCtx;
|
|
8810
8810
|
if (name) push("class", full, node);
|
|
8811
8811
|
walkBody(node, nsCtx, full);
|
|
8812
8812
|
return;
|
|
8813
8813
|
}
|
|
8814
8814
|
case "method_declaration": {
|
|
8815
8815
|
const name = node.childForFieldName("name")?.text;
|
|
8816
|
-
if (name) push("method",
|
|
8816
|
+
if (name) push("method", join2(classCtx ?? nsCtx, name), node);
|
|
8817
8817
|
return;
|
|
8818
8818
|
}
|
|
8819
8819
|
case "constructor_declaration": {
|
|
8820
8820
|
const name = node.childForFieldName("name")?.text;
|
|
8821
|
-
if (name) push("constructor",
|
|
8821
|
+
if (name) push("constructor", join2(classCtx ?? nsCtx, name), node);
|
|
8822
8822
|
return;
|
|
8823
8823
|
}
|
|
8824
8824
|
}
|
|
@@ -8837,7 +8837,7 @@ function collectJavaSymbolDefs(root) {
|
|
|
8837
8837
|
endLine: node.endPosition.row + 1
|
|
8838
8838
|
});
|
|
8839
8839
|
};
|
|
8840
|
-
const
|
|
8840
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8841
8841
|
let pkg;
|
|
8842
8842
|
for (let i = 0; i < root.namedChildCount; i++) {
|
|
8843
8843
|
const child = root.namedChild(i);
|
|
@@ -8863,19 +8863,19 @@ function collectJavaSymbolDefs(root) {
|
|
|
8863
8863
|
case "enum_declaration":
|
|
8864
8864
|
case "record_declaration": {
|
|
8865
8865
|
const name = node.childForFieldName("name")?.text;
|
|
8866
|
-
const full = name ?
|
|
8866
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
8867
8867
|
if (name) push("class", full, node);
|
|
8868
8868
|
walkBody(node, full);
|
|
8869
8869
|
return;
|
|
8870
8870
|
}
|
|
8871
8871
|
case "method_declaration": {
|
|
8872
8872
|
const name = node.childForFieldName("name")?.text;
|
|
8873
|
-
if (name) push("method",
|
|
8873
|
+
if (name) push("method", join2(classCtx ?? pkg, name), node);
|
|
8874
8874
|
return;
|
|
8875
8875
|
}
|
|
8876
8876
|
case "constructor_declaration": {
|
|
8877
8877
|
const name = node.childForFieldName("name")?.text;
|
|
8878
|
-
if (name) push("constructor",
|
|
8878
|
+
if (name) push("constructor", join2(classCtx ?? pkg, name), node);
|
|
8879
8879
|
return;
|
|
8880
8880
|
}
|
|
8881
8881
|
}
|
|
@@ -8894,7 +8894,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8894
8894
|
endLine: node.endPosition.row + 1
|
|
8895
8895
|
});
|
|
8896
8896
|
};
|
|
8897
|
-
const
|
|
8897
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8898
8898
|
const firstChildOfType2 = (node, types) => {
|
|
8899
8899
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
8900
8900
|
const child = node.namedChild(i);
|
|
@@ -8923,7 +8923,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8923
8923
|
case "class_declaration":
|
|
8924
8924
|
case "object_declaration": {
|
|
8925
8925
|
const name = nameOf(node, "type_identifier");
|
|
8926
|
-
const full = name ?
|
|
8926
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
8927
8927
|
if (name) push("class", full, node);
|
|
8928
8928
|
const body = bodyOf(node);
|
|
8929
8929
|
if (body) walkChildren(body, full);
|
|
@@ -8931,20 +8931,20 @@ function collectKotlinSymbolDefs(root) {
|
|
|
8931
8931
|
}
|
|
8932
8932
|
case "companion_object": {
|
|
8933
8933
|
const name = nameOf(node, "type_identifier");
|
|
8934
|
-
const full = name ?
|
|
8934
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx ?? pkg;
|
|
8935
8935
|
const body = bodyOf(node);
|
|
8936
8936
|
if (body) walkChildren(body, full);
|
|
8937
8937
|
return;
|
|
8938
8938
|
}
|
|
8939
8939
|
case "function_declaration": {
|
|
8940
8940
|
const name = nameOf(node, "simple_identifier");
|
|
8941
|
-
if (name) push(classCtx ? "method" : "function",
|
|
8941
|
+
if (name) push(classCtx ? "method" : "function", join2(classCtx ?? pkg, name), node);
|
|
8942
8942
|
return;
|
|
8943
8943
|
}
|
|
8944
8944
|
case "secondary_constructor": {
|
|
8945
8945
|
if (classCtx) {
|
|
8946
8946
|
const typeName = classCtx.slice(classCtx.lastIndexOf(".") + 1);
|
|
8947
|
-
push("constructor",
|
|
8947
|
+
push("constructor", join2(classCtx, typeName), node);
|
|
8948
8948
|
}
|
|
8949
8949
|
return;
|
|
8950
8950
|
}
|
|
@@ -8964,14 +8964,14 @@ function collectRustSymbolDefs(root) {
|
|
|
8964
8964
|
endLine: node.endPosition.row + 1
|
|
8965
8965
|
});
|
|
8966
8966
|
};
|
|
8967
|
-
const
|
|
8967
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
8968
8968
|
const walkTypeBody = (body, typeCtx) => {
|
|
8969
8969
|
for (let i = 0; i < body.namedChildCount; i++) {
|
|
8970
8970
|
const child = body.namedChild(i);
|
|
8971
8971
|
if (!child) continue;
|
|
8972
8972
|
if (child.type === "function_item" || child.type === "function_signature_item") {
|
|
8973
8973
|
const name = child.childForFieldName("name")?.text;
|
|
8974
|
-
if (name) push("method",
|
|
8974
|
+
if (name) push("method", join2(typeCtx, name), child);
|
|
8975
8975
|
}
|
|
8976
8976
|
}
|
|
8977
8977
|
};
|
|
@@ -8985,7 +8985,7 @@ function collectRustSymbolDefs(root) {
|
|
|
8985
8985
|
switch (node.type) {
|
|
8986
8986
|
case "mod_item": {
|
|
8987
8987
|
const name = node.childForFieldName("name")?.text;
|
|
8988
|
-
const full = name ?
|
|
8988
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
8989
8989
|
const body = node.childForFieldName("body");
|
|
8990
8990
|
if (body) walkChildren(body, full);
|
|
8991
8991
|
return;
|
|
@@ -8993,12 +8993,12 @@ function collectRustSymbolDefs(root) {
|
|
|
8993
8993
|
case "struct_item":
|
|
8994
8994
|
case "enum_item": {
|
|
8995
8995
|
const name = node.childForFieldName("name")?.text;
|
|
8996
|
-
if (name) push("class",
|
|
8996
|
+
if (name) push("class", join2(modCtx, name), node);
|
|
8997
8997
|
return;
|
|
8998
8998
|
}
|
|
8999
8999
|
case "trait_item": {
|
|
9000
9000
|
const name = node.childForFieldName("name")?.text;
|
|
9001
|
-
const full = name ?
|
|
9001
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
9002
9002
|
if (name) push("class", full, node);
|
|
9003
9003
|
const body = node.childForFieldName("body");
|
|
9004
9004
|
if (body && full) walkTypeBody(body, full);
|
|
@@ -9006,14 +9006,14 @@ function collectRustSymbolDefs(root) {
|
|
|
9006
9006
|
}
|
|
9007
9007
|
case "impl_item": {
|
|
9008
9008
|
const typeName = node.childForFieldName("type")?.text;
|
|
9009
|
-
const full = typeName ?
|
|
9009
|
+
const full = typeName ? join2(modCtx, typeName) : modCtx;
|
|
9010
9010
|
const body = node.childForFieldName("body");
|
|
9011
9011
|
if (body && full) walkTypeBody(body, full);
|
|
9012
9012
|
return;
|
|
9013
9013
|
}
|
|
9014
9014
|
case "function_item": {
|
|
9015
9015
|
const name = node.childForFieldName("name")?.text;
|
|
9016
|
-
if (name) push("function",
|
|
9016
|
+
if (name) push("function", join2(modCtx, name), node);
|
|
9017
9017
|
return;
|
|
9018
9018
|
}
|
|
9019
9019
|
}
|
|
@@ -9032,7 +9032,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9032
9032
|
endLine: node.endPosition.row + 1
|
|
9033
9033
|
});
|
|
9034
9034
|
};
|
|
9035
|
-
const
|
|
9035
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
9036
9036
|
const DECLARATOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
9037
9037
|
"function_declarator",
|
|
9038
9038
|
"pointer_declarator",
|
|
@@ -9058,7 +9058,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9058
9058
|
return void 0;
|
|
9059
9059
|
};
|
|
9060
9060
|
const classify = (nameText, prefix, enclosingClass) => {
|
|
9061
|
-
const qualname =
|
|
9061
|
+
const qualname = join2(prefix, nameText);
|
|
9062
9062
|
let className;
|
|
9063
9063
|
let memberName;
|
|
9064
9064
|
const idx = nameText.lastIndexOf("::");
|
|
@@ -9087,7 +9087,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9087
9087
|
switch (node.type) {
|
|
9088
9088
|
case "namespace_definition": {
|
|
9089
9089
|
const name = node.childForFieldName("name")?.text;
|
|
9090
|
-
const newPrefix = name ?
|
|
9090
|
+
const newPrefix = name ? join2(prefix, name) : prefix;
|
|
9091
9091
|
const body = node.childForFieldName("body");
|
|
9092
9092
|
if (body) walkChildren(body, newPrefix, void 0);
|
|
9093
9093
|
return;
|
|
@@ -9095,7 +9095,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9095
9095
|
case "class_specifier":
|
|
9096
9096
|
case "struct_specifier": {
|
|
9097
9097
|
const name = node.childForFieldName("name")?.text;
|
|
9098
|
-
const full = name ?
|
|
9098
|
+
const full = name ? join2(prefix, name) : prefix;
|
|
9099
9099
|
if (name) push("class", full, node);
|
|
9100
9100
|
const body = node.childForFieldName("body");
|
|
9101
9101
|
if (body && name) walkChildren(body, full, name);
|
|
@@ -16471,7 +16471,7 @@ function startPersistLoop(graph, outPath, opts = {}) {
|
|
|
16471
16471
|
init_cjs_shims();
|
|
16472
16472
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
16473
16473
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
16474
|
-
var
|
|
16474
|
+
var import_types101 = require("@neat.is/types");
|
|
16475
16475
|
|
|
16476
16476
|
// src/extend/index.ts
|
|
16477
16477
|
init_cjs_shims();
|
|
@@ -17701,7 +17701,7 @@ var INTENT_RULES = [
|
|
|
17701
17701
|
},
|
|
17702
17702
|
{
|
|
17703
17703
|
intent: "blast-radius",
|
|
17704
|
-
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/
|
|
17704
|
+
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/
|
|
17705
17705
|
},
|
|
17706
17706
|
{
|
|
17707
17707
|
intent: "divergence",
|
|
@@ -17713,11 +17713,11 @@ var INTENT_RULES = [
|
|
|
17713
17713
|
},
|
|
17714
17714
|
{
|
|
17715
17715
|
intent: "observed",
|
|
17716
|
-
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually
|
|
17716
|
+
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually|really\s+call\w*|observed|runtime\s+traffic|slow|latency|p95|timing)\b/
|
|
17717
17717
|
},
|
|
17718
17718
|
{
|
|
17719
17719
|
intent: "dependencies",
|
|
17720
|
-
test: /\b(depend\w*|calls?|uses?|imports?|relies\s+on|needs
|
|
17720
|
+
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/
|
|
17721
17721
|
}
|
|
17722
17722
|
];
|
|
17723
17723
|
function classifyIntent(question) {
|
|
@@ -17884,7 +17884,25 @@ var INTENT_WORDS = /* @__PURE__ */ new Set([
|
|
|
17884
17884
|
"rely",
|
|
17885
17885
|
"needs",
|
|
17886
17886
|
"need",
|
|
17887
|
-
"sync"
|
|
17887
|
+
"sync",
|
|
17888
|
+
"talk",
|
|
17889
|
+
"talks",
|
|
17890
|
+
"connect",
|
|
17891
|
+
"connects",
|
|
17892
|
+
"hit",
|
|
17893
|
+
"hits",
|
|
17894
|
+
"read",
|
|
17895
|
+
"reads",
|
|
17896
|
+
"write",
|
|
17897
|
+
"writes",
|
|
17898
|
+
"consumer",
|
|
17899
|
+
"consumers",
|
|
17900
|
+
"caller",
|
|
17901
|
+
"callers",
|
|
17902
|
+
"slow",
|
|
17903
|
+
"latency",
|
|
17904
|
+
"p95",
|
|
17905
|
+
"timing"
|
|
17888
17906
|
]);
|
|
17889
17907
|
function tokens(input) {
|
|
17890
17908
|
const spaced = input.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
@@ -17908,6 +17926,13 @@ function idBody(id) {
|
|
|
17908
17926
|
const colon = id.indexOf(":");
|
|
17909
17927
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
17910
17928
|
}
|
|
17929
|
+
var TYPE_NOUNS = [
|
|
17930
|
+
{ nouns: ["database", "db", "table"], type: import_types62.NodeType.DatabaseNode },
|
|
17931
|
+
{ nouns: ["service", "api", "backend"], type: import_types62.NodeType.ServiceNode },
|
|
17932
|
+
{ nouns: ["route", "endpoint"], type: import_types62.NodeType.RouteNode },
|
|
17933
|
+
{ nouns: ["file"], type: import_types62.NodeType.FileNode },
|
|
17934
|
+
{ nouns: ["config"], type: import_types62.NodeType.ConfigNode }
|
|
17935
|
+
];
|
|
17911
17936
|
var EMBED_MIN_SCORE = 0.35;
|
|
17912
17937
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
17913
17938
|
const qTokens = queryTokens(question);
|
|
@@ -17915,6 +17940,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17915
17940
|
const best = /* @__PURE__ */ new Map();
|
|
17916
17941
|
const consider = (cand) => {
|
|
17917
17942
|
const cur = best.get(cand.nodeId);
|
|
17943
|
+
if (cur?.via === "id" && cand.via === "embedding") return;
|
|
17918
17944
|
if (!cur || cand.score > cur.score) best.set(cand.nodeId, cand);
|
|
17919
17945
|
};
|
|
17920
17946
|
graph.forEachNode((id, attrs) => {
|
|
@@ -17924,12 +17950,12 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17924
17950
|
const body = idBody(id);
|
|
17925
17951
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
17926
17952
|
if (labelTokens.size === 0) return;
|
|
17927
|
-
let
|
|
17928
|
-
for (const t of qTokens) if (labelTokens.has(t))
|
|
17953
|
+
let matched2 = 0;
|
|
17954
|
+
for (const t of qTokens) if (labelTokens.has(t)) matched2 += 1;
|
|
17929
17955
|
const named2 = body.length >= 2 && normalized.includes(body.toLowerCase()) || name.length >= 2 && normalized.includes(name.toLowerCase());
|
|
17930
|
-
if (
|
|
17931
|
-
const coverage = qTokens.length > 0 ?
|
|
17932
|
-
const via = named2 ? "id" :
|
|
17956
|
+
if (matched2 === 0 && !named2) return;
|
|
17957
|
+
const coverage = qTokens.length > 0 ? matched2 / qTokens.length : 0;
|
|
17958
|
+
const via = named2 ? "id" : matched2 > 0 && tokens(name).some((t) => qTokens.includes(t)) ? "label" : "token";
|
|
17933
17959
|
const score = named2 ? Math.max(0.9, coverage) : Math.min(0.85, 0.3 + 0.7 * coverage);
|
|
17934
17960
|
consider({ nodeId: id, label: name, via, score: Math.min(1, score) });
|
|
17935
17961
|
});
|
|
@@ -17939,6 +17965,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17939
17965
|
if (res.provider !== "substring") {
|
|
17940
17966
|
for (const m of res.matches) {
|
|
17941
17967
|
if (m.node.type === import_types62.NodeType.FrontierNode) continue;
|
|
17968
|
+
if (!graph.hasNode(m.node.id)) continue;
|
|
17942
17969
|
const already = best.get(m.node.id);
|
|
17943
17970
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
17944
17971
|
consider({
|
|
@@ -17952,10 +17979,31 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17952
17979
|
} catch {
|
|
17953
17980
|
}
|
|
17954
17981
|
}
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17982
|
+
if (best.size === 0) {
|
|
17983
|
+
const words = new Set(tokens(question));
|
|
17984
|
+
const kind = TYPE_NOUNS.find((entry) => entry.nouns.some((noun) => words.has(noun)));
|
|
17985
|
+
if (kind) {
|
|
17986
|
+
const ids = graph.filterNodes((_id, attrs) => attrs.type === kind.type).sort();
|
|
17987
|
+
if (ids.length > 1) {
|
|
17988
|
+
return { matched: [], ambiguousType: { noun: kind.nouns.find((noun) => words.has(noun)), ids } };
|
|
17989
|
+
}
|
|
17990
|
+
if (ids.length === 1) {
|
|
17991
|
+
const id = ids[0];
|
|
17992
|
+
return { matched: [{ nodeId: id, label: nodeName(graph.getNodeAttributes(id)), via: "type", score: 0.6 }].slice(0, maxNodes) };
|
|
17993
|
+
}
|
|
17994
|
+
return { matched: [] };
|
|
17995
|
+
}
|
|
17996
|
+
}
|
|
17997
|
+
const viaRank = { id: 4, label: 3, token: 2, type: 1, embedding: 0 };
|
|
17998
|
+
const ranked = [...best.values()].sort(
|
|
17999
|
+
(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)
|
|
18000
|
+
);
|
|
18001
|
+
const primary = ranked[0];
|
|
18002
|
+
const primaryType = primary && graph.getNodeAttributes(primary.nodeId).type;
|
|
18003
|
+
const matched = ranked.filter(
|
|
18004
|
+
(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
|
|
17958
18005
|
).slice(0, maxNodes).map((s) => ({ nodeId: s.nodeId, label: s.label, via: s.via, score: Number(s.score.toFixed(3)) }));
|
|
18006
|
+
return { matched };
|
|
17959
18007
|
}
|
|
17960
18008
|
function incidentsForNode(nodeId, incidents) {
|
|
17961
18009
|
if (!incidents || incidents.length === 0) return [];
|
|
@@ -18047,6 +18095,23 @@ function buildBlastSection(graph, node) {
|
|
|
18047
18095
|
facts
|
|
18048
18096
|
};
|
|
18049
18097
|
}
|
|
18098
|
+
function buildDatabaseCallersSection(graph, node) {
|
|
18099
|
+
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18100
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types62.NodeType.ServiceNode) return false;
|
|
18101
|
+
return item.path.slice(1, -1).every((id) => {
|
|
18102
|
+
const type = graph.getNodeAttributes(id).type;
|
|
18103
|
+
return type === import_types62.NodeType.FileNode || type === import_types62.NodeType.SymbolNode;
|
|
18104
|
+
});
|
|
18105
|
+
});
|
|
18106
|
+
return {
|
|
18107
|
+
heading: `Services calling ${node} \u2014 ${callers.length}`,
|
|
18108
|
+
facts: callers.length > 0 ? callers.slice(0, MAX_FACTS_PER_SECTION).map((item) => ({
|
|
18109
|
+
text: `${item.nodeId} (distance ${item.distance})`,
|
|
18110
|
+
provenance: item.edgeProvenance,
|
|
18111
|
+
confidence: item.confidence
|
|
18112
|
+
})) : [{ text: `No inbound service callers found for ${node}.` }]
|
|
18113
|
+
};
|
|
18114
|
+
}
|
|
18050
18115
|
function buildIncidentsSection(node, incidents) {
|
|
18051
18116
|
const relevant = incidentsForNode(node, incidents);
|
|
18052
18117
|
if (relevant.length === 0) return null;
|
|
@@ -18073,6 +18138,29 @@ function divergenceLine(d) {
|
|
|
18073
18138
|
}
|
|
18074
18139
|
return `[${d.type}] ${d.source} \u2192 ${d.target} \u2014 ${d.reason}`;
|
|
18075
18140
|
}
|
|
18141
|
+
function runtimeEdgeState(graph) {
|
|
18142
|
+
let observed = false;
|
|
18143
|
+
let stale = false;
|
|
18144
|
+
graph.forEachEdge((_id, attrs) => {
|
|
18145
|
+
if (attrs.provenance === import_types62.Provenance.OBSERVED) observed = true;
|
|
18146
|
+
if (attrs.provenance === import_types62.Provenance.STALE) stale = true;
|
|
18147
|
+
});
|
|
18148
|
+
return { observed, stale };
|
|
18149
|
+
}
|
|
18150
|
+
function pendingRuntimeMessage(graph, divergences) {
|
|
18151
|
+
const count = divergences.filter((d) => d.type === "missing-observed").length;
|
|
18152
|
+
if (count === 0) return void 0;
|
|
18153
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18154
|
+
if (observed) return void 0;
|
|
18155
|
+
const prefix = stale ? "No current runtime observations \u2014 earlier runtime evidence is stale" : "No runtime observed yet";
|
|
18156
|
+
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.`;
|
|
18157
|
+
}
|
|
18158
|
+
function noDivergenceMessage(graph) {
|
|
18159
|
+
if (graph.order === 0) return "Graph is empty \u2014 no declared or observed dependencies to compare.";
|
|
18160
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18161
|
+
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.";
|
|
18162
|
+
return "None \u2014 declared code and observed runtime agree across the graph.";
|
|
18163
|
+
}
|
|
18076
18164
|
function buildDivergenceSection(graph, node, incidents) {
|
|
18077
18165
|
const result = computeDivergences(graph, { node, ...incidents ? { incidents } : {} });
|
|
18078
18166
|
if (result.totalAffected === 0) return null;
|
|
@@ -18089,19 +18177,28 @@ function buildDivergenceSection(graph, node, incidents) {
|
|
|
18089
18177
|
}
|
|
18090
18178
|
function buildGlobalDivergenceSection(graph, incidents) {
|
|
18091
18179
|
const result = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18180
|
+
const pending = pendingRuntimeMessage(graph, result.divergences);
|
|
18181
|
+
const visible = pending ? result.divergences.filter((d) => d.type !== "missing-observed") : result.divergences;
|
|
18182
|
+
if (visible.length === 0 && pending) {
|
|
18183
|
+
return {
|
|
18184
|
+
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18185
|
+
facts: [{ text: pending }]
|
|
18186
|
+
};
|
|
18187
|
+
}
|
|
18092
18188
|
if (result.totalAffected === 0) {
|
|
18093
18189
|
return {
|
|
18094
18190
|
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18095
|
-
facts: [{ text:
|
|
18191
|
+
facts: [{ text: noDivergenceMessage(graph) }]
|
|
18096
18192
|
};
|
|
18097
18193
|
}
|
|
18098
|
-
const facts =
|
|
18194
|
+
const facts = visible.slice(0, MAX_FACTS_PER_SECTION).map((d) => ({
|
|
18099
18195
|
text: divergenceLine(d),
|
|
18100
18196
|
confidence: d.confidence
|
|
18101
18197
|
// Composite by construction (EXTRACTED vs OBSERVED), so no single provenance.
|
|
18102
18198
|
}));
|
|
18199
|
+
if (pending && facts.length < MAX_FACTS_PER_SECTION) facts.push({ text: pending });
|
|
18103
18200
|
return {
|
|
18104
|
-
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${
|
|
18201
|
+
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${visible.length}`,
|
|
18105
18202
|
facts
|
|
18106
18203
|
};
|
|
18107
18204
|
}
|
|
@@ -18187,13 +18284,12 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18187
18284
|
});
|
|
18188
18285
|
}
|
|
18189
18286
|
const div = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18287
|
+
const pending = pendingRuntimeMessage(graph, div.divergences);
|
|
18288
|
+
const visibleCount = pending ? div.divergences.filter((d) => d.type !== "missing-observed").length : div.totalAffected;
|
|
18289
|
+
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);
|
|
18190
18290
|
sections.push({
|
|
18191
18291
|
heading: "Divergences",
|
|
18192
|
-
facts: [
|
|
18193
|
-
{
|
|
18194
|
-
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.`
|
|
18195
|
-
}
|
|
18196
|
-
]
|
|
18292
|
+
facts: [{ text: divergenceText }]
|
|
18197
18293
|
});
|
|
18198
18294
|
return sections;
|
|
18199
18295
|
}
|
|
@@ -18238,6 +18334,8 @@ function summarizeGlobal(intent, sections) {
|
|
|
18238
18334
|
const lead = sections[0];
|
|
18239
18335
|
switch (intent) {
|
|
18240
18336
|
case "divergence": {
|
|
18337
|
+
const pending = lead?.facts[0]?.text;
|
|
18338
|
+
if (pending?.startsWith("No runtime") || pending?.startsWith("No current runtime") || pending?.startsWith("Graph is empty")) return pending;
|
|
18241
18339
|
const none = lead?.facts[0]?.text.startsWith("None") ?? true;
|
|
18242
18340
|
return none ? "No divergences across the graph \u2014 declared code and observed runtime agree." : `${lead.heading} across the graph, highest-confidence first below.`;
|
|
18243
18341
|
}
|
|
@@ -18250,11 +18348,16 @@ function summarizeGlobal(intent, sections) {
|
|
|
18250
18348
|
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.`;
|
|
18251
18349
|
}
|
|
18252
18350
|
}
|
|
18253
|
-
function summarize(question, intent, matched, primary, sections, scope) {
|
|
18351
|
+
function summarize(question, intent, matched, primary, sections, scope, ambiguousType) {
|
|
18254
18352
|
if (scope === "global") {
|
|
18255
18353
|
return summarizeGlobal(intent, sections);
|
|
18256
18354
|
}
|
|
18257
18355
|
if (!primary) {
|
|
18356
|
+
if (ambiguousType) {
|
|
18357
|
+
const shown = ambiguousType.ids.slice(0, 10);
|
|
18358
|
+
const more = ambiguousType.ids.length - shown.length;
|
|
18359
|
+
return `"${ambiguousType.noun}" matches ${ambiguousType.ids.length} nodes. Name one by ID: ${shown.join(", ")}${more > 0 ? `, and ${more} more` : ""}.`;
|
|
18360
|
+
}
|
|
18258
18361
|
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.`;
|
|
18259
18362
|
}
|
|
18260
18363
|
const lead = sections[0];
|
|
@@ -18277,10 +18380,13 @@ function summarize(question, intent, matched, primary, sections, scope) {
|
|
|
18277
18380
|
core = lead ? `${lead.heading} of ${primary}.` : `${primary} has no dependents \u2014 nothing else would break if it failed.`;
|
|
18278
18381
|
break;
|
|
18279
18382
|
case "dependencies":
|
|
18280
|
-
core = lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18383
|
+
core = lead?.heading.startsWith("Services calling") ? `${lead.heading}.` : lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18281
18384
|
break;
|
|
18282
18385
|
case "observed":
|
|
18283
|
-
|
|
18386
|
+
{
|
|
18387
|
+
const observed = sections.find((s) => s.heading === "Runtime dependencies (OBSERVED)");
|
|
18388
|
+
core = observed ? `${primary} at runtime: ${observed.facts.length} OBSERVED fact${observed.facts.length === 1 ? "" : "s"}.` : `No runtime traffic OBSERVED for ${primary}.`;
|
|
18389
|
+
}
|
|
18284
18390
|
break;
|
|
18285
18391
|
case "incidents":
|
|
18286
18392
|
core = lead ? `${primary}: ${lead.heading.toLowerCase()}.` : `No incidents recorded against ${primary}.`;
|
|
@@ -18297,24 +18403,28 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18297
18403
|
const now = opts.now ?? Date.now();
|
|
18298
18404
|
const maxNodes = opts.maxNodes ?? DEFAULT_MAX_NODES;
|
|
18299
18405
|
const intent = classifyIntent(question);
|
|
18300
|
-
const
|
|
18406
|
+
const resolution = await resolveEntities(graph, question, opts.searchIndex, maxNodes);
|
|
18407
|
+
const matched = resolution.matched;
|
|
18301
18408
|
const primary = matched[0]?.nodeId;
|
|
18302
18409
|
const sections = [];
|
|
18303
18410
|
let scope;
|
|
18304
18411
|
if (primary) {
|
|
18305
18412
|
scope = "node";
|
|
18413
|
+
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);
|
|
18414
|
+
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18306
18415
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18416
|
+
if (callersQuestion && kind === "blast") continue;
|
|
18307
18417
|
const s = buildSection(kind, graph, primary, opts.incidents, now);
|
|
18308
18418
|
if (s && s.facts.length > 0) sections.push(s);
|
|
18309
18419
|
}
|
|
18310
18420
|
} else {
|
|
18311
|
-
const global = buildGlobalSections(intent, graph, opts.incidents);
|
|
18421
|
+
const global = resolution.ambiguousType ? null : buildGlobalSections(intent, graph, opts.incidents);
|
|
18312
18422
|
if (global) {
|
|
18313
18423
|
scope = "global";
|
|
18314
18424
|
for (const s of global) if (s.facts.length > 0) sections.push(s);
|
|
18315
18425
|
}
|
|
18316
18426
|
}
|
|
18317
|
-
const answer = summarize(question, intent, matched, primary, sections, scope);
|
|
18427
|
+
const answer = summarize(question, intent, matched, primary, sections, scope, resolution.ambiguousType);
|
|
18318
18428
|
const provSet = /* @__PURE__ */ new Set();
|
|
18319
18429
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18320
18430
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
@@ -20252,9 +20362,9 @@ var RESOURCE_TYPES = [
|
|
|
20252
20362
|
function isFirebaseResourceType(value) {
|
|
20253
20363
|
return RESOURCE_TYPES.includes(value);
|
|
20254
20364
|
}
|
|
20255
|
-
function buildEntriesFilter(sinceIso) {
|
|
20365
|
+
function buildEntriesFilter(sinceIso, resourceTypes = RESOURCE_TYPES) {
|
|
20256
20366
|
return [
|
|
20257
|
-
|
|
20367
|
+
`resource.type = (${resourceTypes.map((t) => `"${t}"`).join(" OR ")})`,
|
|
20258
20368
|
"httpRequest:*",
|
|
20259
20369
|
`timestamp >= "${sinceIso}"`
|
|
20260
20370
|
].join(" AND ");
|
|
@@ -20263,8 +20373,8 @@ var DEFAULT_LOOKBACK_MS = 24 * 60 * 60 * 1e3;
|
|
|
20263
20373
|
var ENTRIES_LIST_URL = "https://logging.googleapis.com/v2/entries:list";
|
|
20264
20374
|
var PAGE_SIZE = 1e3;
|
|
20265
20375
|
var MAX_PAGES = 20;
|
|
20266
|
-
async function fetchHttpRequestLogEntries(creds, sinceIso) {
|
|
20267
|
-
const filter = buildEntriesFilter(sinceIso);
|
|
20376
|
+
async function fetchHttpRequestLogEntries(creds, sinceIso, resourceTypes) {
|
|
20377
|
+
const filter = buildEntriesFilter(sinceIso, resourceTypes);
|
|
20268
20378
|
const out = [];
|
|
20269
20379
|
let pageToken;
|
|
20270
20380
|
for (let page = 0; page < MAX_PAGES; page++) {
|
|
@@ -20379,7 +20489,38 @@ function mapLogEntriesToSignals(entries) {
|
|
|
20379
20489
|
|
|
20380
20490
|
// src/connectors/firebase/resolve.ts
|
|
20381
20491
|
init_cjs_shims();
|
|
20492
|
+
var import_types72 = require("@neat.is/types");
|
|
20493
|
+
|
|
20494
|
+
// src/connectors/infer-service.ts
|
|
20495
|
+
init_cjs_shims();
|
|
20382
20496
|
var import_types71 = require("@neat.is/types");
|
|
20497
|
+
function normalizeName(name) {
|
|
20498
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
20499
|
+
}
|
|
20500
|
+
function inferServiceName(graph, resourceName, method, path79) {
|
|
20501
|
+
const wantedMethod = method.toUpperCase();
|
|
20502
|
+
const wantedPath = normalizePathTemplate(path79);
|
|
20503
|
+
const services = [];
|
|
20504
|
+
const owners = /* @__PURE__ */ new Set();
|
|
20505
|
+
graph.forEachNode((_id, attrs) => {
|
|
20506
|
+
const node = attrs;
|
|
20507
|
+
if (node.type === import_types71.NodeType.ServiceNode && typeof node.name === "string") {
|
|
20508
|
+
services.push(node.name);
|
|
20509
|
+
return;
|
|
20510
|
+
}
|
|
20511
|
+
if (node.type !== import_types71.NodeType.RouteNode) return;
|
|
20512
|
+
const route = attrs;
|
|
20513
|
+
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
20514
|
+
const routeMethod = route.method.toUpperCase();
|
|
20515
|
+
if (routeMethod === "ALL" || routeMethod === wantedMethod) owners.add(route.service);
|
|
20516
|
+
});
|
|
20517
|
+
const wanted = normalizeName(resourceName);
|
|
20518
|
+
const byName = services.find((s) => normalizeName(s) === wanted);
|
|
20519
|
+
if (byName) return byName;
|
|
20520
|
+
return owners.size === 1 ? [...owners][0] : null;
|
|
20521
|
+
}
|
|
20522
|
+
|
|
20523
|
+
// src/connectors/firebase/resolve.ts
|
|
20383
20524
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
20384
20525
|
switch (resourceType) {
|
|
20385
20526
|
case "cloud_function":
|
|
@@ -20394,7 +20535,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
20394
20535
|
const entries = [];
|
|
20395
20536
|
graph.forEachNode((_id, attrs) => {
|
|
20396
20537
|
const node = attrs;
|
|
20397
|
-
if (node.type !==
|
|
20538
|
+
if (node.type !== import_types72.NodeType.RouteNode) return;
|
|
20398
20539
|
const route = attrs;
|
|
20399
20540
|
if (route.service !== serviceName) return;
|
|
20400
20541
|
entries.push({
|
|
@@ -20418,32 +20559,38 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
20418
20559
|
}
|
|
20419
20560
|
const identity = parseFirebaseTargetName(signal.targetName);
|
|
20420
20561
|
if (!identity) return null;
|
|
20421
|
-
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap);
|
|
20422
|
-
if (!serviceName) return null;
|
|
20423
20562
|
const normalizedPath = normalizePathTemplate(identity.path);
|
|
20563
|
+
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap) ?? (serviceMap.inferServices ? inferServiceName(graph, identity.resourceName, identity.method, identity.path) : null);
|
|
20564
|
+
if (!serviceName) return null;
|
|
20424
20565
|
const match = findRoute2(routeEntriesFor(graph, serviceName), identity.method, normalizedPath);
|
|
20425
20566
|
if (!match) return null;
|
|
20426
20567
|
return {
|
|
20427
20568
|
targetNodeId: match.routeNodeId,
|
|
20428
20569
|
serviceName,
|
|
20429
|
-
edgeType:
|
|
20570
|
+
edgeType: import_types72.EdgeType.CALLS
|
|
20430
20571
|
};
|
|
20431
20572
|
};
|
|
20432
20573
|
}
|
|
20433
20574
|
|
|
20434
20575
|
// src/connectors/firebase/index.ts
|
|
20435
20576
|
var FirebaseConnector = class {
|
|
20577
|
+
constructor(opts = {}) {
|
|
20578
|
+
this.opts = opts;
|
|
20579
|
+
}
|
|
20580
|
+
opts;
|
|
20436
20581
|
provider = "firebase";
|
|
20437
20582
|
async poll(ctx) {
|
|
20438
20583
|
const creds = readFirebaseCredentials(ctx.credentials);
|
|
20439
20584
|
const sinceIso = ctx.since ?? new Date(Date.now() - DEFAULT_LOOKBACK_MS).toISOString();
|
|
20440
|
-
const entries = await fetchHttpRequestLogEntries(creds, sinceIso);
|
|
20585
|
+
const entries = await fetchHttpRequestLogEntries(creds, sinceIso, this.opts.resourceTypes);
|
|
20441
20586
|
return mapLogEntriesToSignals(entries);
|
|
20442
20587
|
}
|
|
20443
20588
|
};
|
|
20444
20589
|
function createFirebaseConnector(graph, serviceMap) {
|
|
20445
20590
|
return {
|
|
20446
|
-
connector: new FirebaseConnector(
|
|
20591
|
+
connector: new FirebaseConnector(
|
|
20592
|
+
serviceMap.excludeCloudRun ? { resourceTypes: ["cloud_function", "firebase_domain"] } : {}
|
|
20593
|
+
),
|
|
20447
20594
|
resolveTarget: createFirebaseResolveTarget(graph, serviceMap)
|
|
20448
20595
|
};
|
|
20449
20596
|
}
|
|
@@ -20453,7 +20600,7 @@ init_cjs_shims();
|
|
|
20453
20600
|
|
|
20454
20601
|
// src/connectors/cloudflare/connector.ts
|
|
20455
20602
|
init_cjs_shims();
|
|
20456
|
-
var
|
|
20603
|
+
var import_types74 = require("@neat.is/types");
|
|
20457
20604
|
|
|
20458
20605
|
// src/connectors/cloudflare/client.ts
|
|
20459
20606
|
init_cjs_shims();
|
|
@@ -20617,7 +20764,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
20617
20764
|
graph.forEachNode((id, attrs) => {
|
|
20618
20765
|
if (found) return;
|
|
20619
20766
|
const a = attrs;
|
|
20620
|
-
if (a.type ===
|
|
20767
|
+
if (a.type === import_types74.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
20621
20768
|
found = id;
|
|
20622
20769
|
}
|
|
20623
20770
|
});
|
|
@@ -20629,7 +20776,7 @@ function findMatchingRouteNode(graph, serviceName, method, path79) {
|
|
|
20629
20776
|
graph.forEachNode((id, attrs) => {
|
|
20630
20777
|
if (found) return;
|
|
20631
20778
|
const a = attrs;
|
|
20632
|
-
if (a.type !==
|
|
20779
|
+
if (a.type !== import_types74.NodeType.RouteNode || a.service !== serviceName) return;
|
|
20633
20780
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
20634
20781
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
20635
20782
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -20648,11 +20795,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20648
20795
|
};
|
|
20649
20796
|
const mapping = config.workers?.[scriptName];
|
|
20650
20797
|
if (mapping) {
|
|
20651
|
-
const wholeFileId = (0,
|
|
20798
|
+
const wholeFileId = (0, import_types74.fileId)(mapping.service, mapping.entryFile);
|
|
20652
20799
|
return {
|
|
20653
20800
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
20654
20801
|
serviceName: mapping.service,
|
|
20655
|
-
edgeType:
|
|
20802
|
+
edgeType: import_types74.EdgeType.CALLS
|
|
20656
20803
|
};
|
|
20657
20804
|
}
|
|
20658
20805
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -20661,13 +20808,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
20661
20808
|
return {
|
|
20662
20809
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
20663
20810
|
serviceName: fileNode.service,
|
|
20664
|
-
edgeType:
|
|
20811
|
+
edgeType: import_types74.EdgeType.CALLS
|
|
20665
20812
|
};
|
|
20666
20813
|
}
|
|
20667
20814
|
return {
|
|
20668
|
-
targetNodeId: (0,
|
|
20815
|
+
targetNodeId: (0, import_types74.infraId)("cloudflare-worker", scriptName),
|
|
20669
20816
|
serviceName: scriptName,
|
|
20670
|
-
edgeType:
|
|
20817
|
+
edgeType: import_types74.EdgeType.CALLS,
|
|
20671
20818
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
20672
20819
|
};
|
|
20673
20820
|
};
|
|
@@ -20863,14 +21010,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
20863
21010
|
|
|
20864
21011
|
// src/connectors/neon/resolve.ts
|
|
20865
21012
|
init_cjs_shims();
|
|
20866
|
-
var
|
|
21013
|
+
var import_types78 = require("@neat.is/types");
|
|
20867
21014
|
function createNeonResolveTarget(config) {
|
|
20868
21015
|
return (signal) => {
|
|
20869
21016
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
20870
21017
|
return {
|
|
20871
|
-
targetNodeId: (0,
|
|
21018
|
+
targetNodeId: (0, import_types78.infraId)("sql-table", signal.targetName),
|
|
20872
21019
|
serviceName: config.serviceName,
|
|
20873
|
-
edgeType:
|
|
21020
|
+
edgeType: import_types78.EdgeType.CALLS,
|
|
20874
21021
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
20875
21022
|
};
|
|
20876
21023
|
};
|
|
@@ -21051,14 +21198,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
21051
21198
|
|
|
21052
21199
|
// src/connectors/cloud-run/resolve.ts
|
|
21053
21200
|
init_cjs_shims();
|
|
21054
|
-
var
|
|
21201
|
+
var import_types82 = require("@neat.is/types");
|
|
21055
21202
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
21056
21203
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
21057
21204
|
let found = null;
|
|
21058
21205
|
graph.forEachNode((_id, attrs) => {
|
|
21059
21206
|
if (found) return;
|
|
21060
21207
|
const node = attrs;
|
|
21061
|
-
if (node.type !==
|
|
21208
|
+
if (node.type !== import_types82.NodeType.RouteNode) return;
|
|
21062
21209
|
const route = attrs;
|
|
21063
21210
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
21064
21211
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -21074,7 +21221,7 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
21074
21221
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
21075
21222
|
if (!identity) return null;
|
|
21076
21223
|
const { serviceName: gcpServiceName, method, path: path79 } = identity;
|
|
21077
|
-
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
21224
|
+
const mappedService = config.serviceMap?.[gcpServiceName] ?? (config.inferServices ? inferServiceName(graph, gcpServiceName, method, path79) ?? void 0 : void 0);
|
|
21078
21225
|
if (mappedService) {
|
|
21079
21226
|
const routeNodeId = findMatchingRouteNode2(
|
|
21080
21227
|
graph,
|
|
@@ -21083,13 +21230,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
21083
21230
|
normalizePathTemplate(path79)
|
|
21084
21231
|
);
|
|
21085
21232
|
if (routeNodeId) {
|
|
21086
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21233
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types82.EdgeType.CALLS };
|
|
21087
21234
|
}
|
|
21088
21235
|
}
|
|
21089
21236
|
return {
|
|
21090
|
-
targetNodeId: (0,
|
|
21237
|
+
targetNodeId: (0, import_types82.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
21091
21238
|
serviceName: mappedService ?? gcpServiceName,
|
|
21092
|
-
edgeType:
|
|
21239
|
+
edgeType: import_types82.EdgeType.CALLS,
|
|
21093
21240
|
ensureInfraNode: {
|
|
21094
21241
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
21095
21242
|
name: gcpServiceName,
|
|
@@ -21271,14 +21418,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
21271
21418
|
|
|
21272
21419
|
// src/connectors/gcp-lb/resolve.ts
|
|
21273
21420
|
init_cjs_shims();
|
|
21274
|
-
var
|
|
21421
|
+
var import_types86 = require("@neat.is/types");
|
|
21275
21422
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
21276
21423
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
21277
21424
|
let found = null;
|
|
21278
21425
|
graph.forEachNode((_id, attrs) => {
|
|
21279
21426
|
if (found) return;
|
|
21280
21427
|
const node = attrs;
|
|
21281
|
-
if (node.type !==
|
|
21428
|
+
if (node.type !== import_types86.NodeType.RouteNode) return;
|
|
21282
21429
|
const route = attrs;
|
|
21283
21430
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
21284
21431
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -21294,7 +21441,7 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21294
21441
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21295
21442
|
if (!identity) return null;
|
|
21296
21443
|
const { backendServiceName, method, path: path79 } = identity;
|
|
21297
|
-
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
21444
|
+
const mappedService = config.backendServiceMap?.[backendServiceName] ?? (config.inferServices ? inferServiceName(graph, backendServiceName, method, path79) ?? void 0 : void 0);
|
|
21298
21445
|
if (mappedService) {
|
|
21299
21446
|
const routeNodeId = findMatchingRouteNode3(
|
|
21300
21447
|
graph,
|
|
@@ -21303,13 +21450,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21303
21450
|
normalizePathTemplate(path79)
|
|
21304
21451
|
);
|
|
21305
21452
|
if (routeNodeId) {
|
|
21306
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21453
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types86.EdgeType.CALLS };
|
|
21307
21454
|
}
|
|
21308
21455
|
}
|
|
21309
21456
|
return {
|
|
21310
|
-
targetNodeId: (0,
|
|
21457
|
+
targetNodeId: (0, import_types86.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
21311
21458
|
serviceName: mappedService ?? backendServiceName,
|
|
21312
|
-
edgeType:
|
|
21459
|
+
edgeType: import_types86.EdgeType.CALLS,
|
|
21313
21460
|
ensureInfraNode: {
|
|
21314
21461
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
21315
21462
|
name: backendServiceName,
|
|
@@ -21350,7 +21497,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
21350
21497
|
|
|
21351
21498
|
// src/connectors/render/index.ts
|
|
21352
21499
|
init_cjs_shims();
|
|
21353
|
-
var
|
|
21500
|
+
var import_types89 = require("@neat.is/types");
|
|
21354
21501
|
|
|
21355
21502
|
// src/connectors/render/types.ts
|
|
21356
21503
|
init_cjs_shims();
|
|
@@ -21428,7 +21575,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
21428
21575
|
const out = [];
|
|
21429
21576
|
graph.forEachNode((_id, attrs) => {
|
|
21430
21577
|
const node = attrs;
|
|
21431
|
-
if (node.type !==
|
|
21578
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
21432
21579
|
const route = attrs;
|
|
21433
21580
|
if (route.service !== serviceName) return;
|
|
21434
21581
|
out.push({
|
|
@@ -21513,7 +21660,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
21513
21660
|
function createRenderResolveTarget(config) {
|
|
21514
21661
|
return (signal) => {
|
|
21515
21662
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
21516
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
21663
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types89.EdgeType.CALLS };
|
|
21517
21664
|
}
|
|
21518
21665
|
return null;
|
|
21519
21666
|
};
|
|
@@ -21651,21 +21798,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
21651
21798
|
|
|
21652
21799
|
// src/connectors/planetscale/resolve.ts
|
|
21653
21800
|
init_cjs_shims();
|
|
21654
|
-
var
|
|
21801
|
+
var import_types93 = require("@neat.is/types");
|
|
21655
21802
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
21656
21803
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
21657
21804
|
const databaseName = `${config.organization}/${config.database}`;
|
|
21658
21805
|
return (signal, _ctx) => {
|
|
21659
21806
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
21660
|
-
const tableId = (0,
|
|
21807
|
+
const tableId = (0, import_types93.infraId)("sql-table", signal.targetName);
|
|
21661
21808
|
if (graph.hasNode(tableId)) {
|
|
21662
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
21809
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types93.EdgeType.CALLS };
|
|
21663
21810
|
}
|
|
21664
|
-
const providerId = (0,
|
|
21811
|
+
const providerId = (0, import_types93.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
21665
21812
|
return {
|
|
21666
21813
|
targetNodeId: providerId,
|
|
21667
21814
|
serviceName: config.serviceName,
|
|
21668
|
-
edgeType:
|
|
21815
|
+
edgeType: import_types93.EdgeType.CALLS,
|
|
21669
21816
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
21670
21817
|
};
|
|
21671
21818
|
};
|
|
@@ -21930,7 +22077,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
21930
22077
|
|
|
21931
22078
|
// src/connectors/eas/resolve.ts
|
|
21932
22079
|
init_cjs_shims();
|
|
21933
|
-
var
|
|
22080
|
+
var import_types98 = require("@neat.is/types");
|
|
21934
22081
|
var NO_ENV2 = "unknown";
|
|
21935
22082
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
21936
22083
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -21946,8 +22093,8 @@ function configBasenamesForPhase(phase) {
|
|
|
21946
22093
|
function configNodeService(graph, configNodeId) {
|
|
21947
22094
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
21948
22095
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
21949
|
-
if (edge.type !==
|
|
21950
|
-
const parsed = (0,
|
|
22096
|
+
if (edge.type !== import_types98.EdgeType.CONFIGURED_BY) continue;
|
|
22097
|
+
const parsed = (0, import_types98.parseFileId)(edge.source);
|
|
21951
22098
|
if (parsed) return parsed.service;
|
|
21952
22099
|
}
|
|
21953
22100
|
return null;
|
|
@@ -21958,7 +22105,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
21958
22105
|
graph.forEachNode((id, attrs) => {
|
|
21959
22106
|
if (scoped) return;
|
|
21960
22107
|
const node = attrs;
|
|
21961
|
-
if (node.type !==
|
|
22108
|
+
if (node.type !== import_types98.NodeType.ConfigNode) return;
|
|
21962
22109
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
21963
22110
|
if (anyMatch === null) anyMatch = id;
|
|
21964
22111
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -21975,13 +22122,13 @@ function createEasResolveTarget(graph) {
|
|
|
21975
22122
|
if (basenames.length > 0) {
|
|
21976
22123
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
21977
22124
|
if (configNodeId) {
|
|
21978
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
22125
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types98.EdgeType.CALLS };
|
|
21979
22126
|
}
|
|
21980
22127
|
}
|
|
21981
22128
|
return {
|
|
21982
22129
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
21983
22130
|
serviceName,
|
|
21984
|
-
edgeType:
|
|
22131
|
+
edgeType: import_types98.EdgeType.CALLS
|
|
21985
22132
|
};
|
|
21986
22133
|
};
|
|
21987
22134
|
}
|
|
@@ -22469,6 +22616,9 @@ var PUSH_PROVIDER_DISPATCH = {
|
|
|
22469
22616
|
}
|
|
22470
22617
|
}
|
|
22471
22618
|
};
|
|
22619
|
+
function getPushProviderDispatch(provider) {
|
|
22620
|
+
return PUSH_PROVIDER_DISPATCH[provider];
|
|
22621
|
+
}
|
|
22472
22622
|
function isPushProvider(provider) {
|
|
22473
22623
|
return provider in PUSH_PROVIDER_DISPATCH;
|
|
22474
22624
|
}
|
|
@@ -22762,11 +22912,11 @@ function registerRoutes(scope, ctx) {
|
|
|
22762
22912
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
22763
22913
|
const parsed = [];
|
|
22764
22914
|
for (const c of candidates) {
|
|
22765
|
-
const r =
|
|
22915
|
+
const r = import_types101.DivergenceTypeSchema.safeParse(c);
|
|
22766
22916
|
if (!r.success) {
|
|
22767
22917
|
return reply.code(400).send({
|
|
22768
22918
|
error: `unknown divergence type "${c}"`,
|
|
22769
|
-
allowed:
|
|
22919
|
+
allowed: import_types101.DivergenceTypeSchema.options
|
|
22770
22920
|
});
|
|
22771
22921
|
}
|
|
22772
22922
|
parsed.push(r.data);
|
|
@@ -23162,7 +23312,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23162
23312
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
23163
23313
|
let violations = await log.readAll();
|
|
23164
23314
|
if (req.query.severity) {
|
|
23165
|
-
const sev =
|
|
23315
|
+
const sev = import_types101.PolicySeveritySchema.safeParse(req.query.severity);
|
|
23166
23316
|
if (!sev.success) {
|
|
23167
23317
|
return reply.code(400).send({
|
|
23168
23318
|
error: "invalid severity",
|
|
@@ -23201,7 +23351,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23201
23351
|
scope.post("/policies/check", async (req, reply) => {
|
|
23202
23352
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
23203
23353
|
if (!proj) return;
|
|
23204
|
-
const parsed =
|
|
23354
|
+
const parsed = import_types101.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
23205
23355
|
if (!parsed.success) {
|
|
23206
23356
|
return reply.code(400).send({
|
|
23207
23357
|
error: "invalid /policies/check body",
|
|
@@ -23523,13 +23673,13 @@ init_otel_grpc();
|
|
|
23523
23673
|
// src/daemon.ts
|
|
23524
23674
|
init_cjs_shims();
|
|
23525
23675
|
var import_node_fs41 = require("fs");
|
|
23526
|
-
var
|
|
23676
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
23527
23677
|
var import_node_module = require("module");
|
|
23528
23678
|
init_otel();
|
|
23529
23679
|
|
|
23530
23680
|
// src/hang-sensor.ts
|
|
23531
23681
|
init_cjs_shims();
|
|
23532
|
-
var
|
|
23682
|
+
var import_types102 = require("@neat.is/types");
|
|
23533
23683
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
23534
23684
|
function stageHangSurfaces(graph, incidents) {
|
|
23535
23685
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -23542,7 +23692,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
23542
23692
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
23543
23693
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
23544
23694
|
if (!hop) continue;
|
|
23545
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
23695
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types102.EdgeType.CALLS)) staged++;
|
|
23546
23696
|
}
|
|
23547
23697
|
return staged;
|
|
23548
23698
|
}
|
|
@@ -23559,6 +23709,8 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
|
|
|
23559
23709
|
|
|
23560
23710
|
// src/connectors/hosted.ts
|
|
23561
23711
|
init_cjs_shims();
|
|
23712
|
+
var import_promises = require("fs/promises");
|
|
23713
|
+
var import_node_path75 = require("path");
|
|
23562
23714
|
|
|
23563
23715
|
// src/connectors/railway/target-ref.ts
|
|
23564
23716
|
init_cjs_shims();
|
|
@@ -23605,11 +23757,14 @@ function credentialRecord(provider, cred) {
|
|
|
23605
23757
|
switch (provider) {
|
|
23606
23758
|
case "supabase":
|
|
23607
23759
|
return { managementToken: cred.accessToken };
|
|
23760
|
+
case "gcp":
|
|
23761
|
+
if (!cred.projectRef) throw new Error("gcp credential delivered without a project ref");
|
|
23762
|
+
return { projectId: cred.projectRef, accessToken: cred.accessToken };
|
|
23608
23763
|
default:
|
|
23609
23764
|
return { token: cred.accessToken };
|
|
23610
23765
|
}
|
|
23611
23766
|
}
|
|
23612
|
-
function hostedOptions(provider, summary, serviceName) {
|
|
23767
|
+
function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
23613
23768
|
switch (provider) {
|
|
23614
23769
|
case "supabase": {
|
|
23615
23770
|
const ref = summary.projectRef;
|
|
@@ -23625,10 +23780,125 @@ function hostedOptions(provider, summary, serviceName) {
|
|
|
23625
23780
|
serviceNameById: { [target.serviceId]: serviceName }
|
|
23626
23781
|
};
|
|
23627
23782
|
}
|
|
23783
|
+
case "firebase": {
|
|
23784
|
+
return { inferServices: true, excludeCloudRun: true, ...firebaseServiceMap ?? {} };
|
|
23785
|
+
}
|
|
23786
|
+
case "cloud-run":
|
|
23787
|
+
case "gcp-lb":
|
|
23788
|
+
return { inferServices: true };
|
|
23628
23789
|
default:
|
|
23629
23790
|
return null;
|
|
23630
23791
|
}
|
|
23631
23792
|
}
|
|
23793
|
+
function parseFirebaseServiceMap(raw) {
|
|
23794
|
+
if (!raw) return void 0;
|
|
23795
|
+
try {
|
|
23796
|
+
const parsed = JSON.parse(raw);
|
|
23797
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
23798
|
+
const out = {};
|
|
23799
|
+
for (const key of ["functions", "cloudRun", "hosting"]) {
|
|
23800
|
+
const group = parsed[key];
|
|
23801
|
+
if (group === void 0) continue;
|
|
23802
|
+
if (!group || typeof group !== "object" || Array.isArray(group)) return void 0;
|
|
23803
|
+
const entries = Object.entries(group);
|
|
23804
|
+
if (entries.some(([, v]) => typeof v !== "string" || v.length === 0)) return void 0;
|
|
23805
|
+
out[key] = Object.fromEntries(entries);
|
|
23806
|
+
}
|
|
23807
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
23808
|
+
} catch {
|
|
23809
|
+
return void 0;
|
|
23810
|
+
}
|
|
23811
|
+
}
|
|
23812
|
+
function pushHandlesPath(projectDir) {
|
|
23813
|
+
return (0, import_node_path75.join)(projectDir, "neat-out", "connectors-hosted.json");
|
|
23814
|
+
}
|
|
23815
|
+
async function readPushHandles(projectDir) {
|
|
23816
|
+
try {
|
|
23817
|
+
const parsed = JSON.parse(await (0, import_promises.readFile)(pushHandlesPath(projectDir), "utf8"));
|
|
23818
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
23819
|
+
} catch {
|
|
23820
|
+
return {};
|
|
23821
|
+
}
|
|
23822
|
+
}
|
|
23823
|
+
async function writePushHandle(projectDir, provider, handle) {
|
|
23824
|
+
const path79 = pushHandlesPath(projectDir);
|
|
23825
|
+
const handles = await readPushHandles(projectDir);
|
|
23826
|
+
handles[provider] = handle;
|
|
23827
|
+
await (0, import_promises.mkdir)((0, import_node_path75.dirname)(path79), { recursive: true });
|
|
23828
|
+
const tmp = `${path79}.${process.pid}.tmp`;
|
|
23829
|
+
await (0, import_promises.writeFile)(tmp, `${JSON.stringify(handles, null, 2)}
|
|
23830
|
+
`, "utf8");
|
|
23831
|
+
await (0, import_promises.rename)(tmp, path79);
|
|
23832
|
+
}
|
|
23833
|
+
function pushCredentialRecord(provider, cred, deps) {
|
|
23834
|
+
switch (provider) {
|
|
23835
|
+
case "vercel":
|
|
23836
|
+
return { token: cred.accessToken, otelToken: deps.otelToken ?? deps.daemonToken };
|
|
23837
|
+
default:
|
|
23838
|
+
return { token: cred.accessToken };
|
|
23839
|
+
}
|
|
23840
|
+
}
|
|
23841
|
+
function hostedPushOptions(provider, summary, deps) {
|
|
23842
|
+
switch (provider) {
|
|
23843
|
+
case "vercel": {
|
|
23844
|
+
if (!deps.publicUrl) {
|
|
23845
|
+
return { skip: "no public URL for this daemon (NEAT_PUBLIC_URL) \u2014 a drain has nowhere to deliver" };
|
|
23846
|
+
}
|
|
23847
|
+
if (!summary.projectRef) return { skip: "no Vercel team selected yet \u2014 drains are team-scoped" };
|
|
23848
|
+
const endpoint2 = `${deps.publicUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
23849
|
+
return { options: { teamId: summary.projectRef, endpoint: endpoint2 }, endpoint: endpoint2 };
|
|
23850
|
+
}
|
|
23851
|
+
default:
|
|
23852
|
+
return { skip: "no hosted option mapping for this push provider" };
|
|
23853
|
+
}
|
|
23854
|
+
}
|
|
23855
|
+
async function provisionHostedPushProvider(summary, dispatch, input) {
|
|
23856
|
+
const { deps, projectDir, onSkip, onProvisioned } = input;
|
|
23857
|
+
const provider = summary.provider;
|
|
23858
|
+
const mapped = hostedPushOptions(provider, summary, deps);
|
|
23859
|
+
if ("skip" in mapped) {
|
|
23860
|
+
onSkip?.(provider, mapped.skip);
|
|
23861
|
+
return;
|
|
23862
|
+
}
|
|
23863
|
+
let cred;
|
|
23864
|
+
try {
|
|
23865
|
+
cred = await cpGet(
|
|
23866
|
+
`/internal/projects/${deps.projectId}/connections/${provider}/credential`,
|
|
23867
|
+
deps
|
|
23868
|
+
);
|
|
23869
|
+
} catch (err) {
|
|
23870
|
+
onSkip?.(provider, `credential delivery failed \u2014 ${err.message}`);
|
|
23871
|
+
return;
|
|
23872
|
+
}
|
|
23873
|
+
const credentials = pushCredentialRecord(provider, cred, deps);
|
|
23874
|
+
const existing = (await readPushHandles(projectDir))[provider];
|
|
23875
|
+
const alreadyProvisioned = existing !== void 0 && existing.endpoint === mapped.endpoint;
|
|
23876
|
+
const options = alreadyProvisioned ? { ...mapped.options, ...existing.options } : mapped.options;
|
|
23877
|
+
const seam = deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {};
|
|
23878
|
+
const validation = await dispatch.validate({ credentials, options, ...seam });
|
|
23879
|
+
if (!validation.ok) {
|
|
23880
|
+
onSkip?.(provider, `drain delivery test failed \u2014 ${validation.reason}`);
|
|
23881
|
+
return;
|
|
23882
|
+
}
|
|
23883
|
+
if (alreadyProvisioned) {
|
|
23884
|
+
onProvisioned?.(provider, "drain already provisioned \u2014 delivery re-validated");
|
|
23885
|
+
return;
|
|
23886
|
+
}
|
|
23887
|
+
const result = await dispatch.provision({ credentials, options, ...seam });
|
|
23888
|
+
if (!result.ok) {
|
|
23889
|
+
onSkip?.(provider, `drain provisioning failed \u2014 ${result.reason}`);
|
|
23890
|
+
return;
|
|
23891
|
+
}
|
|
23892
|
+
await writePushHandle(projectDir, provider, {
|
|
23893
|
+
endpoint: mapped.endpoint,
|
|
23894
|
+
options: result.options ?? {},
|
|
23895
|
+
provisionedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23896
|
+
});
|
|
23897
|
+
onProvisioned?.(provider, result.note);
|
|
23898
|
+
}
|
|
23899
|
+
var HOSTED_CONNECTORS_FOR = {
|
|
23900
|
+
gcp: ["firebase", "cloud-run", "gcp-lb"]
|
|
23901
|
+
};
|
|
23632
23902
|
function createHostedCredentialSource(provider, deps) {
|
|
23633
23903
|
let cached = null;
|
|
23634
23904
|
return async () => {
|
|
@@ -23657,40 +23927,50 @@ async function startHostedConnectors(input) {
|
|
|
23657
23927
|
if (!Array.isArray(connections)) return () => {
|
|
23658
23928
|
};
|
|
23659
23929
|
const stops = [];
|
|
23930
|
+
const lookupPush = input.pushDispatch ?? getPushProviderDispatch;
|
|
23660
23931
|
for (const c of connections) {
|
|
23661
|
-
const
|
|
23662
|
-
if (
|
|
23663
|
-
|
|
23664
|
-
continue;
|
|
23665
|
-
}
|
|
23666
|
-
if (c.needsProjectSelection || !c.projectRef) {
|
|
23667
|
-
onSkip?.(c.provider, "no project selected yet \u2014 not pullable");
|
|
23668
|
-
continue;
|
|
23669
|
-
}
|
|
23670
|
-
const options = hostedOptions(c.provider, c, project);
|
|
23671
|
-
if (!options) {
|
|
23672
|
-
onSkip?.(c.provider, "no hosted option mapping for this provider");
|
|
23932
|
+
const push = lookupPush(c.provider);
|
|
23933
|
+
if (push) {
|
|
23934
|
+
await provisionHostedPushProvider(c, push, input);
|
|
23673
23935
|
continue;
|
|
23674
23936
|
}
|
|
23675
|
-
|
|
23676
|
-
|
|
23677
|
-
|
|
23678
|
-
|
|
23679
|
-
|
|
23680
|
-
|
|
23937
|
+
const credentialSource = createHostedCredentialSource(c.provider, deps);
|
|
23938
|
+
for (const name of HOSTED_CONNECTORS_FOR[c.provider] ?? [c.provider]) {
|
|
23939
|
+
const dispatch = PROVIDER_DISPATCH[name];
|
|
23940
|
+
if (!dispatch) {
|
|
23941
|
+
onSkip?.(name, "no pull connector for this provider");
|
|
23942
|
+
continue;
|
|
23943
|
+
}
|
|
23944
|
+
if (c.needsProjectSelection || !c.projectRef) {
|
|
23945
|
+
onSkip?.(name, "no project selected yet \u2014 not pullable");
|
|
23946
|
+
continue;
|
|
23947
|
+
}
|
|
23948
|
+
const options = hostedOptions(name, c, project, input.firebaseServiceMap);
|
|
23949
|
+
if (!options) {
|
|
23950
|
+
onSkip?.(name, "no hosted option mapping for this provider");
|
|
23951
|
+
continue;
|
|
23952
|
+
}
|
|
23953
|
+
let built;
|
|
23954
|
+
try {
|
|
23955
|
+
built = dispatch.build(graph, options);
|
|
23956
|
+
} catch (err) {
|
|
23957
|
+
onSkip?.(name, err.message);
|
|
23958
|
+
continue;
|
|
23959
|
+
}
|
|
23960
|
+
stops.push(
|
|
23961
|
+
startLoop(
|
|
23962
|
+
built.connector,
|
|
23963
|
+
{ projectDir, project, credentials: {}, ...errorsPath ? { errorsPath } : {} },
|
|
23964
|
+
graph,
|
|
23965
|
+
built.resolveTarget,
|
|
23966
|
+
{
|
|
23967
|
+
connectorId: `hosted:${name}`,
|
|
23968
|
+
// The credential is fetched by the CONNECTION's provider (`gcp`), not the connector's name.
|
|
23969
|
+
refreshCredentials: credentialSource
|
|
23970
|
+
}
|
|
23971
|
+
)
|
|
23972
|
+
);
|
|
23681
23973
|
}
|
|
23682
|
-
stops.push(
|
|
23683
|
-
startLoop(
|
|
23684
|
-
built.connector,
|
|
23685
|
-
{ projectDir, project, credentials: {}, ...errorsPath ? { errorsPath } : {} },
|
|
23686
|
-
graph,
|
|
23687
|
-
built.resolveTarget,
|
|
23688
|
-
{
|
|
23689
|
-
connectorId: `hosted:${c.provider}`,
|
|
23690
|
-
refreshCredentials: createHostedCredentialSource(c.provider, deps)
|
|
23691
|
-
}
|
|
23692
|
-
)
|
|
23693
|
-
);
|
|
23694
23974
|
}
|
|
23695
23975
|
return () => {
|
|
23696
23976
|
for (const stop of stops) stop();
|
|
@@ -23704,10 +23984,18 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23704
23984
|
if (!cpUrl || !projectId || !daemonToken) return () => {
|
|
23705
23985
|
};
|
|
23706
23986
|
return startHostedConnectors({
|
|
23707
|
-
deps: {
|
|
23987
|
+
deps: {
|
|
23988
|
+
cpUrl,
|
|
23989
|
+
projectId,
|
|
23990
|
+
daemonToken,
|
|
23991
|
+
...env.NEAT_PUBLIC_URL ? { publicUrl: env.NEAT_PUBLIC_URL } : {},
|
|
23992
|
+
...env.NEAT_OTEL_TOKEN ? { otelToken: env.NEAT_OTEL_TOKEN } : {},
|
|
23993
|
+
...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
|
|
23994
|
+
},
|
|
23708
23995
|
graph: input.graph,
|
|
23709
23996
|
projectDir: input.projectDir,
|
|
23710
23997
|
project: input.project,
|
|
23998
|
+
...parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) ? { firebaseServiceMap: parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) } : {},
|
|
23711
23999
|
...input.errorsPath ? { errorsPath: input.errorsPath } : {},
|
|
23712
24000
|
...input.onSkip ? { onSkip: input.onSkip } : {}
|
|
23713
24001
|
});
|
|
@@ -23716,8 +24004,8 @@ async function maybeStartHostedConnectors(input) {
|
|
|
23716
24004
|
// src/connectors/hosted-repos.ts
|
|
23717
24005
|
init_cjs_shims();
|
|
23718
24006
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
23719
|
-
var
|
|
23720
|
-
var
|
|
24007
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
24008
|
+
var import_promises2 = require("fs/promises");
|
|
23721
24009
|
var CP_REQUEST_TIMEOUT_MS2 = 1e4;
|
|
23722
24010
|
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
23723
24011
|
var CLONE_TIMEOUT_MS = 5 * 6e4;
|
|
@@ -23787,7 +24075,9 @@ async function syncOneRepo(r, input) {
|
|
|
23787
24075
|
const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
|
|
23788
24076
|
let dir;
|
|
23789
24077
|
try {
|
|
23790
|
-
dir = await (0,
|
|
24078
|
+
dir = await (0, import_promises2.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
24079
|
+
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
24080
|
+
});
|
|
23791
24081
|
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
23792
24082
|
const extracted = await extract(graph, dir);
|
|
23793
24083
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
@@ -23805,7 +24095,7 @@ async function syncOneRepo(r, input) {
|
|
|
23805
24095
|
}).catch(() => {
|
|
23806
24096
|
});
|
|
23807
24097
|
} finally {
|
|
23808
|
-
if (dir) await (0,
|
|
24098
|
+
if (dir) await (0, import_promises2.rm)(dir, { recursive: true, force: true }).catch(() => {
|
|
23809
24099
|
});
|
|
23810
24100
|
}
|
|
23811
24101
|
}
|
|
@@ -23815,23 +24105,26 @@ async function runRepoSyncPass(input) {
|
|
|
23815
24105
|
repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
23816
24106
|
} catch (err) {
|
|
23817
24107
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
23818
|
-
return;
|
|
24108
|
+
return false;
|
|
23819
24109
|
}
|
|
23820
|
-
if (!Array.isArray(repos)) return;
|
|
24110
|
+
if (!Array.isArray(repos)) return false;
|
|
23821
24111
|
for (const r of repos) {
|
|
23822
|
-
if (!needsSync(r)) continue;
|
|
24112
|
+
if (!input.forceResync && !needsSync(r)) continue;
|
|
23823
24113
|
await syncOneRepo(r, input);
|
|
23824
24114
|
}
|
|
24115
|
+
return true;
|
|
23825
24116
|
}
|
|
23826
24117
|
async function startRepoSync(input) {
|
|
23827
24118
|
const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
|
|
23828
24119
|
let stopped = false;
|
|
23829
24120
|
let running = false;
|
|
24121
|
+
let bootResyncDone = false;
|
|
23830
24122
|
const tick = async () => {
|
|
23831
24123
|
if (stopped || running) return;
|
|
23832
24124
|
running = true;
|
|
23833
24125
|
try {
|
|
23834
|
-
await runRepoSyncPass(input);
|
|
24126
|
+
const listed = await runRepoSyncPass({ ...input, forceResync: !bootResyncDone });
|
|
24127
|
+
if (listed) bootResyncDone = true;
|
|
23835
24128
|
} finally {
|
|
23836
24129
|
running = false;
|
|
23837
24130
|
}
|
|
@@ -24215,7 +24508,7 @@ function mapWorkloadsToSignals(deployments, pods, config) {
|
|
|
24215
24508
|
|
|
24216
24509
|
// src/connectors/kubernetes/resolve.ts
|
|
24217
24510
|
init_cjs_shims();
|
|
24218
|
-
var
|
|
24511
|
+
var import_types104 = require("@neat.is/types");
|
|
24219
24512
|
var NO_ENV3 = "unknown";
|
|
24220
24513
|
function createK8sResolveTarget(graph) {
|
|
24221
24514
|
return (signal) => {
|
|
@@ -24226,28 +24519,28 @@ function createK8sResolveTarget(graph) {
|
|
|
24226
24519
|
return {
|
|
24227
24520
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
24228
24521
|
serviceName,
|
|
24229
|
-
edgeType:
|
|
24522
|
+
edgeType: import_types104.EdgeType.CALLS
|
|
24230
24523
|
};
|
|
24231
24524
|
};
|
|
24232
24525
|
}
|
|
24233
24526
|
|
|
24234
24527
|
// src/connectors/kubernetes/substrate.ts
|
|
24235
24528
|
init_cjs_shims();
|
|
24236
|
-
var
|
|
24529
|
+
var import_promises3 = require("fs/promises");
|
|
24237
24530
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
24238
|
-
var
|
|
24531
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
24239
24532
|
function defaultHome() {
|
|
24240
24533
|
const override = process.env.NEAT_HOME;
|
|
24241
|
-
if (override && override.length > 0) return
|
|
24242
|
-
return
|
|
24534
|
+
if (override && override.length > 0) return import_node_path77.default.resolve(override);
|
|
24535
|
+
return import_node_path77.default.join(import_node_os6.default.homedir(), ".neat");
|
|
24243
24536
|
}
|
|
24244
24537
|
function k8sSubstrateConfigPath(home = defaultHome()) {
|
|
24245
|
-
return
|
|
24538
|
+
return import_node_path77.default.join(home, "k8s.json");
|
|
24246
24539
|
}
|
|
24247
24540
|
async function readK8sSubstrateConfig(home = defaultHome()) {
|
|
24248
24541
|
let raw;
|
|
24249
24542
|
try {
|
|
24250
|
-
raw = await (0,
|
|
24543
|
+
raw = await (0, import_promises3.readFile)(k8sSubstrateConfigPath(home), "utf8");
|
|
24251
24544
|
} catch {
|
|
24252
24545
|
return { version: 1, deployments: [] };
|
|
24253
24546
|
}
|
|
@@ -24342,7 +24635,7 @@ init_auth();
|
|
|
24342
24635
|
// src/unrouted.ts
|
|
24343
24636
|
init_cjs_shims();
|
|
24344
24637
|
var import_node_fs40 = require("fs");
|
|
24345
|
-
var
|
|
24638
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
24346
24639
|
function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
|
|
24347
24640
|
return {
|
|
24348
24641
|
timestamp: now.toISOString(),
|
|
@@ -24352,34 +24645,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
|
|
|
24352
24645
|
};
|
|
24353
24646
|
}
|
|
24354
24647
|
async function appendUnroutedSpan(neatHome3, record) {
|
|
24355
|
-
const target =
|
|
24648
|
+
const target = import_node_path78.default.join(neatHome3, "errors.ndjson");
|
|
24356
24649
|
await import_node_fs40.promises.mkdir(neatHome3, { recursive: true });
|
|
24357
24650
|
await import_node_fs40.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
|
|
24358
24651
|
}
|
|
24359
24652
|
function unroutedErrorsPath(neatHome3) {
|
|
24360
|
-
return
|
|
24653
|
+
return import_node_path78.default.join(neatHome3, "errors.ndjson");
|
|
24361
24654
|
}
|
|
24362
24655
|
|
|
24363
24656
|
// src/daemon.ts
|
|
24364
|
-
var
|
|
24657
|
+
var import_types107 = require("@neat.is/types");
|
|
24365
24658
|
function daemonJsonPath(scanPath) {
|
|
24366
|
-
return
|
|
24659
|
+
return import_node_path79.default.join(scanPath, "neat-out", "daemon.json");
|
|
24367
24660
|
}
|
|
24368
24661
|
function daemonsDiscoveryDir(home) {
|
|
24369
24662
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
24370
|
-
return
|
|
24663
|
+
return import_node_path79.default.join(base, "daemons");
|
|
24371
24664
|
}
|
|
24372
24665
|
function daemonDiscoveryPath(project, home) {
|
|
24373
|
-
return
|
|
24666
|
+
return import_node_path79.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
24374
24667
|
}
|
|
24375
24668
|
function sanitizeDiscoveryName(project) {
|
|
24376
24669
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
24377
24670
|
}
|
|
24378
24671
|
function neatHomeFromEnv() {
|
|
24379
24672
|
const env = process.env.NEAT_HOME;
|
|
24380
|
-
if (env && env.length > 0) return
|
|
24673
|
+
if (env && env.length > 0) return import_node_path79.default.resolve(env);
|
|
24381
24674
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24382
|
-
return
|
|
24675
|
+
return import_node_path79.default.join(home, ".neat");
|
|
24383
24676
|
}
|
|
24384
24677
|
function resolveNeatVersion() {
|
|
24385
24678
|
if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
|
|
@@ -24446,11 +24739,11 @@ function teardownSlot(slot) {
|
|
|
24446
24739
|
}
|
|
24447
24740
|
}
|
|
24448
24741
|
function neatHomeFor(opts) {
|
|
24449
|
-
if (opts.neatHome && opts.neatHome.length > 0) return
|
|
24742
|
+
if (opts.neatHome && opts.neatHome.length > 0) return import_node_path79.default.resolve(opts.neatHome);
|
|
24450
24743
|
const env = process.env.NEAT_HOME;
|
|
24451
|
-
if (env && env.length > 0) return
|
|
24744
|
+
if (env && env.length > 0) return import_node_path79.default.resolve(env);
|
|
24452
24745
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24453
|
-
return
|
|
24746
|
+
return import_node_path79.default.join(home, ".neat");
|
|
24454
24747
|
}
|
|
24455
24748
|
function routeSpanToProject(serviceName, projects) {
|
|
24456
24749
|
if (!serviceName) return DEFAULT_PROJECT;
|
|
@@ -24498,11 +24791,11 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
24498
24791
|
if (!serviceName) return true;
|
|
24499
24792
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
24500
24793
|
return graph.someNode(
|
|
24501
|
-
(_id, attrs) => attrs.type ===
|
|
24794
|
+
(_id, attrs) => attrs.type === import_types107.NodeType.ServiceNode && attrs.name === serviceName
|
|
24502
24795
|
);
|
|
24503
24796
|
}
|
|
24504
24797
|
async function bootstrapProject(entry, connectors = [], neatHome3) {
|
|
24505
|
-
const paths = pathsForProject(entry.name,
|
|
24798
|
+
const paths = pathsForProject(entry.name, import_node_path79.default.join(entry.path, "neat-out"));
|
|
24506
24799
|
try {
|
|
24507
24800
|
const stat = await import_node_fs41.promises.stat(entry.path);
|
|
24508
24801
|
if (!stat.isDirectory()) {
|
|
@@ -24656,7 +24949,7 @@ async function startDaemon(opts = {}) {
|
|
|
24656
24949
|
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;
|
|
24657
24950
|
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;
|
|
24658
24951
|
const singleProject = projectArg;
|
|
24659
|
-
const singleProjectPath = singleProject && projectPathArg ?
|
|
24952
|
+
const singleProjectPath = singleProject && projectPathArg ? import_node_path79.default.resolve(projectPathArg) : null;
|
|
24660
24953
|
if (singleProject && !singleProjectPath) {
|
|
24661
24954
|
throw new Error(
|
|
24662
24955
|
`neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
|
|
@@ -24671,7 +24964,7 @@ async function startDaemon(opts = {}) {
|
|
|
24671
24964
|
);
|
|
24672
24965
|
}
|
|
24673
24966
|
}
|
|
24674
|
-
const pidPath =
|
|
24967
|
+
const pidPath = import_node_path79.default.join(home, "neatd.pid");
|
|
24675
24968
|
await writeAtomically(pidPath, `${process.pid}
|
|
24676
24969
|
`);
|
|
24677
24970
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -25143,8 +25436,8 @@ async function startDaemon(opts = {}) {
|
|
|
25143
25436
|
let registryWatcher = null;
|
|
25144
25437
|
let reloadTimer = null;
|
|
25145
25438
|
if (!singleProject) try {
|
|
25146
|
-
const regDir =
|
|
25147
|
-
const regBase =
|
|
25439
|
+
const regDir = import_node_path79.default.dirname(regPath);
|
|
25440
|
+
const regBase = import_node_path79.default.basename(regPath);
|
|
25148
25441
|
registryWatcher = (0, import_node_fs41.watch)(regDir, (_eventType, filename) => {
|
|
25149
25442
|
if (filename !== null && filename !== regBase) return;
|
|
25150
25443
|
if (reloadTimer) clearTimeout(reloadTimer);
|