@neat.is/core 0.9.21-dev.20260924 → 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/cli.cjs
CHANGED
|
@@ -805,7 +805,7 @@ __export(cli_exports, {
|
|
|
805
805
|
});
|
|
806
806
|
module.exports = __toCommonJS(cli_exports);
|
|
807
807
|
init_cjs_shims();
|
|
808
|
-
var
|
|
808
|
+
var import_node_path98 = __toESM(require("path"), 1);
|
|
809
809
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
810
810
|
var import_node_fs59 = require("fs");
|
|
811
811
|
|
|
@@ -8838,7 +8838,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8838
8838
|
});
|
|
8839
8839
|
};
|
|
8840
8840
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
8841
|
-
const
|
|
8841
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8842
8842
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8843
8843
|
let ns = nsCtx;
|
|
8844
8844
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8860,7 +8860,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8860
8860
|
switch (node.type) {
|
|
8861
8861
|
case "function_definition": {
|
|
8862
8862
|
const name = node.childForFieldName("name")?.text;
|
|
8863
|
-
if (name) push("function",
|
|
8863
|
+
if (name) push("function", join2(nsCtx, name), node);
|
|
8864
8864
|
walkBody(node, nsCtx, void 0);
|
|
8865
8865
|
return;
|
|
8866
8866
|
}
|
|
@@ -8868,7 +8868,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8868
8868
|
case "trait_declaration":
|
|
8869
8869
|
case "interface_declaration": {
|
|
8870
8870
|
const name = node.childForFieldName("name")?.text;
|
|
8871
|
-
const full = name ?
|
|
8871
|
+
const full = name ? join2(nsCtx, name) : classCtx;
|
|
8872
8872
|
if (name) push("class", full, node);
|
|
8873
8873
|
walkBody(node, nsCtx, full);
|
|
8874
8874
|
return;
|
|
@@ -8877,7 +8877,7 @@ function collectPhpSymbolDefs(root) {
|
|
|
8877
8877
|
const name = node.childForFieldName("name")?.text;
|
|
8878
8878
|
if (name) {
|
|
8879
8879
|
const kind = name === "__construct" ? "constructor" : "method";
|
|
8880
|
-
push(kind,
|
|
8880
|
+
push(kind, join2(classCtx ?? nsCtx, name), node);
|
|
8881
8881
|
}
|
|
8882
8882
|
return;
|
|
8883
8883
|
}
|
|
@@ -8903,7 +8903,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8903
8903
|
endLine: node.endPosition.row + 1
|
|
8904
8904
|
});
|
|
8905
8905
|
};
|
|
8906
|
-
const
|
|
8906
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8907
8907
|
const walkChildren = (container, nsCtx, classCtx) => {
|
|
8908
8908
|
let ns = nsCtx;
|
|
8909
8909
|
for (let i = 0; i < container.namedChildCount; i++) {
|
|
@@ -8911,7 +8911,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8911
8911
|
if (!child) continue;
|
|
8912
8912
|
if (child.type === "file_scoped_namespace_declaration") {
|
|
8913
8913
|
const nameNode = child.childForFieldName("name");
|
|
8914
|
-
if (nameNode) ns =
|
|
8914
|
+
if (nameNode) ns = join2(nsCtx, nameNode.text);
|
|
8915
8915
|
continue;
|
|
8916
8916
|
}
|
|
8917
8917
|
visit(child, ns, classCtx);
|
|
@@ -8925,7 +8925,7 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8925
8925
|
switch (node.type) {
|
|
8926
8926
|
case "namespace_declaration": {
|
|
8927
8927
|
const nameNode = node.childForFieldName("name");
|
|
8928
|
-
const ns = nameNode ?
|
|
8928
|
+
const ns = nameNode ? join2(nsCtx, nameNode.text) : nsCtx;
|
|
8929
8929
|
walkBody(node, ns, classCtx);
|
|
8930
8930
|
return;
|
|
8931
8931
|
}
|
|
@@ -8934,19 +8934,19 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8934
8934
|
case "struct_declaration":
|
|
8935
8935
|
case "record_declaration": {
|
|
8936
8936
|
const name = node.childForFieldName("name")?.text;
|
|
8937
|
-
const full = name ?
|
|
8937
|
+
const full = name ? join2(classCtx ?? nsCtx, name) : classCtx;
|
|
8938
8938
|
if (name) push("class", full, node);
|
|
8939
8939
|
walkBody(node, nsCtx, full);
|
|
8940
8940
|
return;
|
|
8941
8941
|
}
|
|
8942
8942
|
case "method_declaration": {
|
|
8943
8943
|
const name = node.childForFieldName("name")?.text;
|
|
8944
|
-
if (name) push("method",
|
|
8944
|
+
if (name) push("method", join2(classCtx ?? nsCtx, name), node);
|
|
8945
8945
|
return;
|
|
8946
8946
|
}
|
|
8947
8947
|
case "constructor_declaration": {
|
|
8948
8948
|
const name = node.childForFieldName("name")?.text;
|
|
8949
|
-
if (name) push("constructor",
|
|
8949
|
+
if (name) push("constructor", join2(classCtx ?? nsCtx, name), node);
|
|
8950
8950
|
return;
|
|
8951
8951
|
}
|
|
8952
8952
|
}
|
|
@@ -8965,7 +8965,7 @@ function collectJavaSymbolDefs(root) {
|
|
|
8965
8965
|
endLine: node.endPosition.row + 1
|
|
8966
8966
|
});
|
|
8967
8967
|
};
|
|
8968
|
-
const
|
|
8968
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
8969
8969
|
let pkg;
|
|
8970
8970
|
for (let i = 0; i < root.namedChildCount; i++) {
|
|
8971
8971
|
const child = root.namedChild(i);
|
|
@@ -8991,19 +8991,19 @@ function collectJavaSymbolDefs(root) {
|
|
|
8991
8991
|
case "enum_declaration":
|
|
8992
8992
|
case "record_declaration": {
|
|
8993
8993
|
const name = node.childForFieldName("name")?.text;
|
|
8994
|
-
const full = name ?
|
|
8994
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
8995
8995
|
if (name) push("class", full, node);
|
|
8996
8996
|
walkBody(node, full);
|
|
8997
8997
|
return;
|
|
8998
8998
|
}
|
|
8999
8999
|
case "method_declaration": {
|
|
9000
9000
|
const name = node.childForFieldName("name")?.text;
|
|
9001
|
-
if (name) push("method",
|
|
9001
|
+
if (name) push("method", join2(classCtx ?? pkg, name), node);
|
|
9002
9002
|
return;
|
|
9003
9003
|
}
|
|
9004
9004
|
case "constructor_declaration": {
|
|
9005
9005
|
const name = node.childForFieldName("name")?.text;
|
|
9006
|
-
if (name) push("constructor",
|
|
9006
|
+
if (name) push("constructor", join2(classCtx ?? pkg, name), node);
|
|
9007
9007
|
return;
|
|
9008
9008
|
}
|
|
9009
9009
|
}
|
|
@@ -9022,7 +9022,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9022
9022
|
endLine: node.endPosition.row + 1
|
|
9023
9023
|
});
|
|
9024
9024
|
};
|
|
9025
|
-
const
|
|
9025
|
+
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
9026
9026
|
const firstChildOfType2 = (node, types) => {
|
|
9027
9027
|
for (let i = 0; i < node.namedChildCount; i++) {
|
|
9028
9028
|
const child = node.namedChild(i);
|
|
@@ -9051,7 +9051,7 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9051
9051
|
case "class_declaration":
|
|
9052
9052
|
case "object_declaration": {
|
|
9053
9053
|
const name = nameOf(node, "type_identifier");
|
|
9054
|
-
const full = name ?
|
|
9054
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx;
|
|
9055
9055
|
if (name) push("class", full, node);
|
|
9056
9056
|
const body = bodyOf(node);
|
|
9057
9057
|
if (body) walkChildren(body, full);
|
|
@@ -9059,20 +9059,20 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9059
9059
|
}
|
|
9060
9060
|
case "companion_object": {
|
|
9061
9061
|
const name = nameOf(node, "type_identifier");
|
|
9062
|
-
const full = name ?
|
|
9062
|
+
const full = name ? join2(classCtx ?? pkg, name) : classCtx ?? pkg;
|
|
9063
9063
|
const body = bodyOf(node);
|
|
9064
9064
|
if (body) walkChildren(body, full);
|
|
9065
9065
|
return;
|
|
9066
9066
|
}
|
|
9067
9067
|
case "function_declaration": {
|
|
9068
9068
|
const name = nameOf(node, "simple_identifier");
|
|
9069
|
-
if (name) push(classCtx ? "method" : "function",
|
|
9069
|
+
if (name) push(classCtx ? "method" : "function", join2(classCtx ?? pkg, name), node);
|
|
9070
9070
|
return;
|
|
9071
9071
|
}
|
|
9072
9072
|
case "secondary_constructor": {
|
|
9073
9073
|
if (classCtx) {
|
|
9074
9074
|
const typeName = classCtx.slice(classCtx.lastIndexOf(".") + 1);
|
|
9075
|
-
push("constructor",
|
|
9075
|
+
push("constructor", join2(classCtx, typeName), node);
|
|
9076
9076
|
}
|
|
9077
9077
|
return;
|
|
9078
9078
|
}
|
|
@@ -9092,14 +9092,14 @@ function collectRustSymbolDefs(root) {
|
|
|
9092
9092
|
endLine: node.endPosition.row + 1
|
|
9093
9093
|
});
|
|
9094
9094
|
};
|
|
9095
|
-
const
|
|
9095
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
9096
9096
|
const walkTypeBody = (body, typeCtx) => {
|
|
9097
9097
|
for (let i = 0; i < body.namedChildCount; i++) {
|
|
9098
9098
|
const child = body.namedChild(i);
|
|
9099
9099
|
if (!child) continue;
|
|
9100
9100
|
if (child.type === "function_item" || child.type === "function_signature_item") {
|
|
9101
9101
|
const name = child.childForFieldName("name")?.text;
|
|
9102
|
-
if (name) push("method",
|
|
9102
|
+
if (name) push("method", join2(typeCtx, name), child);
|
|
9103
9103
|
}
|
|
9104
9104
|
}
|
|
9105
9105
|
};
|
|
@@ -9113,7 +9113,7 @@ function collectRustSymbolDefs(root) {
|
|
|
9113
9113
|
switch (node.type) {
|
|
9114
9114
|
case "mod_item": {
|
|
9115
9115
|
const name = node.childForFieldName("name")?.text;
|
|
9116
|
-
const full = name ?
|
|
9116
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
9117
9117
|
const body = node.childForFieldName("body");
|
|
9118
9118
|
if (body) walkChildren(body, full);
|
|
9119
9119
|
return;
|
|
@@ -9121,12 +9121,12 @@ function collectRustSymbolDefs(root) {
|
|
|
9121
9121
|
case "struct_item":
|
|
9122
9122
|
case "enum_item": {
|
|
9123
9123
|
const name = node.childForFieldName("name")?.text;
|
|
9124
|
-
if (name) push("class",
|
|
9124
|
+
if (name) push("class", join2(modCtx, name), node);
|
|
9125
9125
|
return;
|
|
9126
9126
|
}
|
|
9127
9127
|
case "trait_item": {
|
|
9128
9128
|
const name = node.childForFieldName("name")?.text;
|
|
9129
|
-
const full = name ?
|
|
9129
|
+
const full = name ? join2(modCtx, name) : modCtx;
|
|
9130
9130
|
if (name) push("class", full, node);
|
|
9131
9131
|
const body = node.childForFieldName("body");
|
|
9132
9132
|
if (body && full) walkTypeBody(body, full);
|
|
@@ -9134,14 +9134,14 @@ function collectRustSymbolDefs(root) {
|
|
|
9134
9134
|
}
|
|
9135
9135
|
case "impl_item": {
|
|
9136
9136
|
const typeName = node.childForFieldName("type")?.text;
|
|
9137
|
-
const full = typeName ?
|
|
9137
|
+
const full = typeName ? join2(modCtx, typeName) : modCtx;
|
|
9138
9138
|
const body = node.childForFieldName("body");
|
|
9139
9139
|
if (body && full) walkTypeBody(body, full);
|
|
9140
9140
|
return;
|
|
9141
9141
|
}
|
|
9142
9142
|
case "function_item": {
|
|
9143
9143
|
const name = node.childForFieldName("name")?.text;
|
|
9144
|
-
if (name) push("function",
|
|
9144
|
+
if (name) push("function", join2(modCtx, name), node);
|
|
9145
9145
|
return;
|
|
9146
9146
|
}
|
|
9147
9147
|
}
|
|
@@ -9160,7 +9160,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9160
9160
|
endLine: node.endPosition.row + 1
|
|
9161
9161
|
});
|
|
9162
9162
|
};
|
|
9163
|
-
const
|
|
9163
|
+
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
9164
9164
|
const DECLARATOR_WRAPPERS = /* @__PURE__ */ new Set([
|
|
9165
9165
|
"function_declarator",
|
|
9166
9166
|
"pointer_declarator",
|
|
@@ -9186,7 +9186,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9186
9186
|
return void 0;
|
|
9187
9187
|
};
|
|
9188
9188
|
const classify = (nameText, prefix, enclosingClass) => {
|
|
9189
|
-
const qualname =
|
|
9189
|
+
const qualname = join2(prefix, nameText);
|
|
9190
9190
|
let className;
|
|
9191
9191
|
let memberName;
|
|
9192
9192
|
const idx = nameText.lastIndexOf("::");
|
|
@@ -9215,7 +9215,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9215
9215
|
switch (node.type) {
|
|
9216
9216
|
case "namespace_definition": {
|
|
9217
9217
|
const name = node.childForFieldName("name")?.text;
|
|
9218
|
-
const newPrefix = name ?
|
|
9218
|
+
const newPrefix = name ? join2(prefix, name) : prefix;
|
|
9219
9219
|
const body = node.childForFieldName("body");
|
|
9220
9220
|
if (body) walkChildren(body, newPrefix, void 0);
|
|
9221
9221
|
return;
|
|
@@ -9223,7 +9223,7 @@ function collectCppSymbolDefs(root) {
|
|
|
9223
9223
|
case "class_specifier":
|
|
9224
9224
|
case "struct_specifier": {
|
|
9225
9225
|
const name = node.childForFieldName("name")?.text;
|
|
9226
|
-
const full = name ?
|
|
9226
|
+
const full = name ? join2(prefix, name) : prefix;
|
|
9227
9227
|
if (name) push("class", full, node);
|
|
9228
9228
|
const body = node.childForFieldName("body");
|
|
9229
9229
|
if (body && name) walkChildren(body, full, name);
|
|
@@ -17492,14 +17492,14 @@ function formatIncompat(inc) {
|
|
|
17492
17492
|
// src/watch.ts
|
|
17493
17493
|
init_cjs_shims();
|
|
17494
17494
|
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
17495
|
-
var
|
|
17495
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
17496
17496
|
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
17497
17497
|
|
|
17498
17498
|
// src/api.ts
|
|
17499
17499
|
init_cjs_shims();
|
|
17500
17500
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
17501
17501
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
17502
|
-
var
|
|
17502
|
+
var import_types103 = require("@neat.is/types");
|
|
17503
17503
|
|
|
17504
17504
|
// src/extend/index.ts
|
|
17505
17505
|
init_cjs_shims();
|
|
@@ -18052,7 +18052,7 @@ var INTENT_RULES = [
|
|
|
18052
18052
|
},
|
|
18053
18053
|
{
|
|
18054
18054
|
intent: "blast-radius",
|
|
18055
|
-
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/
|
|
18055
|
+
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/
|
|
18056
18056
|
},
|
|
18057
18057
|
{
|
|
18058
18058
|
intent: "divergence",
|
|
@@ -18064,11 +18064,11 @@ var INTENT_RULES = [
|
|
|
18064
18064
|
},
|
|
18065
18065
|
{
|
|
18066
18066
|
intent: "observed",
|
|
18067
|
-
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually
|
|
18067
|
+
test: /\b(at\s+runtime|in\s+prod(?:uction)?|actually|really\s+call\w*|observed|runtime\s+traffic|slow|latency|p95|timing)\b/
|
|
18068
18068
|
},
|
|
18069
18069
|
{
|
|
18070
18070
|
intent: "dependencies",
|
|
18071
|
-
test: /\b(depend\w*|calls?|uses?|imports?|relies\s+on|needs
|
|
18071
|
+
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/
|
|
18072
18072
|
}
|
|
18073
18073
|
];
|
|
18074
18074
|
function classifyIntent(question) {
|
|
@@ -18235,7 +18235,25 @@ var INTENT_WORDS = /* @__PURE__ */ new Set([
|
|
|
18235
18235
|
"rely",
|
|
18236
18236
|
"needs",
|
|
18237
18237
|
"need",
|
|
18238
|
-
"sync"
|
|
18238
|
+
"sync",
|
|
18239
|
+
"talk",
|
|
18240
|
+
"talks",
|
|
18241
|
+
"connect",
|
|
18242
|
+
"connects",
|
|
18243
|
+
"hit",
|
|
18244
|
+
"hits",
|
|
18245
|
+
"read",
|
|
18246
|
+
"reads",
|
|
18247
|
+
"write",
|
|
18248
|
+
"writes",
|
|
18249
|
+
"consumer",
|
|
18250
|
+
"consumers",
|
|
18251
|
+
"caller",
|
|
18252
|
+
"callers",
|
|
18253
|
+
"slow",
|
|
18254
|
+
"latency",
|
|
18255
|
+
"p95",
|
|
18256
|
+
"timing"
|
|
18239
18257
|
]);
|
|
18240
18258
|
function tokens(input) {
|
|
18241
18259
|
const spaced = input.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
@@ -18259,6 +18277,13 @@ function idBody(id) {
|
|
|
18259
18277
|
const colon = id.indexOf(":");
|
|
18260
18278
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18261
18279
|
}
|
|
18280
|
+
var TYPE_NOUNS = [
|
|
18281
|
+
{ nouns: ["database", "db", "table"], type: import_types64.NodeType.DatabaseNode },
|
|
18282
|
+
{ nouns: ["service", "api", "backend"], type: import_types64.NodeType.ServiceNode },
|
|
18283
|
+
{ nouns: ["route", "endpoint"], type: import_types64.NodeType.RouteNode },
|
|
18284
|
+
{ nouns: ["file"], type: import_types64.NodeType.FileNode },
|
|
18285
|
+
{ nouns: ["config"], type: import_types64.NodeType.ConfigNode }
|
|
18286
|
+
];
|
|
18262
18287
|
var EMBED_MIN_SCORE = 0.35;
|
|
18263
18288
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
18264
18289
|
const qTokens = queryTokens(question);
|
|
@@ -18266,6 +18291,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18266
18291
|
const best = /* @__PURE__ */ new Map();
|
|
18267
18292
|
const consider = (cand) => {
|
|
18268
18293
|
const cur = best.get(cand.nodeId);
|
|
18294
|
+
if (cur?.via === "id" && cand.via === "embedding") return;
|
|
18269
18295
|
if (!cur || cand.score > cur.score) best.set(cand.nodeId, cand);
|
|
18270
18296
|
};
|
|
18271
18297
|
graph.forEachNode((id, attrs) => {
|
|
@@ -18275,12 +18301,12 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18275
18301
|
const body = idBody(id);
|
|
18276
18302
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
18277
18303
|
if (labelTokens.size === 0) return;
|
|
18278
|
-
let
|
|
18279
|
-
for (const t of qTokens) if (labelTokens.has(t))
|
|
18304
|
+
let matched2 = 0;
|
|
18305
|
+
for (const t of qTokens) if (labelTokens.has(t)) matched2 += 1;
|
|
18280
18306
|
const named2 = body.length >= 2 && normalized.includes(body.toLowerCase()) || name.length >= 2 && normalized.includes(name.toLowerCase());
|
|
18281
|
-
if (
|
|
18282
|
-
const coverage = qTokens.length > 0 ?
|
|
18283
|
-
const via = named2 ? "id" :
|
|
18307
|
+
if (matched2 === 0 && !named2) return;
|
|
18308
|
+
const coverage = qTokens.length > 0 ? matched2 / qTokens.length : 0;
|
|
18309
|
+
const via = named2 ? "id" : matched2 > 0 && tokens(name).some((t) => qTokens.includes(t)) ? "label" : "token";
|
|
18284
18310
|
const score = named2 ? Math.max(0.9, coverage) : Math.min(0.85, 0.3 + 0.7 * coverage);
|
|
18285
18311
|
consider({ nodeId: id, label: name, via, score: Math.min(1, score) });
|
|
18286
18312
|
});
|
|
@@ -18290,6 +18316,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18290
18316
|
if (res.provider !== "substring") {
|
|
18291
18317
|
for (const m of res.matches) {
|
|
18292
18318
|
if (m.node.type === import_types64.NodeType.FrontierNode) continue;
|
|
18319
|
+
if (!graph.hasNode(m.node.id)) continue;
|
|
18293
18320
|
const already = best.get(m.node.id);
|
|
18294
18321
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
18295
18322
|
consider({
|
|
@@ -18303,10 +18330,31 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18303
18330
|
} catch {
|
|
18304
18331
|
}
|
|
18305
18332
|
}
|
|
18306
|
-
|
|
18307
|
-
|
|
18308
|
-
|
|
18333
|
+
if (best.size === 0) {
|
|
18334
|
+
const words = new Set(tokens(question));
|
|
18335
|
+
const kind = TYPE_NOUNS.find((entry2) => entry2.nouns.some((noun) => words.has(noun)));
|
|
18336
|
+
if (kind) {
|
|
18337
|
+
const ids = graph.filterNodes((_id, attrs) => attrs.type === kind.type).sort();
|
|
18338
|
+
if (ids.length > 1) {
|
|
18339
|
+
return { matched: [], ambiguousType: { noun: kind.nouns.find((noun) => words.has(noun)), ids } };
|
|
18340
|
+
}
|
|
18341
|
+
if (ids.length === 1) {
|
|
18342
|
+
const id = ids[0];
|
|
18343
|
+
return { matched: [{ nodeId: id, label: nodeName(graph.getNodeAttributes(id)), via: "type", score: 0.6 }].slice(0, maxNodes) };
|
|
18344
|
+
}
|
|
18345
|
+
return { matched: [] };
|
|
18346
|
+
}
|
|
18347
|
+
}
|
|
18348
|
+
const viaRank = { id: 4, label: 3, token: 2, type: 1, embedding: 0 };
|
|
18349
|
+
const ranked = [...best.values()].sort(
|
|
18350
|
+
(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)
|
|
18351
|
+
);
|
|
18352
|
+
const primary = ranked[0];
|
|
18353
|
+
const primaryType = primary && graph.getNodeAttributes(primary.nodeId).type;
|
|
18354
|
+
const matched = ranked.filter(
|
|
18355
|
+
(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
|
|
18309
18356
|
).slice(0, maxNodes).map((s) => ({ nodeId: s.nodeId, label: s.label, via: s.via, score: Number(s.score.toFixed(3)) }));
|
|
18357
|
+
return { matched };
|
|
18310
18358
|
}
|
|
18311
18359
|
function incidentsForNode(nodeId, incidents) {
|
|
18312
18360
|
if (!incidents || incidents.length === 0) return [];
|
|
@@ -18398,6 +18446,23 @@ function buildBlastSection(graph, node) {
|
|
|
18398
18446
|
facts
|
|
18399
18447
|
};
|
|
18400
18448
|
}
|
|
18449
|
+
function buildDatabaseCallersSection(graph, node) {
|
|
18450
|
+
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18451
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types64.NodeType.ServiceNode) return false;
|
|
18452
|
+
return item.path.slice(1, -1).every((id) => {
|
|
18453
|
+
const type = graph.getNodeAttributes(id).type;
|
|
18454
|
+
return type === import_types64.NodeType.FileNode || type === import_types64.NodeType.SymbolNode;
|
|
18455
|
+
});
|
|
18456
|
+
});
|
|
18457
|
+
return {
|
|
18458
|
+
heading: `Services calling ${node} \u2014 ${callers.length}`,
|
|
18459
|
+
facts: callers.length > 0 ? callers.slice(0, MAX_FACTS_PER_SECTION).map((item) => ({
|
|
18460
|
+
text: `${item.nodeId} (distance ${item.distance})`,
|
|
18461
|
+
provenance: item.edgeProvenance,
|
|
18462
|
+
confidence: item.confidence
|
|
18463
|
+
})) : [{ text: `No inbound service callers found for ${node}.` }]
|
|
18464
|
+
};
|
|
18465
|
+
}
|
|
18401
18466
|
function buildIncidentsSection(node, incidents) {
|
|
18402
18467
|
const relevant = incidentsForNode(node, incidents);
|
|
18403
18468
|
if (relevant.length === 0) return null;
|
|
@@ -18424,6 +18489,29 @@ function divergenceLine(d) {
|
|
|
18424
18489
|
}
|
|
18425
18490
|
return `[${d.type}] ${d.source} \u2192 ${d.target} \u2014 ${d.reason}`;
|
|
18426
18491
|
}
|
|
18492
|
+
function runtimeEdgeState(graph) {
|
|
18493
|
+
let observed = false;
|
|
18494
|
+
let stale = false;
|
|
18495
|
+
graph.forEachEdge((_id, attrs) => {
|
|
18496
|
+
if (attrs.provenance === import_types64.Provenance.OBSERVED) observed = true;
|
|
18497
|
+
if (attrs.provenance === import_types64.Provenance.STALE) stale = true;
|
|
18498
|
+
});
|
|
18499
|
+
return { observed, stale };
|
|
18500
|
+
}
|
|
18501
|
+
function pendingRuntimeMessage(graph, divergences) {
|
|
18502
|
+
const count = divergences.filter((d) => d.type === "missing-observed").length;
|
|
18503
|
+
if (count === 0) return void 0;
|
|
18504
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18505
|
+
if (observed) return void 0;
|
|
18506
|
+
const prefix = stale ? "No current runtime observations \u2014 earlier runtime evidence is stale" : "No runtime observed yet";
|
|
18507
|
+
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.`;
|
|
18508
|
+
}
|
|
18509
|
+
function noDivergenceMessage(graph) {
|
|
18510
|
+
if (graph.order === 0) return "Graph is empty \u2014 no declared or observed dependencies to compare.";
|
|
18511
|
+
const { observed, stale } = runtimeEdgeState(graph);
|
|
18512
|
+
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.";
|
|
18513
|
+
return "None \u2014 declared code and observed runtime agree across the graph.";
|
|
18514
|
+
}
|
|
18427
18515
|
function buildDivergenceSection(graph, node, incidents) {
|
|
18428
18516
|
const result = computeDivergences(graph, { node, ...incidents ? { incidents } : {} });
|
|
18429
18517
|
if (result.totalAffected === 0) return null;
|
|
@@ -18440,19 +18528,28 @@ function buildDivergenceSection(graph, node, incidents) {
|
|
|
18440
18528
|
}
|
|
18441
18529
|
function buildGlobalDivergenceSection(graph, incidents) {
|
|
18442
18530
|
const result = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18531
|
+
const pending = pendingRuntimeMessage(graph, result.divergences);
|
|
18532
|
+
const visible = pending ? result.divergences.filter((d) => d.type !== "missing-observed") : result.divergences;
|
|
18533
|
+
if (visible.length === 0 && pending) {
|
|
18534
|
+
return {
|
|
18535
|
+
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18536
|
+
facts: [{ text: pending }]
|
|
18537
|
+
};
|
|
18538
|
+
}
|
|
18443
18539
|
if (result.totalAffected === 0) {
|
|
18444
18540
|
return {
|
|
18445
18541
|
heading: "Divergences (EXTRACTED vs OBSERVED)",
|
|
18446
|
-
facts: [{ text:
|
|
18542
|
+
facts: [{ text: noDivergenceMessage(graph) }]
|
|
18447
18543
|
};
|
|
18448
18544
|
}
|
|
18449
|
-
const facts =
|
|
18545
|
+
const facts = visible.slice(0, MAX_FACTS_PER_SECTION).map((d) => ({
|
|
18450
18546
|
text: divergenceLine(d),
|
|
18451
18547
|
confidence: d.confidence
|
|
18452
18548
|
// Composite by construction (EXTRACTED vs OBSERVED), so no single provenance.
|
|
18453
18549
|
}));
|
|
18550
|
+
if (pending && facts.length < MAX_FACTS_PER_SECTION) facts.push({ text: pending });
|
|
18454
18551
|
return {
|
|
18455
|
-
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${
|
|
18552
|
+
heading: `Divergences (EXTRACTED vs OBSERVED) \u2014 ${visible.length}`,
|
|
18456
18553
|
facts
|
|
18457
18554
|
};
|
|
18458
18555
|
}
|
|
@@ -18538,13 +18635,12 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18538
18635
|
});
|
|
18539
18636
|
}
|
|
18540
18637
|
const div = computeDivergences(graph, incidents ? { incidents } : {});
|
|
18638
|
+
const pending = pendingRuntimeMessage(graph, div.divergences);
|
|
18639
|
+
const visibleCount = pending ? div.divergences.filter((d) => d.type !== "missing-observed").length : div.totalAffected;
|
|
18640
|
+
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);
|
|
18541
18641
|
sections.push({
|
|
18542
18642
|
heading: "Divergences",
|
|
18543
|
-
facts: [
|
|
18544
|
-
{
|
|
18545
|
-
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.`
|
|
18546
|
-
}
|
|
18547
|
-
]
|
|
18643
|
+
facts: [{ text: divergenceText }]
|
|
18548
18644
|
});
|
|
18549
18645
|
return sections;
|
|
18550
18646
|
}
|
|
@@ -18589,6 +18685,8 @@ function summarizeGlobal(intent, sections) {
|
|
|
18589
18685
|
const lead = sections[0];
|
|
18590
18686
|
switch (intent) {
|
|
18591
18687
|
case "divergence": {
|
|
18688
|
+
const pending = lead?.facts[0]?.text;
|
|
18689
|
+
if (pending?.startsWith("No runtime") || pending?.startsWith("No current runtime") || pending?.startsWith("Graph is empty")) return pending;
|
|
18592
18690
|
const none = lead?.facts[0]?.text.startsWith("None") ?? true;
|
|
18593
18691
|
return none ? "No divergences across the graph \u2014 declared code and observed runtime agree." : `${lead.heading} across the graph, highest-confidence first below.`;
|
|
18594
18692
|
}
|
|
@@ -18601,11 +18699,16 @@ function summarizeGlobal(intent, sections) {
|
|
|
18601
18699
|
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.`;
|
|
18602
18700
|
}
|
|
18603
18701
|
}
|
|
18604
|
-
function summarize(question, intent, matched, primary, sections, scope) {
|
|
18702
|
+
function summarize(question, intent, matched, primary, sections, scope, ambiguousType) {
|
|
18605
18703
|
if (scope === "global") {
|
|
18606
18704
|
return summarizeGlobal(intent, sections);
|
|
18607
18705
|
}
|
|
18608
18706
|
if (!primary) {
|
|
18707
|
+
if (ambiguousType) {
|
|
18708
|
+
const shown = ambiguousType.ids.slice(0, 10);
|
|
18709
|
+
const more = ambiguousType.ids.length - shown.length;
|
|
18710
|
+
return `"${ambiguousType.noun}" matches ${ambiguousType.ids.length} nodes. Name one by ID: ${shown.join(", ")}${more > 0 ? `, and ${more} more` : ""}.`;
|
|
18711
|
+
}
|
|
18609
18712
|
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.`;
|
|
18610
18713
|
}
|
|
18611
18714
|
const lead = sections[0];
|
|
@@ -18628,10 +18731,13 @@ function summarize(question, intent, matched, primary, sections, scope) {
|
|
|
18628
18731
|
core = lead ? `${lead.heading} of ${primary}.` : `${primary} has no dependents \u2014 nothing else would break if it failed.`;
|
|
18629
18732
|
break;
|
|
18630
18733
|
case "dependencies":
|
|
18631
|
-
core = lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18734
|
+
core = lead?.heading.startsWith("Services calling") ? `${lead.heading}.` : lead ? `${primary}: ${lead.heading.toLowerCase()} listed below.` : `${primary} has no declared dependencies in the graph.`;
|
|
18632
18735
|
break;
|
|
18633
18736
|
case "observed":
|
|
18634
|
-
|
|
18737
|
+
{
|
|
18738
|
+
const observed = sections.find((s) => s.heading === "Runtime dependencies (OBSERVED)");
|
|
18739
|
+
core = observed ? `${primary} at runtime: ${observed.facts.length} OBSERVED fact${observed.facts.length === 1 ? "" : "s"}.` : `No runtime traffic OBSERVED for ${primary}.`;
|
|
18740
|
+
}
|
|
18635
18741
|
break;
|
|
18636
18742
|
case "incidents":
|
|
18637
18743
|
core = lead ? `${primary}: ${lead.heading.toLowerCase()}.` : `No incidents recorded against ${primary}.`;
|
|
@@ -18648,24 +18754,28 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18648
18754
|
const now = opts.now ?? Date.now();
|
|
18649
18755
|
const maxNodes = opts.maxNodes ?? DEFAULT_MAX_NODES;
|
|
18650
18756
|
const intent = classifyIntent(question);
|
|
18651
|
-
const
|
|
18757
|
+
const resolution = await resolveEntities(graph, question, opts.searchIndex, maxNodes);
|
|
18758
|
+
const matched = resolution.matched;
|
|
18652
18759
|
const primary = matched[0]?.nodeId;
|
|
18653
18760
|
const sections = [];
|
|
18654
18761
|
let scope;
|
|
18655
18762
|
if (primary) {
|
|
18656
18763
|
scope = "node";
|
|
18764
|
+
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types64.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);
|
|
18765
|
+
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18657
18766
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18767
|
+
if (callersQuestion && kind === "blast") continue;
|
|
18658
18768
|
const s = buildSection(kind, graph, primary, opts.incidents, now);
|
|
18659
18769
|
if (s && s.facts.length > 0) sections.push(s);
|
|
18660
18770
|
}
|
|
18661
18771
|
} else {
|
|
18662
|
-
const global = buildGlobalSections(intent, graph, opts.incidents);
|
|
18772
|
+
const global = resolution.ambiguousType ? null : buildGlobalSections(intent, graph, opts.incidents);
|
|
18663
18773
|
if (global) {
|
|
18664
18774
|
scope = "global";
|
|
18665
18775
|
for (const s of global) if (s.facts.length > 0) sections.push(s);
|
|
18666
18776
|
}
|
|
18667
18777
|
}
|
|
18668
|
-
const answer = summarize(question, intent, matched, primary, sections, scope);
|
|
18778
|
+
const answer = summarize(question, intent, matched, primary, sections, scope, resolution.ambiguousType);
|
|
18669
18779
|
const provSet = /* @__PURE__ */ new Set();
|
|
18670
18780
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18671
18781
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
@@ -20759,9 +20869,9 @@ var RESOURCE_TYPES = [
|
|
|
20759
20869
|
function isFirebaseResourceType(value) {
|
|
20760
20870
|
return RESOURCE_TYPES.includes(value);
|
|
20761
20871
|
}
|
|
20762
|
-
function buildEntriesFilter(sinceIso) {
|
|
20872
|
+
function buildEntriesFilter(sinceIso, resourceTypes = RESOURCE_TYPES) {
|
|
20763
20873
|
return [
|
|
20764
|
-
|
|
20874
|
+
`resource.type = (${resourceTypes.map((t) => `"${t}"`).join(" OR ")})`,
|
|
20765
20875
|
"httpRequest:*",
|
|
20766
20876
|
`timestamp >= "${sinceIso}"`
|
|
20767
20877
|
].join(" AND ");
|
|
@@ -20770,8 +20880,8 @@ var DEFAULT_LOOKBACK_MS = 24 * 60 * 60 * 1e3;
|
|
|
20770
20880
|
var ENTRIES_LIST_URL = "https://logging.googleapis.com/v2/entries:list";
|
|
20771
20881
|
var PAGE_SIZE = 1e3;
|
|
20772
20882
|
var MAX_PAGES = 20;
|
|
20773
|
-
async function fetchHttpRequestLogEntries(creds, sinceIso) {
|
|
20774
|
-
const filter = buildEntriesFilter(sinceIso);
|
|
20883
|
+
async function fetchHttpRequestLogEntries(creds, sinceIso, resourceTypes) {
|
|
20884
|
+
const filter = buildEntriesFilter(sinceIso, resourceTypes);
|
|
20775
20885
|
const out = [];
|
|
20776
20886
|
let pageToken;
|
|
20777
20887
|
for (let page = 0; page < MAX_PAGES; page++) {
|
|
@@ -20886,7 +20996,38 @@ function mapLogEntriesToSignals(entries) {
|
|
|
20886
20996
|
|
|
20887
20997
|
// src/connectors/firebase/resolve.ts
|
|
20888
20998
|
init_cjs_shims();
|
|
20999
|
+
var import_types74 = require("@neat.is/types");
|
|
21000
|
+
|
|
21001
|
+
// src/connectors/infer-service.ts
|
|
21002
|
+
init_cjs_shims();
|
|
20889
21003
|
var import_types73 = require("@neat.is/types");
|
|
21004
|
+
function normalizeName(name) {
|
|
21005
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21006
|
+
}
|
|
21007
|
+
function inferServiceName(graph, resourceName, method, path98) {
|
|
21008
|
+
const wantedMethod = method.toUpperCase();
|
|
21009
|
+
const wantedPath = normalizePathTemplate(path98);
|
|
21010
|
+
const services = [];
|
|
21011
|
+
const owners = /* @__PURE__ */ new Set();
|
|
21012
|
+
graph.forEachNode((_id, attrs) => {
|
|
21013
|
+
const node = attrs;
|
|
21014
|
+
if (node.type === import_types73.NodeType.ServiceNode && typeof node.name === "string") {
|
|
21015
|
+
services.push(node.name);
|
|
21016
|
+
return;
|
|
21017
|
+
}
|
|
21018
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
21019
|
+
const route = attrs;
|
|
21020
|
+
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
21021
|
+
const routeMethod = route.method.toUpperCase();
|
|
21022
|
+
if (routeMethod === "ALL" || routeMethod === wantedMethod) owners.add(route.service);
|
|
21023
|
+
});
|
|
21024
|
+
const wanted = normalizeName(resourceName);
|
|
21025
|
+
const byName = services.find((s) => normalizeName(s) === wanted);
|
|
21026
|
+
if (byName) return byName;
|
|
21027
|
+
return owners.size === 1 ? [...owners][0] : null;
|
|
21028
|
+
}
|
|
21029
|
+
|
|
21030
|
+
// src/connectors/firebase/resolve.ts
|
|
20890
21031
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
20891
21032
|
switch (resourceType) {
|
|
20892
21033
|
case "cloud_function":
|
|
@@ -20901,7 +21042,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
20901
21042
|
const entries = [];
|
|
20902
21043
|
graph.forEachNode((_id, attrs) => {
|
|
20903
21044
|
const node = attrs;
|
|
20904
|
-
if (node.type !==
|
|
21045
|
+
if (node.type !== import_types74.NodeType.RouteNode) return;
|
|
20905
21046
|
const route = attrs;
|
|
20906
21047
|
if (route.service !== serviceName) return;
|
|
20907
21048
|
entries.push({
|
|
@@ -20925,32 +21066,38 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
20925
21066
|
}
|
|
20926
21067
|
const identity = parseFirebaseTargetName(signal.targetName);
|
|
20927
21068
|
if (!identity) return null;
|
|
20928
|
-
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap);
|
|
20929
|
-
if (!serviceName) return null;
|
|
20930
21069
|
const normalizedPath = normalizePathTemplate(identity.path);
|
|
21070
|
+
const serviceName = neatServiceNameFor(resourceType, identity.resourceName, serviceMap) ?? (serviceMap.inferServices ? inferServiceName(graph, identity.resourceName, identity.method, identity.path) : null);
|
|
21071
|
+
if (!serviceName) return null;
|
|
20931
21072
|
const match = findRoute2(routeEntriesFor(graph, serviceName), identity.method, normalizedPath);
|
|
20932
21073
|
if (!match) return null;
|
|
20933
21074
|
return {
|
|
20934
21075
|
targetNodeId: match.routeNodeId,
|
|
20935
21076
|
serviceName,
|
|
20936
|
-
edgeType:
|
|
21077
|
+
edgeType: import_types74.EdgeType.CALLS
|
|
20937
21078
|
};
|
|
20938
21079
|
};
|
|
20939
21080
|
}
|
|
20940
21081
|
|
|
20941
21082
|
// src/connectors/firebase/index.ts
|
|
20942
21083
|
var FirebaseConnector = class {
|
|
21084
|
+
constructor(opts = {}) {
|
|
21085
|
+
this.opts = opts;
|
|
21086
|
+
}
|
|
21087
|
+
opts;
|
|
20943
21088
|
provider = "firebase";
|
|
20944
21089
|
async poll(ctx) {
|
|
20945
21090
|
const creds = readFirebaseCredentials(ctx.credentials);
|
|
20946
21091
|
const sinceIso = ctx.since ?? new Date(Date.now() - DEFAULT_LOOKBACK_MS).toISOString();
|
|
20947
|
-
const entries = await fetchHttpRequestLogEntries(creds, sinceIso);
|
|
21092
|
+
const entries = await fetchHttpRequestLogEntries(creds, sinceIso, this.opts.resourceTypes);
|
|
20948
21093
|
return mapLogEntriesToSignals(entries);
|
|
20949
21094
|
}
|
|
20950
21095
|
};
|
|
20951
21096
|
function createFirebaseConnector(graph, serviceMap) {
|
|
20952
21097
|
return {
|
|
20953
|
-
connector: new FirebaseConnector(
|
|
21098
|
+
connector: new FirebaseConnector(
|
|
21099
|
+
serviceMap.excludeCloudRun ? { resourceTypes: ["cloud_function", "firebase_domain"] } : {}
|
|
21100
|
+
),
|
|
20954
21101
|
resolveTarget: createFirebaseResolveTarget(graph, serviceMap)
|
|
20955
21102
|
};
|
|
20956
21103
|
}
|
|
@@ -20960,7 +21107,7 @@ init_cjs_shims();
|
|
|
20960
21107
|
|
|
20961
21108
|
// src/connectors/cloudflare/connector.ts
|
|
20962
21109
|
init_cjs_shims();
|
|
20963
|
-
var
|
|
21110
|
+
var import_types76 = require("@neat.is/types");
|
|
20964
21111
|
|
|
20965
21112
|
// src/connectors/cloudflare/client.ts
|
|
20966
21113
|
init_cjs_shims();
|
|
@@ -21124,7 +21271,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
21124
21271
|
graph.forEachNode((id, attrs) => {
|
|
21125
21272
|
if (found) return;
|
|
21126
21273
|
const a = attrs;
|
|
21127
|
-
if (a.type ===
|
|
21274
|
+
if (a.type === import_types76.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
21128
21275
|
found = id;
|
|
21129
21276
|
}
|
|
21130
21277
|
});
|
|
@@ -21136,7 +21283,7 @@ function findMatchingRouteNode(graph, serviceName, method, path98) {
|
|
|
21136
21283
|
graph.forEachNode((id, attrs) => {
|
|
21137
21284
|
if (found) return;
|
|
21138
21285
|
const a = attrs;
|
|
21139
|
-
if (a.type !==
|
|
21286
|
+
if (a.type !== import_types76.NodeType.RouteNode || a.service !== serviceName) return;
|
|
21140
21287
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
21141
21288
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
21142
21289
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -21155,11 +21302,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
21155
21302
|
};
|
|
21156
21303
|
const mapping = config.workers?.[scriptName];
|
|
21157
21304
|
if (mapping) {
|
|
21158
|
-
const wholeFileId = (0,
|
|
21305
|
+
const wholeFileId = (0, import_types76.fileId)(mapping.service, mapping.entryFile);
|
|
21159
21306
|
return {
|
|
21160
21307
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
21161
21308
|
serviceName: mapping.service,
|
|
21162
|
-
edgeType:
|
|
21309
|
+
edgeType: import_types76.EdgeType.CALLS
|
|
21163
21310
|
};
|
|
21164
21311
|
}
|
|
21165
21312
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -21168,13 +21315,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
21168
21315
|
return {
|
|
21169
21316
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
21170
21317
|
serviceName: fileNode.service,
|
|
21171
|
-
edgeType:
|
|
21318
|
+
edgeType: import_types76.EdgeType.CALLS
|
|
21172
21319
|
};
|
|
21173
21320
|
}
|
|
21174
21321
|
return {
|
|
21175
|
-
targetNodeId: (0,
|
|
21322
|
+
targetNodeId: (0, import_types76.infraId)("cloudflare-worker", scriptName),
|
|
21176
21323
|
serviceName: scriptName,
|
|
21177
|
-
edgeType:
|
|
21324
|
+
edgeType: import_types76.EdgeType.CALLS,
|
|
21178
21325
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
21179
21326
|
};
|
|
21180
21327
|
};
|
|
@@ -21370,14 +21517,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
21370
21517
|
|
|
21371
21518
|
// src/connectors/neon/resolve.ts
|
|
21372
21519
|
init_cjs_shims();
|
|
21373
|
-
var
|
|
21520
|
+
var import_types80 = require("@neat.is/types");
|
|
21374
21521
|
function createNeonResolveTarget(config) {
|
|
21375
21522
|
return (signal) => {
|
|
21376
21523
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
21377
21524
|
return {
|
|
21378
|
-
targetNodeId: (0,
|
|
21525
|
+
targetNodeId: (0, import_types80.infraId)("sql-table", signal.targetName),
|
|
21379
21526
|
serviceName: config.serviceName,
|
|
21380
|
-
edgeType:
|
|
21527
|
+
edgeType: import_types80.EdgeType.CALLS,
|
|
21381
21528
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
21382
21529
|
};
|
|
21383
21530
|
};
|
|
@@ -21558,14 +21705,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
21558
21705
|
|
|
21559
21706
|
// src/connectors/cloud-run/resolve.ts
|
|
21560
21707
|
init_cjs_shims();
|
|
21561
|
-
var
|
|
21708
|
+
var import_types84 = require("@neat.is/types");
|
|
21562
21709
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
21563
21710
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
21564
21711
|
let found = null;
|
|
21565
21712
|
graph.forEachNode((_id, attrs) => {
|
|
21566
21713
|
if (found) return;
|
|
21567
21714
|
const node = attrs;
|
|
21568
|
-
if (node.type !==
|
|
21715
|
+
if (node.type !== import_types84.NodeType.RouteNode) return;
|
|
21569
21716
|
const route = attrs;
|
|
21570
21717
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
21571
21718
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -21581,7 +21728,7 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
21581
21728
|
const identity = parseCloudRunTargetName(signal.targetName);
|
|
21582
21729
|
if (!identity) return null;
|
|
21583
21730
|
const { serviceName: gcpServiceName, method, path: path98 } = identity;
|
|
21584
|
-
const mappedService = config.serviceMap?.[gcpServiceName];
|
|
21731
|
+
const mappedService = config.serviceMap?.[gcpServiceName] ?? (config.inferServices ? inferServiceName(graph, gcpServiceName, method, path98) ?? void 0 : void 0);
|
|
21585
21732
|
if (mappedService) {
|
|
21586
21733
|
const routeNodeId = findMatchingRouteNode2(
|
|
21587
21734
|
graph,
|
|
@@ -21590,13 +21737,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
21590
21737
|
normalizePathTemplate(path98)
|
|
21591
21738
|
);
|
|
21592
21739
|
if (routeNodeId) {
|
|
21593
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21740
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types84.EdgeType.CALLS };
|
|
21594
21741
|
}
|
|
21595
21742
|
}
|
|
21596
21743
|
return {
|
|
21597
|
-
targetNodeId: (0,
|
|
21744
|
+
targetNodeId: (0, import_types84.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
21598
21745
|
serviceName: mappedService ?? gcpServiceName,
|
|
21599
|
-
edgeType:
|
|
21746
|
+
edgeType: import_types84.EdgeType.CALLS,
|
|
21600
21747
|
ensureInfraNode: {
|
|
21601
21748
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
21602
21749
|
name: gcpServiceName,
|
|
@@ -21778,14 +21925,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
21778
21925
|
|
|
21779
21926
|
// src/connectors/gcp-lb/resolve.ts
|
|
21780
21927
|
init_cjs_shims();
|
|
21781
|
-
var
|
|
21928
|
+
var import_types88 = require("@neat.is/types");
|
|
21782
21929
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
21783
21930
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
21784
21931
|
let found = null;
|
|
21785
21932
|
graph.forEachNode((_id, attrs) => {
|
|
21786
21933
|
if (found) return;
|
|
21787
21934
|
const node = attrs;
|
|
21788
|
-
if (node.type !==
|
|
21935
|
+
if (node.type !== import_types88.NodeType.RouteNode) return;
|
|
21789
21936
|
const route = attrs;
|
|
21790
21937
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
21791
21938
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -21801,7 +21948,7 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21801
21948
|
const identity = parseGcpLbTargetName(signal.targetName);
|
|
21802
21949
|
if (!identity) return null;
|
|
21803
21950
|
const { backendServiceName, method, path: path98 } = identity;
|
|
21804
|
-
const mappedService = config.backendServiceMap?.[backendServiceName];
|
|
21951
|
+
const mappedService = config.backendServiceMap?.[backendServiceName] ?? (config.inferServices ? inferServiceName(graph, backendServiceName, method, path98) ?? void 0 : void 0);
|
|
21805
21952
|
if (mappedService) {
|
|
21806
21953
|
const routeNodeId = findMatchingRouteNode3(
|
|
21807
21954
|
graph,
|
|
@@ -21810,13 +21957,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
21810
21957
|
normalizePathTemplate(path98)
|
|
21811
21958
|
);
|
|
21812
21959
|
if (routeNodeId) {
|
|
21813
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
21960
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types88.EdgeType.CALLS };
|
|
21814
21961
|
}
|
|
21815
21962
|
}
|
|
21816
21963
|
return {
|
|
21817
|
-
targetNodeId: (0,
|
|
21964
|
+
targetNodeId: (0, import_types88.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
21818
21965
|
serviceName: mappedService ?? backendServiceName,
|
|
21819
|
-
edgeType:
|
|
21966
|
+
edgeType: import_types88.EdgeType.CALLS,
|
|
21820
21967
|
ensureInfraNode: {
|
|
21821
21968
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
21822
21969
|
name: backendServiceName,
|
|
@@ -21857,7 +22004,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
21857
22004
|
|
|
21858
22005
|
// src/connectors/render/index.ts
|
|
21859
22006
|
init_cjs_shims();
|
|
21860
|
-
var
|
|
22007
|
+
var import_types91 = require("@neat.is/types");
|
|
21861
22008
|
|
|
21862
22009
|
// src/connectors/render/types.ts
|
|
21863
22010
|
init_cjs_shims();
|
|
@@ -21935,7 +22082,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
21935
22082
|
const out = [];
|
|
21936
22083
|
graph.forEachNode((_id, attrs) => {
|
|
21937
22084
|
const node = attrs;
|
|
21938
|
-
if (node.type !==
|
|
22085
|
+
if (node.type !== import_types91.NodeType.RouteNode) return;
|
|
21939
22086
|
const route = attrs;
|
|
21940
22087
|
if (route.service !== serviceName) return;
|
|
21941
22088
|
out.push({
|
|
@@ -22020,7 +22167,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
22020
22167
|
function createRenderResolveTarget(config) {
|
|
22021
22168
|
return (signal) => {
|
|
22022
22169
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
22023
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
22170
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types91.EdgeType.CALLS };
|
|
22024
22171
|
}
|
|
22025
22172
|
return null;
|
|
22026
22173
|
};
|
|
@@ -22158,21 +22305,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
22158
22305
|
|
|
22159
22306
|
// src/connectors/planetscale/resolve.ts
|
|
22160
22307
|
init_cjs_shims();
|
|
22161
|
-
var
|
|
22308
|
+
var import_types95 = require("@neat.is/types");
|
|
22162
22309
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
22163
22310
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
22164
22311
|
const databaseName = `${config.organization}/${config.database}`;
|
|
22165
22312
|
return (signal, _ctx) => {
|
|
22166
22313
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22167
|
-
const tableId = (0,
|
|
22314
|
+
const tableId = (0, import_types95.infraId)("sql-table", signal.targetName);
|
|
22168
22315
|
if (graph.hasNode(tableId)) {
|
|
22169
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
22316
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types95.EdgeType.CALLS };
|
|
22170
22317
|
}
|
|
22171
|
-
const providerId = (0,
|
|
22318
|
+
const providerId = (0, import_types95.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
22172
22319
|
return {
|
|
22173
22320
|
targetNodeId: providerId,
|
|
22174
22321
|
serviceName: config.serviceName,
|
|
22175
|
-
edgeType:
|
|
22322
|
+
edgeType: import_types95.EdgeType.CALLS,
|
|
22176
22323
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
22177
22324
|
};
|
|
22178
22325
|
};
|
|
@@ -22437,7 +22584,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
22437
22584
|
|
|
22438
22585
|
// src/connectors/eas/resolve.ts
|
|
22439
22586
|
init_cjs_shims();
|
|
22440
|
-
var
|
|
22587
|
+
var import_types100 = require("@neat.is/types");
|
|
22441
22588
|
var NO_ENV2 = "unknown";
|
|
22442
22589
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
22443
22590
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -22453,8 +22600,8 @@ function configBasenamesForPhase(phase) {
|
|
|
22453
22600
|
function configNodeService(graph, configNodeId) {
|
|
22454
22601
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
22455
22602
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
22456
|
-
if (edge.type !==
|
|
22457
|
-
const parsed = (0,
|
|
22603
|
+
if (edge.type !== import_types100.EdgeType.CONFIGURED_BY) continue;
|
|
22604
|
+
const parsed = (0, import_types100.parseFileId)(edge.source);
|
|
22458
22605
|
if (parsed) return parsed.service;
|
|
22459
22606
|
}
|
|
22460
22607
|
return null;
|
|
@@ -22465,7 +22612,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
22465
22612
|
graph.forEachNode((id, attrs) => {
|
|
22466
22613
|
if (scoped) return;
|
|
22467
22614
|
const node = attrs;
|
|
22468
|
-
if (node.type !==
|
|
22615
|
+
if (node.type !== import_types100.NodeType.ConfigNode) return;
|
|
22469
22616
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
22470
22617
|
if (anyMatch === null) anyMatch = id;
|
|
22471
22618
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -22482,13 +22629,13 @@ function createEasResolveTarget(graph) {
|
|
|
22482
22629
|
if (basenames.length > 0) {
|
|
22483
22630
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
22484
22631
|
if (configNodeId) {
|
|
22485
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
22632
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types100.EdgeType.CALLS };
|
|
22486
22633
|
}
|
|
22487
22634
|
}
|
|
22488
22635
|
return {
|
|
22489
22636
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
22490
22637
|
serviceName,
|
|
22491
|
-
edgeType:
|
|
22638
|
+
edgeType: import_types100.EdgeType.CALLS
|
|
22492
22639
|
};
|
|
22493
22640
|
};
|
|
22494
22641
|
}
|
|
@@ -23356,11 +23503,11 @@ function registerRoutes(scope, ctx) {
|
|
|
23356
23503
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
23357
23504
|
const parsed = [];
|
|
23358
23505
|
for (const c of candidates) {
|
|
23359
|
-
const r =
|
|
23506
|
+
const r = import_types103.DivergenceTypeSchema.safeParse(c);
|
|
23360
23507
|
if (!r.success) {
|
|
23361
23508
|
return reply.code(400).send({
|
|
23362
23509
|
error: `unknown divergence type "${c}"`,
|
|
23363
|
-
allowed:
|
|
23510
|
+
allowed: import_types103.DivergenceTypeSchema.options
|
|
23364
23511
|
});
|
|
23365
23512
|
}
|
|
23366
23513
|
parsed.push(r.data);
|
|
@@ -23756,7 +23903,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23756
23903
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
23757
23904
|
let violations = await log.readAll();
|
|
23758
23905
|
if (req.query.severity) {
|
|
23759
|
-
const sev =
|
|
23906
|
+
const sev = import_types103.PolicySeveritySchema.safeParse(req.query.severity);
|
|
23760
23907
|
if (!sev.success) {
|
|
23761
23908
|
return reply.code(400).send({
|
|
23762
23909
|
error: "invalid severity",
|
|
@@ -23795,7 +23942,7 @@ function registerRoutes(scope, ctx) {
|
|
|
23795
23942
|
scope.post("/policies/check", async (req, reply) => {
|
|
23796
23943
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
23797
23944
|
if (!proj) return;
|
|
23798
|
-
const parsed =
|
|
23945
|
+
const parsed = import_types103.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
23799
23946
|
if (!parsed.success) {
|
|
23800
23947
|
return reply.code(400).send({
|
|
23801
23948
|
error: "invalid /policies/check body",
|
|
@@ -24115,7 +24262,7 @@ init_auth();
|
|
|
24115
24262
|
|
|
24116
24263
|
// src/hang-sensor.ts
|
|
24117
24264
|
init_cjs_shims();
|
|
24118
|
-
var
|
|
24265
|
+
var import_types104 = require("@neat.is/types");
|
|
24119
24266
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
24120
24267
|
function stageHangSurfaces(graph, incidents) {
|
|
24121
24268
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -24128,7 +24275,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
24128
24275
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
24129
24276
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
24130
24277
|
if (!hop) continue;
|
|
24131
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
24278
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types104.EdgeType.CALLS)) staged++;
|
|
24132
24279
|
}
|
|
24133
24280
|
return staged;
|
|
24134
24281
|
}
|
|
@@ -24495,7 +24642,7 @@ function mapWorkloadsToSignals(deployments, pods, config) {
|
|
|
24495
24642
|
|
|
24496
24643
|
// src/connectors/kubernetes/resolve.ts
|
|
24497
24644
|
init_cjs_shims();
|
|
24498
|
-
var
|
|
24645
|
+
var import_types106 = require("@neat.is/types");
|
|
24499
24646
|
var NO_ENV3 = "unknown";
|
|
24500
24647
|
function createK8sResolveTarget(graph) {
|
|
24501
24648
|
return (signal) => {
|
|
@@ -24506,7 +24653,7 @@ function createK8sResolveTarget(graph) {
|
|
|
24506
24653
|
return {
|
|
24507
24654
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
24508
24655
|
serviceName,
|
|
24509
|
-
edgeType:
|
|
24656
|
+
edgeType: import_types106.EdgeType.CALLS
|
|
24510
24657
|
};
|
|
24511
24658
|
};
|
|
24512
24659
|
}
|
|
@@ -24619,12 +24766,14 @@ function createKubernetesConnector(graph, config, fetchImpl) {
|
|
|
24619
24766
|
// src/daemon.ts
|
|
24620
24767
|
init_cjs_shims();
|
|
24621
24768
|
var import_node_fs43 = require("fs");
|
|
24622
|
-
var
|
|
24769
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
24623
24770
|
var import_node_module = require("module");
|
|
24624
24771
|
init_otel();
|
|
24625
24772
|
|
|
24626
24773
|
// src/connectors/hosted.ts
|
|
24627
24774
|
init_cjs_shims();
|
|
24775
|
+
var import_promises2 = require("fs/promises");
|
|
24776
|
+
var import_node_path78 = require("path");
|
|
24628
24777
|
|
|
24629
24778
|
// src/connectors/railway/target-ref.ts
|
|
24630
24779
|
init_cjs_shims();
|
|
@@ -24632,8 +24781,8 @@ init_cjs_shims();
|
|
|
24632
24781
|
// src/connectors/hosted-repos.ts
|
|
24633
24782
|
init_cjs_shims();
|
|
24634
24783
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
24635
|
-
var
|
|
24636
|
-
var
|
|
24784
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
24785
|
+
var import_promises3 = require("fs/promises");
|
|
24637
24786
|
var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
|
|
24638
24787
|
var CLONE_TIMEOUT_MS = 5 * 6e4;
|
|
24639
24788
|
|
|
@@ -24643,28 +24792,28 @@ init_auth();
|
|
|
24643
24792
|
// src/unrouted.ts
|
|
24644
24793
|
init_cjs_shims();
|
|
24645
24794
|
var import_node_fs42 = require("fs");
|
|
24646
|
-
var
|
|
24795
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
24647
24796
|
|
|
24648
24797
|
// src/daemon.ts
|
|
24649
|
-
var
|
|
24798
|
+
var import_types109 = require("@neat.is/types");
|
|
24650
24799
|
function daemonJsonPath(scanPath) {
|
|
24651
|
-
return
|
|
24800
|
+
return import_node_path81.default.join(scanPath, "neat-out", "daemon.json");
|
|
24652
24801
|
}
|
|
24653
24802
|
function daemonsDiscoveryDir(home) {
|
|
24654
24803
|
const base = home && home.length > 0 ? home : neatHomeFromEnv();
|
|
24655
|
-
return
|
|
24804
|
+
return import_node_path81.default.join(base, "daemons");
|
|
24656
24805
|
}
|
|
24657
24806
|
function daemonDiscoveryPath(project, home) {
|
|
24658
|
-
return
|
|
24807
|
+
return import_node_path81.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
|
|
24659
24808
|
}
|
|
24660
24809
|
function sanitizeDiscoveryName(project) {
|
|
24661
24810
|
return project.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
24662
24811
|
}
|
|
24663
24812
|
function neatHomeFromEnv() {
|
|
24664
24813
|
const env = process.env.NEAT_HOME;
|
|
24665
|
-
if (env && env.length > 0) return
|
|
24814
|
+
if (env && env.length > 0) return import_node_path81.default.resolve(env);
|
|
24666
24815
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
24667
|
-
return
|
|
24816
|
+
return import_node_path81.default.join(home, ".neat");
|
|
24668
24817
|
}
|
|
24669
24818
|
async function readDaemonRecord(scanPath) {
|
|
24670
24819
|
try {
|
|
@@ -24735,7 +24884,7 @@ init_otel_grpc();
|
|
|
24735
24884
|
// src/search.ts
|
|
24736
24885
|
init_cjs_shims();
|
|
24737
24886
|
var import_node_fs44 = require("fs");
|
|
24738
|
-
var
|
|
24887
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
24739
24888
|
var import_node_crypto5 = require("crypto");
|
|
24740
24889
|
var DEFAULT_LIMIT = 10;
|
|
24741
24890
|
var NOMIC_DIM = 768;
|
|
@@ -24898,7 +25047,7 @@ async function readCache(cachePath) {
|
|
|
24898
25047
|
}
|
|
24899
25048
|
}
|
|
24900
25049
|
async function writeCache(cachePath, cache) {
|
|
24901
|
-
await import_node_fs44.promises.mkdir(
|
|
25050
|
+
await import_node_fs44.promises.mkdir(import_node_path82.default.dirname(cachePath), { recursive: true });
|
|
24902
25051
|
await import_node_fs44.promises.writeFile(cachePath, JSON.stringify(cache));
|
|
24903
25052
|
}
|
|
24904
25053
|
var VectorIndex = class {
|
|
@@ -25092,8 +25241,8 @@ var ALL_PHASES = [
|
|
|
25092
25241
|
];
|
|
25093
25242
|
function classifyChange(relPath) {
|
|
25094
25243
|
const phases = /* @__PURE__ */ new Set();
|
|
25095
|
-
const base =
|
|
25096
|
-
const segments = relPath.split(
|
|
25244
|
+
const base = import_node_path83.default.basename(relPath).toLowerCase();
|
|
25245
|
+
const segments = relPath.split(import_node_path83.default.sep).map((s) => s.toLowerCase());
|
|
25097
25246
|
if (base === "package.json" || base === "requirements.txt" || base === "pyproject.toml" || base === "setup.py") {
|
|
25098
25247
|
phases.add("services");
|
|
25099
25248
|
phases.add("aliases");
|
|
@@ -25233,9 +25382,9 @@ function countWatchableDirs(scanPath, limit) {
|
|
|
25233
25382
|
for (const e of entries) {
|
|
25234
25383
|
if (count >= limit) return;
|
|
25235
25384
|
if (!e.isDirectory()) continue;
|
|
25236
|
-
if (IGNORED_WATCH_PATHS.some((re) => re.test(
|
|
25385
|
+
if (IGNORED_WATCH_PATHS.some((re) => re.test(import_node_path83.default.join(dir, e.name) + import_node_path83.default.sep))) continue;
|
|
25237
25386
|
count++;
|
|
25238
|
-
if (depth < 2) visit(
|
|
25387
|
+
if (depth < 2) visit(import_node_path83.default.join(dir, e.name), depth + 1);
|
|
25239
25388
|
}
|
|
25240
25389
|
};
|
|
25241
25390
|
visit(scanPath, 0);
|
|
@@ -25253,8 +25402,8 @@ async function startWatch(graph, opts) {
|
|
|
25253
25402
|
const projectName = opts.project ?? DEFAULT_PROJECT;
|
|
25254
25403
|
await loadGraphFromDisk(graph, opts.outPath);
|
|
25255
25404
|
const detachEventBus = attachGraphToEventBus(graph, { project: projectName });
|
|
25256
|
-
const policyFilePath =
|
|
25257
|
-
const policyViolationsPath =
|
|
25405
|
+
const policyFilePath = import_node_path83.default.join(opts.scanPath, "policy.json");
|
|
25406
|
+
const policyViolationsPath = import_node_path83.default.join(import_node_path83.default.dirname(opts.outPath), "policy-violations.ndjson");
|
|
25258
25407
|
let policies = [];
|
|
25259
25408
|
try {
|
|
25260
25409
|
policies = await loadPolicyFile(policyFilePath);
|
|
@@ -25328,7 +25477,7 @@ async function startWatch(graph, opts) {
|
|
|
25328
25477
|
assertBindAuthority(host, auth.authToken);
|
|
25329
25478
|
const port = opts.port ?? 8080;
|
|
25330
25479
|
const otelPort = opts.otelPort ?? 4318;
|
|
25331
|
-
const cachePath = opts.embeddingsCachePath ??
|
|
25480
|
+
const cachePath = opts.embeddingsCachePath ?? import_node_path83.default.join(import_node_path83.default.dirname(opts.outPath), "embeddings.json");
|
|
25332
25481
|
let searchIndex;
|
|
25333
25482
|
try {
|
|
25334
25483
|
searchIndex = await buildSearchIndex(graph, { cachePath });
|
|
@@ -25346,7 +25495,7 @@ async function startWatch(graph, opts) {
|
|
|
25346
25495
|
// Paths are derived from the explicit options the watch caller passes
|
|
25347
25496
|
// — pathsForProject is only used to fill in the embeddings/snapshot
|
|
25348
25497
|
// fields so the registry shape is complete.
|
|
25349
|
-
...pathsForProject(projectName,
|
|
25498
|
+
...pathsForProject(projectName, import_node_path83.default.dirname(opts.outPath)),
|
|
25350
25499
|
snapshotPath: opts.outPath,
|
|
25351
25500
|
errorsPath: opts.errorsPath,
|
|
25352
25501
|
staleEventsPath: opts.staleEventsPath
|
|
@@ -25464,9 +25613,9 @@ async function startWatch(graph, opts) {
|
|
|
25464
25613
|
};
|
|
25465
25614
|
const onPath = (absPath) => {
|
|
25466
25615
|
if (shouldIgnore(absPath)) return;
|
|
25467
|
-
const rel =
|
|
25616
|
+
const rel = import_node_path83.default.relative(opts.scanPath, absPath);
|
|
25468
25617
|
if (!rel || rel.startsWith("..")) return;
|
|
25469
|
-
pendingPaths.add(rel.split(
|
|
25618
|
+
pendingPaths.add(rel.split(import_node_path83.default.sep).join("/"));
|
|
25470
25619
|
const phases = classifyChange(rel);
|
|
25471
25620
|
if (phases.size === 0) {
|
|
25472
25621
|
for (const p of ALL_PHASES) pending.add(p);
|
|
@@ -25525,7 +25674,7 @@ async function startWatch(graph, opts) {
|
|
|
25525
25674
|
// src/deploy/detect.ts
|
|
25526
25675
|
init_cjs_shims();
|
|
25527
25676
|
var import_node_fs46 = require("fs");
|
|
25528
|
-
var
|
|
25677
|
+
var import_node_path84 = __toESM(require("path"), 1);
|
|
25529
25678
|
var import_node_child_process2 = require("child_process");
|
|
25530
25679
|
var import_node_crypto6 = require("crypto");
|
|
25531
25680
|
function generateToken() {
|
|
@@ -25625,7 +25774,7 @@ async function runDeploy(opts = {}) {
|
|
|
25625
25774
|
const token = generateToken();
|
|
25626
25775
|
switch (substrate) {
|
|
25627
25776
|
case "docker-compose": {
|
|
25628
|
-
const artifactPath =
|
|
25777
|
+
const artifactPath = import_node_path84.default.join(cwd, "docker-compose.neat.yml");
|
|
25629
25778
|
const contents = emitDockerCompose(cwd);
|
|
25630
25779
|
await import_node_fs46.promises.writeFile(artifactPath, contents, "utf8");
|
|
25631
25780
|
return {
|
|
@@ -25633,11 +25782,11 @@ async function runDeploy(opts = {}) {
|
|
|
25633
25782
|
artifactPath,
|
|
25634
25783
|
token,
|
|
25635
25784
|
contents,
|
|
25636
|
-
startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${
|
|
25785
|
+
startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${import_node_path84.default.basename(artifactPath)} up -d`
|
|
25637
25786
|
};
|
|
25638
25787
|
}
|
|
25639
25788
|
case "systemd": {
|
|
25640
|
-
const artifactPath =
|
|
25789
|
+
const artifactPath = import_node_path84.default.join(cwd, "neat.service");
|
|
25641
25790
|
const contents = emitSystemdUnit(cwd);
|
|
25642
25791
|
await import_node_fs46.promises.writeFile(artifactPath, contents, "utf8");
|
|
25643
25792
|
return {
|
|
@@ -25673,7 +25822,7 @@ init_cjs_shims();
|
|
|
25673
25822
|
// src/installers/javascript.ts
|
|
25674
25823
|
init_cjs_shims();
|
|
25675
25824
|
var import_node_fs47 = require("fs");
|
|
25676
|
-
var
|
|
25825
|
+
var import_node_path85 = __toESM(require("path"), 1);
|
|
25677
25826
|
var import_semver2 = __toESM(require("semver"), 1);
|
|
25678
25827
|
|
|
25679
25828
|
// src/installers/templates.ts
|
|
@@ -26343,11 +26492,11 @@ var OTEL_ENV = {
|
|
|
26343
26492
|
value: "http://localhost:4318/projects/<project>/v1/traces"
|
|
26344
26493
|
};
|
|
26345
26494
|
function serviceNodeName2(pkg, serviceDir) {
|
|
26346
|
-
return pkg.name ??
|
|
26495
|
+
return pkg.name ?? import_node_path85.default.basename(serviceDir);
|
|
26347
26496
|
}
|
|
26348
26497
|
function projectToken(pkg, serviceDir, project) {
|
|
26349
26498
|
if (project && project.length > 0) return project;
|
|
26350
|
-
return pkg.name ??
|
|
26499
|
+
return pkg.name ?? import_node_path85.default.basename(serviceDir);
|
|
26351
26500
|
}
|
|
26352
26501
|
async function readJsonFile(p) {
|
|
26353
26502
|
try {
|
|
@@ -26360,16 +26509,16 @@ async function readJsonFile(p) {
|
|
|
26360
26509
|
async function detectRuntimeKind(pkgRoot, pkg) {
|
|
26361
26510
|
const deps = allDeps(pkg);
|
|
26362
26511
|
if ("react-native" in deps || "expo" in deps) return "react-native";
|
|
26363
|
-
const appJson = await readJsonFile(
|
|
26512
|
+
const appJson = await readJsonFile(import_node_path85.default.join(pkgRoot, "app.json"));
|
|
26364
26513
|
if (appJson && typeof appJson === "object" && "expo" in appJson) {
|
|
26365
26514
|
return "react-native";
|
|
26366
26515
|
}
|
|
26367
|
-
if (await exists3(
|
|
26516
|
+
if (await exists3(import_node_path85.default.join(pkgRoot, "vite.config.js")) || await exists3(import_node_path85.default.join(pkgRoot, "vite.config.ts")) || await exists3(import_node_path85.default.join(pkgRoot, "vite.config.mjs")) || "vite" in deps) {
|
|
26368
26517
|
return "browser-bundle";
|
|
26369
26518
|
}
|
|
26370
|
-
if (await exists3(
|
|
26371
|
-
if (await exists3(
|
|
26372
|
-
if (await exists3(
|
|
26519
|
+
if (await exists3(import_node_path85.default.join(pkgRoot, "wrangler.toml"))) return "cloudflare-workers";
|
|
26520
|
+
if (await exists3(import_node_path85.default.join(pkgRoot, "bun.lockb"))) return "bun";
|
|
26521
|
+
if (await exists3(import_node_path85.default.join(pkgRoot, "deno.json")) || await exists3(import_node_path85.default.join(pkgRoot, "deno.lock"))) {
|
|
26373
26522
|
return "deno";
|
|
26374
26523
|
}
|
|
26375
26524
|
const engines = pkg.engines ?? {};
|
|
@@ -26378,7 +26527,7 @@ async function detectRuntimeKind(pkgRoot, pkg) {
|
|
|
26378
26527
|
}
|
|
26379
26528
|
async function readPackageJson2(serviceDir) {
|
|
26380
26529
|
try {
|
|
26381
|
-
const raw = await import_node_fs47.promises.readFile(
|
|
26530
|
+
const raw = await import_node_fs47.promises.readFile(import_node_path85.default.join(serviceDir, "package.json"), "utf8");
|
|
26382
26531
|
return JSON.parse(raw);
|
|
26383
26532
|
} catch {
|
|
26384
26533
|
return null;
|
|
@@ -26422,7 +26571,7 @@ function needsVersionUpgrade(installed, expected) {
|
|
|
26422
26571
|
var NEXT_CONFIG_CANDIDATES = ["next.config.js", "next.config.ts", "next.config.mjs"];
|
|
26423
26572
|
async function findNextConfig(serviceDir) {
|
|
26424
26573
|
for (const name of NEXT_CONFIG_CANDIDATES) {
|
|
26425
|
-
const candidate =
|
|
26574
|
+
const candidate = import_node_path85.default.join(serviceDir, name);
|
|
26426
26575
|
if (await exists3(candidate)) return candidate;
|
|
26427
26576
|
}
|
|
26428
26577
|
return null;
|
|
@@ -26491,7 +26640,7 @@ function hasRemixDependency(pkg) {
|
|
|
26491
26640
|
}
|
|
26492
26641
|
async function findRemixEntry(serviceDir) {
|
|
26493
26642
|
for (const rel of REMIX_ENTRY_CANDIDATES) {
|
|
26494
|
-
const candidate =
|
|
26643
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26495
26644
|
if (await exists3(candidate)) return candidate;
|
|
26496
26645
|
}
|
|
26497
26646
|
return null;
|
|
@@ -26503,14 +26652,14 @@ function hasSvelteKitDependency(pkg) {
|
|
|
26503
26652
|
}
|
|
26504
26653
|
async function findSvelteKitHooks(serviceDir) {
|
|
26505
26654
|
for (const rel of SVELTEKIT_HOOKS_CANDIDATES) {
|
|
26506
|
-
const candidate =
|
|
26655
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26507
26656
|
if (await exists3(candidate)) return candidate;
|
|
26508
26657
|
}
|
|
26509
26658
|
return null;
|
|
26510
26659
|
}
|
|
26511
26660
|
async function findSvelteKitConfig(serviceDir) {
|
|
26512
26661
|
for (const rel of SVELTEKIT_CONFIG_CANDIDATES) {
|
|
26513
|
-
const candidate =
|
|
26662
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26514
26663
|
if (await exists3(candidate)) return candidate;
|
|
26515
26664
|
}
|
|
26516
26665
|
return null;
|
|
@@ -26521,7 +26670,7 @@ function hasNuxtDependency(pkg) {
|
|
|
26521
26670
|
}
|
|
26522
26671
|
async function findNuxtConfig(serviceDir) {
|
|
26523
26672
|
for (const name of NUXT_CONFIG_CANDIDATES) {
|
|
26524
|
-
const candidate =
|
|
26673
|
+
const candidate = import_node_path85.default.join(serviceDir, name);
|
|
26525
26674
|
if (await exists3(candidate)) return candidate;
|
|
26526
26675
|
}
|
|
26527
26676
|
return null;
|
|
@@ -26532,7 +26681,7 @@ function hasAstroDependency(pkg) {
|
|
|
26532
26681
|
}
|
|
26533
26682
|
async function findAstroConfig(serviceDir) {
|
|
26534
26683
|
for (const name of ASTRO_CONFIG_CANDIDATES) {
|
|
26535
|
-
const candidate =
|
|
26684
|
+
const candidate = import_node_path85.default.join(serviceDir, name);
|
|
26536
26685
|
if (await exists3(candidate)) return candidate;
|
|
26537
26686
|
}
|
|
26538
26687
|
return null;
|
|
@@ -26546,7 +26695,7 @@ function parseNextMajor(range) {
|
|
|
26546
26695
|
return Number.isFinite(n) ? n : null;
|
|
26547
26696
|
}
|
|
26548
26697
|
async function isTypeScriptProject(serviceDir) {
|
|
26549
|
-
return exists3(
|
|
26698
|
+
return exists3(import_node_path85.default.join(serviceDir, "tsconfig.json"));
|
|
26550
26699
|
}
|
|
26551
26700
|
var INDEX_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs", ".cjs"];
|
|
26552
26701
|
var INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `index${ext}`);
|
|
@@ -26595,7 +26744,7 @@ function entryFromScript(script) {
|
|
|
26595
26744
|
}
|
|
26596
26745
|
async function resolveEntry(serviceDir, pkg) {
|
|
26597
26746
|
if (typeof pkg.main === "string" && pkg.main.length > 0) {
|
|
26598
|
-
const candidate =
|
|
26747
|
+
const candidate = import_node_path85.default.resolve(serviceDir, pkg.main);
|
|
26599
26748
|
if (await exists3(candidate)) return candidate;
|
|
26600
26749
|
}
|
|
26601
26750
|
if (pkg.bin) {
|
|
@@ -26609,40 +26758,40 @@ async function resolveEntry(serviceDir, pkg) {
|
|
|
26609
26758
|
if (typeof first === "string") binEntry = first;
|
|
26610
26759
|
}
|
|
26611
26760
|
if (binEntry) {
|
|
26612
|
-
const candidate =
|
|
26761
|
+
const candidate = import_node_path85.default.resolve(serviceDir, binEntry);
|
|
26613
26762
|
if (await exists3(candidate)) return candidate;
|
|
26614
26763
|
}
|
|
26615
26764
|
}
|
|
26616
26765
|
const startEntry = entryFromScript(pkg.scripts?.start);
|
|
26617
26766
|
if (startEntry) {
|
|
26618
|
-
const candidate =
|
|
26767
|
+
const candidate = import_node_path85.default.resolve(serviceDir, startEntry);
|
|
26619
26768
|
if (await exists3(candidate)) return candidate;
|
|
26620
26769
|
}
|
|
26621
26770
|
const devEntry = entryFromScript(pkg.scripts?.dev);
|
|
26622
26771
|
if (devEntry) {
|
|
26623
|
-
const candidate =
|
|
26772
|
+
const candidate = import_node_path85.default.resolve(serviceDir, devEntry);
|
|
26624
26773
|
if (await exists3(candidate)) return candidate;
|
|
26625
26774
|
}
|
|
26626
26775
|
for (const rel of SRC_INDEX_CANDIDATES) {
|
|
26627
|
-
const candidate =
|
|
26776
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26628
26777
|
if (await exists3(candidate)) return candidate;
|
|
26629
26778
|
}
|
|
26630
26779
|
for (const rel of SRC_NAMED_CANDIDATES) {
|
|
26631
|
-
const candidate =
|
|
26780
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26632
26781
|
if (await exists3(candidate)) return candidate;
|
|
26633
26782
|
}
|
|
26634
26783
|
for (const rel of ROOT_NAMED_CANDIDATES) {
|
|
26635
|
-
const candidate =
|
|
26784
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
26636
26785
|
if (await exists3(candidate)) return candidate;
|
|
26637
26786
|
}
|
|
26638
26787
|
for (const name of INDEX_CANDIDATES) {
|
|
26639
|
-
const candidate =
|
|
26788
|
+
const candidate = import_node_path85.default.join(serviceDir, name);
|
|
26640
26789
|
if (await exists3(candidate)) return candidate;
|
|
26641
26790
|
}
|
|
26642
26791
|
return null;
|
|
26643
26792
|
}
|
|
26644
26793
|
function dispatchEntry(entryFile, pkg) {
|
|
26645
|
-
const ext =
|
|
26794
|
+
const ext = import_node_path85.default.extname(entryFile).toLowerCase();
|
|
26646
26795
|
if (ext === ".ts" || ext === ".tsx") return pkg.type === "module" ? "ts" : "ts-cjs";
|
|
26647
26796
|
if (ext === ".mjs") return "esm";
|
|
26648
26797
|
if (ext === ".cjs") return "cjs";
|
|
@@ -26660,9 +26809,9 @@ function otelInitContents(flavor) {
|
|
|
26660
26809
|
return OTEL_INIT_CJS;
|
|
26661
26810
|
}
|
|
26662
26811
|
function injectionLine(flavor, entryFile, otelInitFile) {
|
|
26663
|
-
let rel =
|
|
26812
|
+
let rel = import_node_path85.default.relative(import_node_path85.default.dirname(entryFile), otelInitFile);
|
|
26664
26813
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
26665
|
-
rel = rel.split(
|
|
26814
|
+
rel = rel.split(import_node_path85.default.sep).join("/");
|
|
26666
26815
|
if (flavor === "cjs") return `require('${rel}')`;
|
|
26667
26816
|
if (flavor === "esm") return `import '${rel}'`;
|
|
26668
26817
|
const tsRel = rel.replace(/\.ts$/, "");
|
|
@@ -26675,27 +26824,27 @@ function lineIsOtelInjection(line) {
|
|
|
26675
26824
|
}
|
|
26676
26825
|
async function detectsSrcLayout(serviceDir) {
|
|
26677
26826
|
const [hasSrcApp, hasSrcPages, hasRootApp, hasRootPages] = await Promise.all([
|
|
26678
|
-
exists3(
|
|
26679
|
-
exists3(
|
|
26680
|
-
exists3(
|
|
26681
|
-
exists3(
|
|
26827
|
+
exists3(import_node_path85.default.join(serviceDir, "src", "app")),
|
|
26828
|
+
exists3(import_node_path85.default.join(serviceDir, "src", "pages")),
|
|
26829
|
+
exists3(import_node_path85.default.join(serviceDir, "app")),
|
|
26830
|
+
exists3(import_node_path85.default.join(serviceDir, "pages"))
|
|
26682
26831
|
]);
|
|
26683
26832
|
return (hasSrcApp || hasSrcPages) && !hasRootApp && !hasRootPages;
|
|
26684
26833
|
}
|
|
26685
26834
|
async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project) {
|
|
26686
26835
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
26687
26836
|
const srcLayout = await detectsSrcLayout(serviceDir);
|
|
26688
|
-
const baseDir = srcLayout ?
|
|
26689
|
-
const instrumentationFile =
|
|
26690
|
-
const instrumentationNodeFile =
|
|
26837
|
+
const baseDir = srcLayout ? import_node_path85.default.join(serviceDir, "src") : serviceDir;
|
|
26838
|
+
const instrumentationFile = import_node_path85.default.join(baseDir, useTs ? "instrumentation.ts" : "instrumentation.js");
|
|
26839
|
+
const instrumentationNodeFile = import_node_path85.default.join(
|
|
26691
26840
|
baseDir,
|
|
26692
26841
|
useTs ? "instrumentation.node.ts" : "instrumentation.node.js"
|
|
26693
26842
|
);
|
|
26694
|
-
const instrumentationEdgeFile =
|
|
26843
|
+
const instrumentationEdgeFile = import_node_path85.default.join(
|
|
26695
26844
|
baseDir,
|
|
26696
26845
|
useTs ? "instrumentation.edge.ts" : "instrumentation.edge.js"
|
|
26697
26846
|
);
|
|
26698
|
-
const envNeatFile =
|
|
26847
|
+
const envNeatFile = import_node_path85.default.join(baseDir, ".env.neat");
|
|
26699
26848
|
const existingDeps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
26700
26849
|
const dependencyEdits = [];
|
|
26701
26850
|
for (const sdk of SDK_PACKAGES) {
|
|
@@ -26820,7 +26969,7 @@ function buildDependencyEdits(pkg, manifestPath) {
|
|
|
26820
26969
|
return edits;
|
|
26821
26970
|
}
|
|
26822
26971
|
async function queueEnvNeat(serviceDir, pkg, project, generatedFiles) {
|
|
26823
|
-
const envNeatFile =
|
|
26972
|
+
const envNeatFile = import_node_path85.default.join(serviceDir, ".env.neat");
|
|
26824
26973
|
if (!await exists3(envNeatFile)) {
|
|
26825
26974
|
generatedFiles.push({
|
|
26826
26975
|
file: envNeatFile,
|
|
@@ -26855,7 +27004,7 @@ function fileImportsOtelHook(raw, specifiers) {
|
|
|
26855
27004
|
}
|
|
26856
27005
|
async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
|
|
26857
27006
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
26858
|
-
const otelServerFile =
|
|
27007
|
+
const otelServerFile = import_node_path85.default.join(
|
|
26859
27008
|
serviceDir,
|
|
26860
27009
|
useTs ? "app/otel.server.ts" : "app/otel.server.js"
|
|
26861
27010
|
);
|
|
@@ -26912,11 +27061,11 @@ async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
|
|
|
26912
27061
|
}
|
|
26913
27062
|
async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project) {
|
|
26914
27063
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
26915
|
-
const otelInitFile =
|
|
27064
|
+
const otelInitFile = import_node_path85.default.join(
|
|
26916
27065
|
serviceDir,
|
|
26917
27066
|
useTs ? "src/otel-init.ts" : "src/otel-init.js"
|
|
26918
27067
|
);
|
|
26919
|
-
const resolvedHooksFile = hooksFile ??
|
|
27068
|
+
const resolvedHooksFile = hooksFile ?? import_node_path85.default.join(serviceDir, useTs ? "src/hooks.server.ts" : "src/hooks.server.js");
|
|
26920
27069
|
const dependencyEdits = buildDependencyEdits(pkg, manifestPath);
|
|
26921
27070
|
const generatedFiles = [];
|
|
26922
27071
|
const entrypointEdits = [];
|
|
@@ -26978,11 +27127,11 @@ async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project)
|
|
|
26978
27127
|
}
|
|
26979
27128
|
async function planNuxt(serviceDir, pkg, manifestPath, project) {
|
|
26980
27129
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
26981
|
-
const otelPluginFile =
|
|
27130
|
+
const otelPluginFile = import_node_path85.default.join(
|
|
26982
27131
|
serviceDir,
|
|
26983
27132
|
useTs ? "server/plugins/otel.ts" : "server/plugins/otel.js"
|
|
26984
27133
|
);
|
|
26985
|
-
const otelInitFile =
|
|
27134
|
+
const otelInitFile = import_node_path85.default.join(
|
|
26986
27135
|
serviceDir,
|
|
26987
27136
|
useTs ? "server/plugins/otel-init.ts" : "server/plugins/otel-init.js"
|
|
26988
27137
|
);
|
|
@@ -27033,19 +27182,19 @@ async function planNuxt(serviceDir, pkg, manifestPath, project) {
|
|
|
27033
27182
|
var ASTRO_MIDDLEWARE_CANDIDATES = ["src/middleware.ts", "src/middleware.js"];
|
|
27034
27183
|
async function findAstroMiddleware(serviceDir) {
|
|
27035
27184
|
for (const rel of ASTRO_MIDDLEWARE_CANDIDATES) {
|
|
27036
|
-
const candidate =
|
|
27185
|
+
const candidate = import_node_path85.default.join(serviceDir, rel);
|
|
27037
27186
|
if (await exists3(candidate)) return candidate;
|
|
27038
27187
|
}
|
|
27039
27188
|
return null;
|
|
27040
27189
|
}
|
|
27041
27190
|
async function planAstro(serviceDir, pkg, manifestPath, project) {
|
|
27042
27191
|
const useTs = await isTypeScriptProject(serviceDir);
|
|
27043
|
-
const otelInitFile =
|
|
27192
|
+
const otelInitFile = import_node_path85.default.join(
|
|
27044
27193
|
serviceDir,
|
|
27045
27194
|
useTs ? "src/otel-init.ts" : "src/otel-init.js"
|
|
27046
27195
|
);
|
|
27047
27196
|
const existingMiddleware = await findAstroMiddleware(serviceDir);
|
|
27048
|
-
const middlewareFile = existingMiddleware ??
|
|
27197
|
+
const middlewareFile = existingMiddleware ?? import_node_path85.default.join(serviceDir, useTs ? "src/middleware.ts" : "src/middleware.js");
|
|
27049
27198
|
const dependencyEdits = buildDependencyEdits(pkg, manifestPath);
|
|
27050
27199
|
const generatedFiles = [];
|
|
27051
27200
|
const entrypointEdits = [];
|
|
@@ -27141,7 +27290,7 @@ async function findFrameworkDispatch(serviceDir, pkg, manifestPath, project) {
|
|
|
27141
27290
|
}
|
|
27142
27291
|
async function plan(serviceDir, opts) {
|
|
27143
27292
|
const pkg = await readPackageJson2(serviceDir);
|
|
27144
|
-
const manifestPath =
|
|
27293
|
+
const manifestPath = import_node_path85.default.join(serviceDir, "package.json");
|
|
27145
27294
|
const project = opts?.project;
|
|
27146
27295
|
const empty = {
|
|
27147
27296
|
language: "javascript",
|
|
@@ -27176,8 +27325,8 @@ async function plan(serviceDir, opts) {
|
|
|
27176
27325
|
return { ...empty, libOnly: true };
|
|
27177
27326
|
}
|
|
27178
27327
|
const flavor = dispatchEntry(entryFile, pkg);
|
|
27179
|
-
const otelInitFile =
|
|
27180
|
-
const envNeatFile =
|
|
27328
|
+
const otelInitFile = import_node_path85.default.join(import_node_path85.default.dirname(entryFile), otelInitFilename(flavor));
|
|
27329
|
+
const envNeatFile = import_node_path85.default.join(serviceDir, ".env.neat");
|
|
27181
27330
|
const existingDeps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
|
|
27182
27331
|
const dependencyEdits = [];
|
|
27183
27332
|
for (const sdk of SDK_PACKAGES) {
|
|
@@ -27246,13 +27395,13 @@ async function plan(serviceDir, opts) {
|
|
|
27246
27395
|
};
|
|
27247
27396
|
}
|
|
27248
27397
|
function isAllowedWritePath(serviceDir, target) {
|
|
27249
|
-
const rel =
|
|
27398
|
+
const rel = import_node_path85.default.relative(serviceDir, target);
|
|
27250
27399
|
if (rel.startsWith("..")) return false;
|
|
27251
|
-
const base =
|
|
27400
|
+
const base = import_node_path85.default.basename(target);
|
|
27252
27401
|
if (base === "package.json") return true;
|
|
27253
27402
|
if (base === ".env.neat") return true;
|
|
27254
27403
|
if (/^otel-init\.(?:js|cjs|mjs|ts)$/.test(base)) return true;
|
|
27255
|
-
const relPosix = rel.split(
|
|
27404
|
+
const relPosix = rel.split(import_node_path85.default.sep).join("/");
|
|
27256
27405
|
if (/^instrumentation(?:\.(?:node|edge))?\.(?:js|cjs|mjs|ts)$/.test(base)) {
|
|
27257
27406
|
if (relPosix === base) return true;
|
|
27258
27407
|
if (relPosix === `src/${base}`) return true;
|
|
@@ -27269,7 +27418,7 @@ function isAllowedWritePath(serviceDir, target) {
|
|
|
27269
27418
|
return false;
|
|
27270
27419
|
}
|
|
27271
27420
|
async function writeAtomic(file, contents) {
|
|
27272
|
-
await import_node_fs47.promises.mkdir(
|
|
27421
|
+
await import_node_fs47.promises.mkdir(import_node_path85.default.dirname(file), { recursive: true });
|
|
27273
27422
|
const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
27274
27423
|
await import_node_fs47.promises.writeFile(tmp, contents, "utf8");
|
|
27275
27424
|
await import_node_fs47.promises.rename(tmp, file);
|
|
@@ -27453,7 +27602,7 @@ async function rollback(installPlan, originals, createdFiles) {
|
|
|
27453
27602
|
...removed.map((f) => `removed: ${f}`),
|
|
27454
27603
|
""
|
|
27455
27604
|
];
|
|
27456
|
-
const rollbackPath =
|
|
27605
|
+
const rollbackPath = import_node_path85.default.join(installPlan.serviceDir, "neat-rollback.patch");
|
|
27457
27606
|
await import_node_fs47.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
|
|
27458
27607
|
}
|
|
27459
27608
|
function injectInstrumentationHook(raw) {
|
|
@@ -27484,7 +27633,7 @@ var javascriptInstaller = {
|
|
|
27484
27633
|
// src/installers/python.ts
|
|
27485
27634
|
init_cjs_shims();
|
|
27486
27635
|
var import_node_fs48 = require("fs");
|
|
27487
|
-
var
|
|
27636
|
+
var import_node_path86 = __toESM(require("path"), 1);
|
|
27488
27637
|
var SDK_PACKAGES2 = [
|
|
27489
27638
|
{ name: "opentelemetry-distro", version: ">=0.49b0" },
|
|
27490
27639
|
{ name: "opentelemetry-exporter-otlp", version: ">=1.28.0" }
|
|
@@ -27582,7 +27731,7 @@ async function writeFileAtomic(file, contents) {
|
|
|
27582
27731
|
await import_node_fs48.promises.rename(tmp, file);
|
|
27583
27732
|
}
|
|
27584
27733
|
async function resolvePyEntrypoint(serviceDir) {
|
|
27585
|
-
const procfile =
|
|
27734
|
+
const procfile = import_node_path86.default.join(serviceDir, "Procfile");
|
|
27586
27735
|
if (await exists4(procfile)) {
|
|
27587
27736
|
const raw = await import_node_fs48.promises.readFile(procfile, "utf8");
|
|
27588
27737
|
for (const line of raw.split(/\r?\n/)) {
|
|
@@ -27592,20 +27741,20 @@ async function resolvePyEntrypoint(serviceDir) {
|
|
|
27592
27741
|
const asgi = cmd.match(/\b(?:uvicorn|gunicorn|hypercorn|daphne)\s+([\w.]+):/);
|
|
27593
27742
|
if (asgi) {
|
|
27594
27743
|
const modPath = asgi[1].replace(/\./g, "/");
|
|
27595
|
-
const asFile =
|
|
27744
|
+
const asFile = import_node_path86.default.join(serviceDir, `${modPath}.py`);
|
|
27596
27745
|
if (await exists4(asFile)) return asFile;
|
|
27597
|
-
const asPkg =
|
|
27746
|
+
const asPkg = import_node_path86.default.join(serviceDir, modPath, "__init__.py");
|
|
27598
27747
|
if (await exists4(asPkg)) return asPkg;
|
|
27599
27748
|
}
|
|
27600
27749
|
const runFile = cmd.match(/\b(?:python3?|fastapi\s+(?:run|dev))\s+([\w./-]+\.py)\b/);
|
|
27601
27750
|
if (runFile) {
|
|
27602
|
-
const p =
|
|
27751
|
+
const p = import_node_path86.default.join(serviceDir, runFile[1]);
|
|
27603
27752
|
if (await exists4(p)) return p;
|
|
27604
27753
|
}
|
|
27605
27754
|
}
|
|
27606
27755
|
}
|
|
27607
27756
|
for (const name of ["main.py", "app.py", "asgi.py", "wsgi.py", "manage.py", "server.py"]) {
|
|
27608
|
-
const p =
|
|
27757
|
+
const p = import_node_path86.default.join(serviceDir, name);
|
|
27609
27758
|
if (await exists4(p)) return p;
|
|
27610
27759
|
}
|
|
27611
27760
|
return null;
|
|
@@ -27631,7 +27780,7 @@ async function exists4(p) {
|
|
|
27631
27780
|
async function detect2(serviceDir) {
|
|
27632
27781
|
const markers = ["requirements.txt", "pyproject.toml", "setup.py"];
|
|
27633
27782
|
for (const m of markers) {
|
|
27634
|
-
if (await exists4(
|
|
27783
|
+
if (await exists4(import_node_path86.default.join(serviceDir, m))) return true;
|
|
27635
27784
|
}
|
|
27636
27785
|
return false;
|
|
27637
27786
|
}
|
|
@@ -27641,7 +27790,7 @@ function reqPackageName(line) {
|
|
|
27641
27790
|
return head.replace(/[<>=!~].*$/, "").toLowerCase();
|
|
27642
27791
|
}
|
|
27643
27792
|
async function planRequirementsTxtEdits(serviceDir) {
|
|
27644
|
-
const file =
|
|
27793
|
+
const file = import_node_path86.default.join(serviceDir, "requirements.txt");
|
|
27645
27794
|
if (!await exists4(file)) return null;
|
|
27646
27795
|
const raw = await import_node_fs48.promises.readFile(file, "utf8");
|
|
27647
27796
|
const presentNames = new Set(
|
|
@@ -27651,7 +27800,7 @@ async function planRequirementsTxtEdits(serviceDir) {
|
|
|
27651
27800
|
return { manifest: file, missing: [...missing] };
|
|
27652
27801
|
}
|
|
27653
27802
|
async function planProcfileEdits(serviceDir) {
|
|
27654
|
-
const procfile =
|
|
27803
|
+
const procfile = import_node_path86.default.join(serviceDir, "Procfile");
|
|
27655
27804
|
if (!await exists4(procfile)) return [];
|
|
27656
27805
|
const raw = await import_node_fs48.promises.readFile(procfile, "utf8");
|
|
27657
27806
|
const edits = [];
|
|
@@ -27689,7 +27838,7 @@ async function plan2(serviceDir) {
|
|
|
27689
27838
|
}
|
|
27690
27839
|
const entrypointEdits = await planProcfileEdits(serviceDir);
|
|
27691
27840
|
const entryFile = await resolvePyEntrypoint(serviceDir);
|
|
27692
|
-
const generatedFiles = entryFile ? [{ file:
|
|
27841
|
+
const generatedFiles = entryFile ? [{ file: import_node_path86.default.join(serviceDir, NEAT_OTEL_FILENAME), contents: neatOtelPy() }] : [];
|
|
27693
27842
|
if (dependencyEdits.length === 0 && entrypointEdits.length === 0 && !entryFile) {
|
|
27694
27843
|
return empty;
|
|
27695
27844
|
}
|
|
@@ -27757,7 +27906,7 @@ async function apply2(installPlan) {
|
|
|
27757
27906
|
if (raw === void 0) {
|
|
27758
27907
|
throw new Error(`python installer: cannot read ${file} during apply`);
|
|
27759
27908
|
}
|
|
27760
|
-
const base =
|
|
27909
|
+
const base = import_node_path86.default.basename(file);
|
|
27761
27910
|
if (base === "requirements.txt") {
|
|
27762
27911
|
const edits = installPlan.dependencyEdits.filter((e) => e.file === file);
|
|
27763
27912
|
if (edits.length > 0) {
|
|
@@ -27812,7 +27961,7 @@ async function rollback2(installPlan, originals, createdFiles = []) {
|
|
|
27812
27961
|
...removed.map((f) => `removed: ${f}`),
|
|
27813
27962
|
""
|
|
27814
27963
|
];
|
|
27815
|
-
const rollbackPath =
|
|
27964
|
+
const rollbackPath = import_node_path86.default.join(installPlan.serviceDir, "neat-rollback.patch");
|
|
27816
27965
|
await import_node_fs48.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
|
|
27817
27966
|
}
|
|
27818
27967
|
var pythonInstaller = {
|
|
@@ -27825,7 +27974,7 @@ var pythonInstaller = {
|
|
|
27825
27974
|
// src/installers/go.ts
|
|
27826
27975
|
init_cjs_shims();
|
|
27827
27976
|
var import_node_fs49 = require("fs");
|
|
27828
|
-
var
|
|
27977
|
+
var import_node_path87 = __toESM(require("path"), 1);
|
|
27829
27978
|
var GO_DEPS = [
|
|
27830
27979
|
{ name: "go.opentelemetry.io/otel", version: "v1.38.0" },
|
|
27831
27980
|
{ name: "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp", version: "v1.38.0" },
|
|
@@ -27835,13 +27984,13 @@ async function exists5(file) {
|
|
|
27835
27984
|
return import_node_fs49.promises.stat(file).then(() => true, () => false);
|
|
27836
27985
|
}
|
|
27837
27986
|
async function findMain(serviceDir) {
|
|
27838
|
-
const root =
|
|
27987
|
+
const root = import_node_path87.default.join(serviceDir, "main.go");
|
|
27839
27988
|
if (await exists5(root)) return root;
|
|
27840
|
-
const cmd =
|
|
27989
|
+
const cmd = import_node_path87.default.join(serviceDir, "cmd");
|
|
27841
27990
|
const entries = await import_node_fs49.promises.readdir(cmd, { withFileTypes: true }).catch(() => []);
|
|
27842
27991
|
for (const entry2 of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
27843
27992
|
if (!entry2.isDirectory()) continue;
|
|
27844
|
-
const candidate =
|
|
27993
|
+
const candidate = import_node_path87.default.join(cmd, entry2.name, "main.go");
|
|
27845
27994
|
if (await exists5(candidate)) return candidate;
|
|
27846
27995
|
}
|
|
27847
27996
|
return null;
|
|
@@ -27916,17 +28065,17 @@ func init() {
|
|
|
27916
28065
|
`;
|
|
27917
28066
|
}
|
|
27918
28067
|
async function detect3(serviceDir) {
|
|
27919
|
-
return exists5(
|
|
28068
|
+
return exists5(import_node_path87.default.join(serviceDir, "go.mod"));
|
|
27920
28069
|
}
|
|
27921
28070
|
async function plan3(serviceDir) {
|
|
27922
|
-
const manifest =
|
|
28071
|
+
const manifest = import_node_path87.default.join(serviceDir, "go.mod");
|
|
27923
28072
|
const raw = await import_node_fs49.promises.readFile(manifest, "utf8");
|
|
27924
28073
|
const main2 = await findMain(serviceDir);
|
|
27925
28074
|
const dependencyEdits = GO_DEPS.filter((dep) => !raw.includes(dep.name)).map((dep) => ({ file: manifest, kind: "add", ...dep }));
|
|
27926
28075
|
if (!main2) return { language: "go", serviceDir, dependencyEdits: [], entrypointEdits: [], envEdits: [], libOnly: true };
|
|
27927
28076
|
const source = await import_node_fs49.promises.readFile(main2, "utf8");
|
|
27928
28077
|
const packageName = source.match(/^\s*package\s+(\w+)\s*$/m)?.[1] ?? "main";
|
|
27929
|
-
const generated =
|
|
28078
|
+
const generated = import_node_path87.default.join(import_node_path87.default.dirname(main2), "neat_otel.go");
|
|
27930
28079
|
const generatedFiles = await exists5(generated) ? [] : [{ file: generated, contents: neatOtelGo(packageName) }];
|
|
27931
28080
|
return { language: "go", serviceDir, dependencyEdits, entrypointEdits: [], envEdits: [], generatedFiles, entryFile: main2 };
|
|
27932
28081
|
}
|
|
@@ -27960,7 +28109,7 @@ var goInstaller = { name: "go", detect: detect3, plan: plan3, apply: apply3 };
|
|
|
27960
28109
|
// src/installers/ruby.ts
|
|
27961
28110
|
init_cjs_shims();
|
|
27962
28111
|
var import_node_fs50 = require("fs");
|
|
27963
|
-
var
|
|
28112
|
+
var import_node_path88 = __toESM(require("path"), 1);
|
|
27964
28113
|
var RUBY_MARKERS = [
|
|
27965
28114
|
"Gemfile",
|
|
27966
28115
|
"Gemfile.lock"
|
|
@@ -27971,7 +28120,7 @@ var RUBY_GEMS = [
|
|
|
27971
28120
|
{ name: "opentelemetry-instrumentation-all", version: "~> 0.62" }
|
|
27972
28121
|
];
|
|
27973
28122
|
var NEAT_OTEL_STAMP2 = "neat-otel-init v1";
|
|
27974
|
-
var INITIALIZER_REL =
|
|
28123
|
+
var INITIALIZER_REL = import_node_path88.default.join("config", "initializers", "neat_otel.rb");
|
|
27975
28124
|
function neatOtelRb(opts = {}) {
|
|
27976
28125
|
const service = opts.project ?? "ruby-service";
|
|
27977
28126
|
const endpoint2 = opts.project ? `http://localhost:4318/projects/${opts.project}/v1/traces` : "http://localhost:4318/v1/traces";
|
|
@@ -28060,14 +28209,14 @@ async function exists6(p) {
|
|
|
28060
28209
|
}
|
|
28061
28210
|
async function detect4(serviceDir) {
|
|
28062
28211
|
for (const marker of RUBY_MARKERS) {
|
|
28063
|
-
if (await exists6(
|
|
28212
|
+
if (await exists6(import_node_path88.default.join(serviceDir, marker))) return true;
|
|
28064
28213
|
}
|
|
28065
28214
|
return false;
|
|
28066
28215
|
}
|
|
28067
28216
|
async function isRailsApp(serviceDir, gemfile) {
|
|
28068
28217
|
if (gemfile && /^\s*gem\s+['"]rails['"]/m.test(gemfile)) return true;
|
|
28069
28218
|
for (const marker of ["config/application.rb", "config/environment.rb", "bin/rails"]) {
|
|
28070
|
-
if (await exists6(
|
|
28219
|
+
if (await exists6(import_node_path88.default.join(serviceDir, marker))) return true;
|
|
28071
28220
|
}
|
|
28072
28221
|
return false;
|
|
28073
28222
|
}
|
|
@@ -28076,7 +28225,7 @@ function gemPresent(gemfile, name) {
|
|
|
28076
28225
|
return new RegExp(`^\\s*gem\\s+['"]${escaped}['"]`, "m").test(gemfile);
|
|
28077
28226
|
}
|
|
28078
28227
|
async function readGemfile(serviceDir) {
|
|
28079
|
-
const file =
|
|
28228
|
+
const file = import_node_path88.default.join(serviceDir, "Gemfile");
|
|
28080
28229
|
if (!await exists6(file)) return null;
|
|
28081
28230
|
return { file, body: await import_node_fs50.promises.readFile(file, "utf8") };
|
|
28082
28231
|
}
|
|
@@ -28098,7 +28247,7 @@ async function plan4(serviceDir, opts) {
|
|
|
28098
28247
|
}
|
|
28099
28248
|
}
|
|
28100
28249
|
const rails = await isRailsApp(serviceDir, gemfile?.body ?? null);
|
|
28101
|
-
const initializer =
|
|
28250
|
+
const initializer = import_node_path88.default.join(serviceDir, INITIALIZER_REL);
|
|
28102
28251
|
const generatedFiles = [];
|
|
28103
28252
|
if (rails && !await exists6(initializer)) {
|
|
28104
28253
|
generatedFiles.push({
|
|
@@ -28163,7 +28312,7 @@ async function rollback3(serviceDir, language, originals, created) {
|
|
|
28163
28312
|
...removed.map((f) => `removed: ${f}`),
|
|
28164
28313
|
""
|
|
28165
28314
|
];
|
|
28166
|
-
await import_node_fs50.promises.writeFile(
|
|
28315
|
+
await import_node_fs50.promises.writeFile(import_node_path88.default.join(serviceDir, "neat-rollback.patch"), body.join("\n"), "utf8");
|
|
28167
28316
|
}
|
|
28168
28317
|
async function apply4(installPlan) {
|
|
28169
28318
|
const { serviceDir } = installPlan;
|
|
@@ -28184,7 +28333,7 @@ async function apply4(installPlan) {
|
|
|
28184
28333
|
try {
|
|
28185
28334
|
for (const gf of generatedFiles) {
|
|
28186
28335
|
if (await exists6(gf.file)) continue;
|
|
28187
|
-
await import_node_fs50.promises.mkdir(
|
|
28336
|
+
await import_node_fs50.promises.mkdir(import_node_path88.default.dirname(gf.file), { recursive: true });
|
|
28188
28337
|
await writeFileAtomic2(gf.file, gf.contents);
|
|
28189
28338
|
writtenFiles.push(gf.file);
|
|
28190
28339
|
created.push(gf.file);
|
|
@@ -28202,7 +28351,7 @@ async function apply4(installPlan) {
|
|
|
28202
28351
|
await rollback3(serviceDir, installPlan.language, originals, created);
|
|
28203
28352
|
throw err;
|
|
28204
28353
|
}
|
|
28205
|
-
const wroteManifest = writtenFiles.some((f) =>
|
|
28354
|
+
const wroteManifest = writtenFiles.some((f) => import_node_path88.default.basename(f) === "Gemfile");
|
|
28206
28355
|
return {
|
|
28207
28356
|
serviceDir,
|
|
28208
28357
|
outcome: writtenFiles.length > 0 ? "instrumented" : "already-instrumented",
|
|
@@ -28215,7 +28364,7 @@ var rubyInstaller = { name: "ruby", detect: detect4, plan: plan4, apply: apply4
|
|
|
28215
28364
|
// src/installers/php.ts
|
|
28216
28365
|
init_cjs_shims();
|
|
28217
28366
|
var import_node_fs51 = require("fs");
|
|
28218
|
-
var
|
|
28367
|
+
var import_node_path89 = __toESM(require("path"), 1);
|
|
28219
28368
|
var PHP_MARKERS = [
|
|
28220
28369
|
"composer.json",
|
|
28221
28370
|
"composer.lock"
|
|
@@ -28292,7 +28441,7 @@ async function exists7(p) {
|
|
|
28292
28441
|
}
|
|
28293
28442
|
async function detect5(serviceDir) {
|
|
28294
28443
|
for (const marker of PHP_MARKERS) {
|
|
28295
|
-
if (await exists7(
|
|
28444
|
+
if (await exists7(import_node_path89.default.join(serviceDir, marker))) return true;
|
|
28296
28445
|
}
|
|
28297
28446
|
return false;
|
|
28298
28447
|
}
|
|
@@ -28316,13 +28465,13 @@ async function plan5(serviceDir, opts) {
|
|
|
28316
28465
|
entrypointEdits: [],
|
|
28317
28466
|
envEdits: []
|
|
28318
28467
|
};
|
|
28319
|
-
const composerPath =
|
|
28468
|
+
const composerPath = import_node_path89.default.join(serviceDir, "composer.json");
|
|
28320
28469
|
const hasComposer = await exists7(composerPath);
|
|
28321
28470
|
const dependencyEdits = [];
|
|
28322
28471
|
if (hasComposer) {
|
|
28323
28472
|
const body = await import_node_fs51.promises.readFile(composerPath, "utf8");
|
|
28324
28473
|
const { require: require2, requireDev } = readComposerObject(body);
|
|
28325
|
-
const laravel = "laravel/framework" in require2 || "laravel/framework" in requireDev || await exists7(
|
|
28474
|
+
const laravel = "laravel/framework" in require2 || "laravel/framework" in requireDev || await exists7(import_node_path89.default.join(serviceDir, "artisan"));
|
|
28326
28475
|
const wanted = laravel ? PHP_PACKAGES : PHP_PACKAGES.filter((p) => p.name !== LARAVEL_PACKAGE);
|
|
28327
28476
|
for (const pkg of wanted) {
|
|
28328
28477
|
if (!(pkg.name in require2)) {
|
|
@@ -28330,7 +28479,7 @@ async function plan5(serviceDir, opts) {
|
|
|
28330
28479
|
}
|
|
28331
28480
|
}
|
|
28332
28481
|
}
|
|
28333
|
-
const bootstrap =
|
|
28482
|
+
const bootstrap = import_node_path89.default.join(serviceDir, NEAT_OTEL_FILENAME2);
|
|
28334
28483
|
const generatedFiles = [];
|
|
28335
28484
|
if (hasComposer && !await exists7(bootstrap)) {
|
|
28336
28485
|
generatedFiles.push({ file: bootstrap, contents: neatOtelPhp({ project: opts?.project }), skipIfExists: true });
|
|
@@ -28402,7 +28551,7 @@ async function rollback4(serviceDir, language, originals, created) {
|
|
|
28402
28551
|
...removed.map((f) => `removed: ${f}`),
|
|
28403
28552
|
""
|
|
28404
28553
|
];
|
|
28405
|
-
await import_node_fs51.promises.writeFile(
|
|
28554
|
+
await import_node_fs51.promises.writeFile(import_node_path89.default.join(serviceDir, "neat-rollback.patch"), body.join("\n"), "utf8");
|
|
28406
28555
|
}
|
|
28407
28556
|
async function apply5(installPlan) {
|
|
28408
28557
|
const { serviceDir } = installPlan;
|
|
@@ -28423,7 +28572,7 @@ async function apply5(installPlan) {
|
|
|
28423
28572
|
try {
|
|
28424
28573
|
for (const gf of generatedFiles) {
|
|
28425
28574
|
if (await exists7(gf.file)) continue;
|
|
28426
|
-
await import_node_fs51.promises.mkdir(
|
|
28575
|
+
await import_node_fs51.promises.mkdir(import_node_path89.default.dirname(gf.file), { recursive: true });
|
|
28427
28576
|
await writeFileAtomic3(gf.file, gf.contents);
|
|
28428
28577
|
writtenFiles.push(gf.file);
|
|
28429
28578
|
created.push(gf.file);
|
|
@@ -28442,10 +28591,10 @@ async function apply5(installPlan) {
|
|
|
28442
28591
|
throw err;
|
|
28443
28592
|
}
|
|
28444
28593
|
if (writtenFiles.length > 0) {
|
|
28445
|
-
console.warn(`neat: PHP instrumentation staged in ${
|
|
28594
|
+
console.warn(`neat: PHP instrumentation staged in ${import_node_path89.default.basename(serviceDir)}, but a system step remains:
|
|
28446
28595
|
${PHP_PECL_CAVEAT}`);
|
|
28447
28596
|
}
|
|
28448
|
-
const wroteManifest = writtenFiles.some((f) =>
|
|
28597
|
+
const wroteManifest = writtenFiles.some((f) => import_node_path89.default.basename(f) === "composer.json");
|
|
28449
28598
|
return {
|
|
28450
28599
|
serviceDir,
|
|
28451
28600
|
outcome: writtenFiles.length > 0 ? "instrumented" : "already-instrumented",
|
|
@@ -28580,7 +28729,7 @@ init_cjs_shims();
|
|
|
28580
28729
|
var import_node_fs52 = require("fs");
|
|
28581
28730
|
var import_node_http = __toESM(require("http"), 1);
|
|
28582
28731
|
var import_node_net = __toESM(require("net"), 1);
|
|
28583
|
-
var
|
|
28732
|
+
var import_node_path90 = __toESM(require("path"), 1);
|
|
28584
28733
|
var import_node_url4 = require("url");
|
|
28585
28734
|
var import_node_child_process3 = require("child_process");
|
|
28586
28735
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
@@ -28590,7 +28739,7 @@ async function extractAndPersist(opts) {
|
|
|
28590
28739
|
const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT;
|
|
28591
28740
|
resetGraph(graphKey);
|
|
28592
28741
|
const graph = getGraph(graphKey);
|
|
28593
|
-
const projectPaths = pathsForProject(graphKey,
|
|
28742
|
+
const projectPaths = pathsForProject(graphKey, import_node_path90.default.join(opts.scanPath, "neat-out"));
|
|
28594
28743
|
const extraction = await extractFromDirectory(graph, opts.scanPath, {
|
|
28595
28744
|
errorsPath: projectPaths.errorsPath
|
|
28596
28745
|
});
|
|
@@ -28634,7 +28783,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28634
28783
|
if (outcome.outcome === "instrumented") {
|
|
28635
28784
|
instrumented++;
|
|
28636
28785
|
if (plan6.dependencyEdits.length > 0) {
|
|
28637
|
-
const manifest =
|
|
28786
|
+
const manifest = import_node_path90.default.basename(plan6.dependencyEdits[0].file);
|
|
28638
28787
|
if (manifest === "package.json") {
|
|
28639
28788
|
const cmd = await resolveManager(svc.dir);
|
|
28640
28789
|
const key = `${cmd.pm}:${cmd.cwd}`;
|
|
@@ -28648,7 +28797,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28648
28797
|
libOnly++;
|
|
28649
28798
|
const appDeps = svc.pkg ? appFrameworkDependencies(svc.pkg) : [];
|
|
28650
28799
|
if (appDeps.length > 0) {
|
|
28651
|
-
const svcName =
|
|
28800
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28652
28801
|
const list = appDeps.join(", ");
|
|
28653
28802
|
console.warn(
|
|
28654
28803
|
`neat: runtime layer won't engage for ${svcName}: no entry point found.
|
|
@@ -28661,7 +28810,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28661
28810
|
console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`);
|
|
28662
28811
|
} else if (outcome.outcome === "react-native") {
|
|
28663
28812
|
reactNative++;
|
|
28664
|
-
const svcName =
|
|
28813
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28665
28814
|
console.log(
|
|
28666
28815
|
`neat: ${svc.dir} detected as React Native / Expo
|
|
28667
28816
|
The installer doesn't cover this runtime deterministically.
|
|
@@ -28672,7 +28821,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28672
28821
|
);
|
|
28673
28822
|
} else if (outcome.outcome === "bun") {
|
|
28674
28823
|
bun++;
|
|
28675
|
-
const svcName =
|
|
28824
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28676
28825
|
console.log(
|
|
28677
28826
|
`neat: ${svc.dir} detected as Bun
|
|
28678
28827
|
The installer doesn't cover this runtime deterministically.
|
|
@@ -28683,7 +28832,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28683
28832
|
);
|
|
28684
28833
|
} else if (outcome.outcome === "deno") {
|
|
28685
28834
|
deno++;
|
|
28686
|
-
const svcName =
|
|
28835
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28687
28836
|
console.log(
|
|
28688
28837
|
`neat: ${svc.dir} detected as Deno
|
|
28689
28838
|
The installer doesn't cover this runtime deterministically.
|
|
@@ -28694,7 +28843,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28694
28843
|
);
|
|
28695
28844
|
} else if (outcome.outcome === "cloudflare-workers") {
|
|
28696
28845
|
cloudflareWorkers++;
|
|
28697
|
-
const svcName =
|
|
28846
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28698
28847
|
console.log(
|
|
28699
28848
|
`neat: ${svc.dir} detected as Cloudflare Workers
|
|
28700
28849
|
The installer doesn't cover this runtime deterministically.
|
|
@@ -28705,7 +28854,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28705
28854
|
);
|
|
28706
28855
|
} else if (outcome.outcome === "electron") {
|
|
28707
28856
|
electron++;
|
|
28708
|
-
const svcName =
|
|
28857
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28709
28858
|
console.log(
|
|
28710
28859
|
`neat: ${svc.dir} detected as Electron
|
|
28711
28860
|
The installer doesn't cover this runtime deterministically.
|
|
@@ -28718,7 +28867,7 @@ async function applyInstallersOver(services, project, options = {}) {
|
|
|
28718
28867
|
if (svc.pkg && (outcome.outcome === "instrumented" || outcome.outcome === "already-instrumented")) {
|
|
28719
28868
|
const gaps = uninstrumentedLibraries(svc.pkg);
|
|
28720
28869
|
if (gaps.length > 0) {
|
|
28721
|
-
const svcName =
|
|
28870
|
+
const svcName = import_node_path90.default.basename(svc.dir);
|
|
28722
28871
|
const list = gaps.join(", ");
|
|
28723
28872
|
const subject = gaps.length === 1 ? "this library" : "these libraries";
|
|
28724
28873
|
const aux = gaps.length === 1 ? "isn't" : "aren't";
|
|
@@ -28930,8 +29079,8 @@ async function persistedPortsFor(scanPath) {
|
|
|
28930
29079
|
return { rest: record.ports.rest, otlp: record.ports.otlp, web: record.ports.web };
|
|
28931
29080
|
}
|
|
28932
29081
|
async function acquireSpawnLock(scanPath) {
|
|
28933
|
-
const lockPath =
|
|
28934
|
-
await import_node_fs52.promises.mkdir(
|
|
29082
|
+
const lockPath = import_node_path90.default.join(scanPath, "neat-out", "daemon.spawn.lock");
|
|
29083
|
+
await import_node_fs52.promises.mkdir(import_node_path90.default.dirname(lockPath), { recursive: true });
|
|
28935
29084
|
const STALE_LOCK_MS = 6e4;
|
|
28936
29085
|
try {
|
|
28937
29086
|
const fd = await import_node_fs52.promises.open(lockPath, "wx");
|
|
@@ -28976,13 +29125,13 @@ async function healthIsForProject(restPort, project) {
|
|
|
28976
29125
|
return false;
|
|
28977
29126
|
}
|
|
28978
29127
|
function daemonLogPath(projectPath3) {
|
|
28979
|
-
return
|
|
29128
|
+
return import_node_path90.default.join(projectPath3, "neat-out", "daemon.log");
|
|
28980
29129
|
}
|
|
28981
29130
|
function spawnDaemonDetached(spec) {
|
|
28982
|
-
const here =
|
|
29131
|
+
const here = import_node_path90.default.dirname((0, import_node_url4.fileURLToPath)(importMetaUrl));
|
|
28983
29132
|
const candidates = [
|
|
28984
|
-
|
|
28985
|
-
|
|
29133
|
+
import_node_path90.default.join(here, "neatd.cjs"),
|
|
29134
|
+
import_node_path90.default.join(here, "neatd.js")
|
|
28986
29135
|
];
|
|
28987
29136
|
let entry2 = null;
|
|
28988
29137
|
const fsSync = require("fs");
|
|
@@ -29012,7 +29161,7 @@ function spawnDaemonDetached(spec) {
|
|
|
29012
29161
|
let logFd = null;
|
|
29013
29162
|
if (spec) {
|
|
29014
29163
|
const logPath = daemonLogPath(spec.projectPath);
|
|
29015
|
-
fsSync.mkdirSync(
|
|
29164
|
+
fsSync.mkdirSync(import_node_path90.default.dirname(logPath), { recursive: true });
|
|
29016
29165
|
logFd = fsSync.openSync(logPath, "a");
|
|
29017
29166
|
}
|
|
29018
29167
|
const child = (0, import_node_child_process3.spawn)(process.execPath, [entry2, "start"], {
|
|
@@ -29211,7 +29360,7 @@ async function runOrchestrator(opts) {
|
|
|
29211
29360
|
result.steps.browser = "skipped";
|
|
29212
29361
|
}
|
|
29213
29362
|
const daemonRunning = result.steps.daemon === "spawned" || result.steps.daemon === "already-running";
|
|
29214
|
-
const daemonLog = daemonRunning ?
|
|
29363
|
+
const daemonLog = daemonRunning ? import_node_path90.default.relative(opts.scanPath, daemonLogPath(opts.scanPath)) : null;
|
|
29215
29364
|
printSummary(result, graph, daemonLog);
|
|
29216
29365
|
return result;
|
|
29217
29366
|
}
|
|
@@ -29691,18 +29840,18 @@ var import_node_crypto7 = require("crypto");
|
|
|
29691
29840
|
init_cjs_shims();
|
|
29692
29841
|
var import_node_fs53 = require("fs");
|
|
29693
29842
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
29694
|
-
var
|
|
29843
|
+
var import_node_path91 = __toESM(require("path"), 1);
|
|
29695
29844
|
var PROFILES_CONFIG_VERSION = 1;
|
|
29696
29845
|
function neatHome3() {
|
|
29697
29846
|
const override = process.env.NEAT_HOME;
|
|
29698
|
-
if (override && override.length > 0) return
|
|
29699
|
-
return
|
|
29847
|
+
if (override && override.length > 0) return import_node_path91.default.resolve(override);
|
|
29848
|
+
return import_node_path91.default.join(import_node_os7.default.homedir(), ".neat");
|
|
29700
29849
|
}
|
|
29701
29850
|
function profilesConfigPath(home = neatHome3()) {
|
|
29702
|
-
return
|
|
29851
|
+
return import_node_path91.default.join(home, "profiles.json");
|
|
29703
29852
|
}
|
|
29704
29853
|
function profilesConfigLockPath(home = neatHome3()) {
|
|
29705
|
-
return
|
|
29854
|
+
return import_node_path91.default.join(home, "profiles.json.lock");
|
|
29706
29855
|
}
|
|
29707
29856
|
var MODE_MASK_LOOSER_THAN_06002 = 63;
|
|
29708
29857
|
async function warnIfModeLooserThan06002(file) {
|
|
@@ -29820,7 +29969,7 @@ function serialize(config) {
|
|
|
29820
29969
|
}
|
|
29821
29970
|
async function writeConfigAtomic(config, home) {
|
|
29822
29971
|
const file = profilesConfigPath(home);
|
|
29823
|
-
await import_node_fs53.promises.mkdir(
|
|
29972
|
+
await import_node_fs53.promises.mkdir(import_node_path91.default.dirname(file), { recursive: true });
|
|
29824
29973
|
const tmp = `${file}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
|
|
29825
29974
|
const fd = await import_node_fs53.promises.open(tmp, "w", 384);
|
|
29826
29975
|
try {
|
|
@@ -29834,7 +29983,7 @@ async function writeConfigAtomic(config, home) {
|
|
|
29834
29983
|
var LOCK_RETRY_MS2 = 50;
|
|
29835
29984
|
var LOCK_TIMEOUT_MS2 = 5e3;
|
|
29836
29985
|
async function acquireLock2(lockPath) {
|
|
29837
|
-
await import_node_fs53.promises.mkdir(
|
|
29986
|
+
await import_node_fs53.promises.mkdir(import_node_path91.default.dirname(lockPath), { recursive: true });
|
|
29838
29987
|
const deadline = Date.now() + LOCK_TIMEOUT_MS2;
|
|
29839
29988
|
for (; ; ) {
|
|
29840
29989
|
try {
|
|
@@ -30194,11 +30343,11 @@ async function runConnectCommand(rawArgs, deps = {}) {
|
|
|
30194
30343
|
// src/doctor-cli.ts
|
|
30195
30344
|
init_cjs_shims();
|
|
30196
30345
|
var import_node_fs54 = require("fs");
|
|
30197
|
-
var
|
|
30346
|
+
var import_node_path92 = __toESM(require("path"), 1);
|
|
30198
30347
|
|
|
30199
30348
|
// src/cli-client.ts
|
|
30200
30349
|
init_cjs_shims();
|
|
30201
|
-
var
|
|
30350
|
+
var import_types110 = require("@neat.is/types");
|
|
30202
30351
|
var HttpError = class extends Error {
|
|
30203
30352
|
constructor(status2, message, responseBody = "") {
|
|
30204
30353
|
super(message);
|
|
@@ -30340,7 +30489,7 @@ async function runBlastRadius(client, input) {
|
|
|
30340
30489
|
}
|
|
30341
30490
|
}
|
|
30342
30491
|
function formatBlastEntry(n) {
|
|
30343
|
-
const tag = n.edgeProvenance ===
|
|
30492
|
+
const tag = n.edgeProvenance === import_types110.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
|
|
30344
30493
|
return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
|
|
30345
30494
|
}
|
|
30346
30495
|
async function runDependencies(client, input) {
|
|
@@ -30397,7 +30546,7 @@ async function runObservedDependencies(client, input) {
|
|
|
30397
30546
|
if (result.observed) {
|
|
30398
30547
|
return {
|
|
30399
30548
|
summary: `${input.nodeId} makes no outbound runtime calls, but OTel has observed it receiving traffic on ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 it's a pure receiver.`,
|
|
30400
|
-
provenance:
|
|
30549
|
+
provenance: import_types110.Provenance.OBSERVED
|
|
30401
30550
|
};
|
|
30402
30551
|
}
|
|
30403
30552
|
const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
|
|
@@ -30407,7 +30556,7 @@ async function runObservedDependencies(client, input) {
|
|
|
30407
30556
|
return {
|
|
30408
30557
|
summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
|
|
30409
30558
|
block: blockLines.join("\n"),
|
|
30410
|
-
provenance:
|
|
30559
|
+
provenance: import_types110.Provenance.OBSERVED
|
|
30411
30560
|
};
|
|
30412
30561
|
} catch (err) {
|
|
30413
30562
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -30461,7 +30610,7 @@ async function runIncidents(client, input) {
|
|
|
30461
30610
|
return {
|
|
30462
30611
|
summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
|
|
30463
30612
|
block: blockLines.join("\n"),
|
|
30464
|
-
provenance:
|
|
30613
|
+
provenance: import_types110.Provenance.OBSERVED
|
|
30465
30614
|
};
|
|
30466
30615
|
} catch (err) {
|
|
30467
30616
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -30570,7 +30719,7 @@ async function runStaleEdges(client, input) {
|
|
|
30570
30719
|
return {
|
|
30571
30720
|
summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
|
|
30572
30721
|
block: blockLines.join("\n"),
|
|
30573
|
-
provenance:
|
|
30722
|
+
provenance: import_types110.Provenance.STALE
|
|
30574
30723
|
};
|
|
30575
30724
|
}
|
|
30576
30725
|
async function runPolicies(client, input) {
|
|
@@ -30808,7 +30957,7 @@ function checkNode(nodeVersion) {
|
|
|
30808
30957
|
}
|
|
30809
30958
|
async function neatOutExists(cwd) {
|
|
30810
30959
|
try {
|
|
30811
|
-
const st = await import_node_fs54.promises.stat(
|
|
30960
|
+
const st = await import_node_fs54.promises.stat(import_node_path92.default.join(cwd, "neat-out"));
|
|
30812
30961
|
return st.isDirectory();
|
|
30813
30962
|
} catch {
|
|
30814
30963
|
return false;
|
|
@@ -30927,7 +31076,7 @@ async function runDoctorCommand(argv, deps = {}) {
|
|
|
30927
31076
|
|
|
30928
31077
|
// src/login-cli.ts
|
|
30929
31078
|
init_cjs_shims();
|
|
30930
|
-
var
|
|
31079
|
+
var import_promises4 = __toESM(require("readline/promises"), 1);
|
|
30931
31080
|
var PROBE_ATTEMPT_TIMEOUT_MS = 3e4;
|
|
30932
31081
|
var PROBE_TOTAL_BUDGET_MS = 12e4;
|
|
30933
31082
|
var PROBE_RETRY_PAUSE_MS = 2e3;
|
|
@@ -31180,7 +31329,7 @@ async function runLogoutCommand(argv, deps = {}) {
|
|
|
31180
31329
|
}
|
|
31181
31330
|
async function defaultReadLine(prompt) {
|
|
31182
31331
|
if (!process.stdin.isTTY) return void 0;
|
|
31183
|
-
const rl =
|
|
31332
|
+
const rl = import_promises4.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
31184
31333
|
try {
|
|
31185
31334
|
return await rl.question(prompt);
|
|
31186
31335
|
} finally {
|
|
@@ -31223,7 +31372,7 @@ async function defaultReadSecret(prompt) {
|
|
|
31223
31372
|
|
|
31224
31373
|
// src/welcome.ts
|
|
31225
31374
|
init_cjs_shims();
|
|
31226
|
-
var
|
|
31375
|
+
var import_promises5 = __toESM(require("readline/promises"), 1);
|
|
31227
31376
|
var WORDMARK = [
|
|
31228
31377
|
"\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
31229
31378
|
"\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D",
|
|
@@ -31306,7 +31455,7 @@ async function shouldShowWelcome(deps = {}) {
|
|
|
31306
31455
|
}
|
|
31307
31456
|
async function defaultReadLine2(prompt) {
|
|
31308
31457
|
if (!process.stdin.isTTY) return void 0;
|
|
31309
|
-
const rl =
|
|
31458
|
+
const rl = import_promises5.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
31310
31459
|
try {
|
|
31311
31460
|
return await rl.question(prompt);
|
|
31312
31461
|
} finally {
|
|
@@ -31316,7 +31465,7 @@ async function defaultReadLine2(prompt) {
|
|
|
31316
31465
|
|
|
31317
31466
|
// src/hooks-cli.ts
|
|
31318
31467
|
init_cjs_shims();
|
|
31319
|
-
var
|
|
31468
|
+
var import_node_path93 = __toESM(require("path"), 1);
|
|
31320
31469
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
31321
31470
|
var import_node_fs55 = require("fs");
|
|
31322
31471
|
var import_node_url5 = require("url");
|
|
@@ -31325,14 +31474,14 @@ var GUIDE_FILENAME = "GRAPH_FIRST.md";
|
|
|
31325
31474
|
var GUIDE_INSTALL_NAME = "neat-graph-first.md";
|
|
31326
31475
|
var HOOK_MATCHER = "Grep|Glob|Bash";
|
|
31327
31476
|
function moduleDir() {
|
|
31328
|
-
return typeof __dirname !== "undefined" ? __dirname :
|
|
31477
|
+
return typeof __dirname !== "undefined" ? __dirname : import_node_path93.default.dirname((0, import_node_url5.fileURLToPath)(importMetaUrl));
|
|
31329
31478
|
}
|
|
31330
31479
|
async function readSkillAsset(rel) {
|
|
31331
31480
|
const here = moduleDir();
|
|
31332
31481
|
const candidates = [
|
|
31333
|
-
|
|
31334
|
-
|
|
31335
|
-
|
|
31482
|
+
import_node_path93.default.resolve(here, "../../claude-skill", rel),
|
|
31483
|
+
import_node_path93.default.resolve(here, "../../../claude-skill", rel),
|
|
31484
|
+
import_node_path93.default.resolve(here, "../claude-skill", rel)
|
|
31336
31485
|
];
|
|
31337
31486
|
for (const candidate of candidates) {
|
|
31338
31487
|
try {
|
|
@@ -31346,20 +31495,20 @@ async function readSkillAsset(rel) {
|
|
|
31346
31495
|
}
|
|
31347
31496
|
function neatHome4() {
|
|
31348
31497
|
const override = process.env.NEAT_HOME;
|
|
31349
|
-
if (override && override.length > 0) return
|
|
31350
|
-
return
|
|
31498
|
+
if (override && override.length > 0) return import_node_path93.default.resolve(override);
|
|
31499
|
+
return import_node_path93.default.join(import_node_os8.default.homedir(), ".neat");
|
|
31351
31500
|
}
|
|
31352
31501
|
function claudeSettingsPath() {
|
|
31353
31502
|
const override = process.env.NEAT_CLAUDE_SETTINGS;
|
|
31354
|
-
if (override && override.length > 0) return
|
|
31503
|
+
if (override && override.length > 0) return import_node_path93.default.resolve(override);
|
|
31355
31504
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? import_node_os8.default.homedir();
|
|
31356
|
-
return
|
|
31505
|
+
return import_node_path93.default.join(home, ".claude", "settings.json");
|
|
31357
31506
|
}
|
|
31358
31507
|
function installedHookPath() {
|
|
31359
|
-
return
|
|
31508
|
+
return import_node_path93.default.join(neatHome4(), "hooks", HOOK_FILENAME);
|
|
31360
31509
|
}
|
|
31361
31510
|
function gateFlagPath() {
|
|
31362
|
-
return
|
|
31511
|
+
return import_node_path93.default.join(neatHome4(), "hooks", "gate-enabled");
|
|
31363
31512
|
}
|
|
31364
31513
|
function isNeatSearchEntry(entry2) {
|
|
31365
31514
|
return (entry2.hooks ?? []).some(
|
|
@@ -31392,9 +31541,9 @@ async function runHooks(opts) {
|
|
|
31392
31541
|
const hookScript = await readSkillAsset(`hooks/${HOOK_FILENAME}`);
|
|
31393
31542
|
const guide = await readSkillAsset(GUIDE_FILENAME);
|
|
31394
31543
|
const scriptPath = installedHookPath();
|
|
31395
|
-
await import_node_fs55.promises.mkdir(
|
|
31544
|
+
await import_node_fs55.promises.mkdir(import_node_path93.default.dirname(scriptPath), { recursive: true });
|
|
31396
31545
|
await import_node_fs55.promises.writeFile(scriptPath, hookScript, { mode: 493 });
|
|
31397
|
-
const guidePath =
|
|
31546
|
+
const guidePath = import_node_path93.default.join(neatHome4(), GUIDE_INSTALL_NAME);
|
|
31398
31547
|
await import_node_fs55.promises.writeFile(guidePath, guide, "utf8");
|
|
31399
31548
|
const settingsFile = claudeSettingsPath();
|
|
31400
31549
|
let settings = {};
|
|
@@ -31421,11 +31570,11 @@ async function runHooks(opts) {
|
|
|
31421
31570
|
...settings,
|
|
31422
31571
|
hooks: { ...hooks, PreToolUse: preToolUse }
|
|
31423
31572
|
};
|
|
31424
|
-
await import_node_fs55.promises.mkdir(
|
|
31573
|
+
await import_node_fs55.promises.mkdir(import_node_path93.default.dirname(settingsFile), { recursive: true });
|
|
31425
31574
|
await import_node_fs55.promises.writeFile(settingsFile, JSON.stringify(merged, null, 2) + "\n", "utf8");
|
|
31426
31575
|
const flag = gateFlagPath();
|
|
31427
31576
|
if (opts.gate) {
|
|
31428
|
-
await import_node_fs55.promises.mkdir(
|
|
31577
|
+
await import_node_fs55.promises.mkdir(import_node_path93.default.dirname(flag), { recursive: true });
|
|
31429
31578
|
await import_node_fs55.promises.writeFile(flag, "1\n", "utf8");
|
|
31430
31579
|
} else {
|
|
31431
31580
|
await import_node_fs55.promises.rm(flag, { force: true });
|
|
@@ -31518,7 +31667,7 @@ async function runHooksCommand(args) {
|
|
|
31518
31667
|
|
|
31519
31668
|
// src/claude-cli.ts
|
|
31520
31669
|
init_cjs_shims();
|
|
31521
|
-
var
|
|
31670
|
+
var import_node_path94 = __toESM(require("path"), 1);
|
|
31522
31671
|
var import_node_fs56 = require("fs");
|
|
31523
31672
|
var NEAT_SECTION_HEADING = "## neat";
|
|
31524
31673
|
var NEAT_DIRECTIVE_BODY = `This project has NEAT wired in: a live, fused semantic graph of the system \u2014
|
|
@@ -31553,8 +31702,8 @@ ${NEAT_DIRECTIVE_BODY}
|
|
|
31553
31702
|
}
|
|
31554
31703
|
function claudeMdPath() {
|
|
31555
31704
|
const override = process.env.NEAT_CLAUDE_MD;
|
|
31556
|
-
if (override && override.length > 0) return
|
|
31557
|
-
return
|
|
31705
|
+
if (override && override.length > 0) return import_node_path94.default.resolve(override);
|
|
31706
|
+
return import_node_path94.default.join(process.cwd(), "CLAUDE.md");
|
|
31558
31707
|
}
|
|
31559
31708
|
function splitAroundSection(raw) {
|
|
31560
31709
|
const lines = raw.split("\n");
|
|
@@ -31593,7 +31742,7 @@ async function runInstall() {
|
|
|
31593
31742
|
const raw = await readIfExists2(file) ?? "";
|
|
31594
31743
|
const { before, after, found } = splitAroundSection(raw);
|
|
31595
31744
|
const next = compose(before, after);
|
|
31596
|
-
await import_node_fs56.promises.mkdir(
|
|
31745
|
+
await import_node_fs56.promises.mkdir(import_node_path94.default.dirname(file), { recursive: true });
|
|
31597
31746
|
await import_node_fs56.promises.writeFile(file, next, "utf8");
|
|
31598
31747
|
const verb = raw.length === 0 ? "created" : found ? "refreshed" : "added";
|
|
31599
31748
|
console.log(`neat claude: ${verb} the \`${NEAT_SECTION_HEADING}\` section in ${file}`);
|
|
@@ -31658,7 +31807,7 @@ async function runClaudeCommand(args) {
|
|
|
31658
31807
|
|
|
31659
31808
|
// src/codex-cli.ts
|
|
31660
31809
|
init_cjs_shims();
|
|
31661
|
-
var
|
|
31810
|
+
var import_node_path95 = __toESM(require("path"), 1);
|
|
31662
31811
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
31663
31812
|
var import_node_fs57 = require("fs");
|
|
31664
31813
|
var import_node_util = require("util");
|
|
@@ -31678,14 +31827,14 @@ var NEAT_GRAPH_FIRST_START = "<!-- neat:graph-first -->";
|
|
|
31678
31827
|
var NEAT_GRAPH_FIRST_END = "<!-- /neat:graph-first -->";
|
|
31679
31828
|
function codexConfigPath() {
|
|
31680
31829
|
const override = process.env.NEAT_CODEX_CONFIG;
|
|
31681
|
-
if (override && override.length > 0) return
|
|
31830
|
+
if (override && override.length > 0) return import_node_path95.default.resolve(override);
|
|
31682
31831
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? import_node_os9.default.homedir();
|
|
31683
|
-
return
|
|
31832
|
+
return import_node_path95.default.join(home, ".codex", "config.toml");
|
|
31684
31833
|
}
|
|
31685
31834
|
function agentsFilePath() {
|
|
31686
31835
|
const override = process.env.NEAT_CODEX_AGENTS;
|
|
31687
|
-
if (override && override.length > 0) return
|
|
31688
|
-
return
|
|
31836
|
+
if (override && override.length > 0) return import_node_path95.default.resolve(override);
|
|
31837
|
+
return import_node_path95.default.join(process.cwd(), "AGENTS.md");
|
|
31689
31838
|
}
|
|
31690
31839
|
function isTableHeader(line) {
|
|
31691
31840
|
return /^\s*\[\[?[^\]]+\]\]?\s*$/.test(line);
|
|
@@ -31868,14 +32017,14 @@ async function runCodex(opts) {
|
|
|
31868
32017
|
return { exitCode: 0 };
|
|
31869
32018
|
}
|
|
31870
32019
|
if (config.changed) {
|
|
31871
|
-
await import_node_fs57.promises.mkdir(
|
|
32020
|
+
await import_node_fs57.promises.mkdir(import_node_path95.default.dirname(configPath), { recursive: true });
|
|
31872
32021
|
await import_node_fs57.promises.writeFile(configPath, config.text, "utf8");
|
|
31873
32022
|
console.log(`neat codex: wrote [mcp_servers.neat] to ${configPath}`);
|
|
31874
32023
|
} else {
|
|
31875
32024
|
console.log(`neat codex: ${configPath} already has NEAT's MCP server`);
|
|
31876
32025
|
}
|
|
31877
32026
|
if (agents.changed) {
|
|
31878
|
-
await import_node_fs57.promises.mkdir(
|
|
32027
|
+
await import_node_fs57.promises.mkdir(import_node_path95.default.dirname(agentsPath), { recursive: true });
|
|
31879
32028
|
await import_node_fs57.promises.writeFile(agentsPath, agents.text, "utf8");
|
|
31880
32029
|
console.log(`neat codex: wrote the graph-first block to ${agentsPath}`);
|
|
31881
32030
|
} else {
|
|
@@ -31933,7 +32082,7 @@ async function runCodexCommand(args) {
|
|
|
31933
32082
|
|
|
31934
32083
|
// src/editors-cli.ts
|
|
31935
32084
|
init_cjs_shims();
|
|
31936
|
-
var
|
|
32085
|
+
var import_node_path96 = __toESM(require("path"), 1);
|
|
31937
32086
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
31938
32087
|
var import_node_fs58 = require("fs");
|
|
31939
32088
|
var import_node_util2 = require("util");
|
|
@@ -31959,17 +32108,17 @@ function homeDir() {
|
|
|
31959
32108
|
}
|
|
31960
32109
|
function xdgConfigDir() {
|
|
31961
32110
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
31962
|
-
return xdg && xdg.length > 0 ?
|
|
32111
|
+
return xdg && xdg.length > 0 ? import_node_path96.default.resolve(xdg) : import_node_path96.default.join(homeDir(), ".config");
|
|
31963
32112
|
}
|
|
31964
32113
|
function envOverride(name) {
|
|
31965
32114
|
const v = process.env[name];
|
|
31966
|
-
return v && v.length > 0 ?
|
|
32115
|
+
return v && v.length > 0 ? import_node_path96.default.resolve(v) : void 0;
|
|
31967
32116
|
}
|
|
31968
32117
|
var CURSOR_CLIENT = {
|
|
31969
32118
|
id: "cursor",
|
|
31970
32119
|
label: "Cursor",
|
|
31971
32120
|
docsUrl: "https://docs.cursor.com/context/mcp",
|
|
31972
|
-
mcpConfigPath: () => envOverride("NEAT_CURSOR_CONFIG") ??
|
|
32121
|
+
mcpConfigPath: () => envOverride("NEAT_CURSOR_CONFIG") ?? import_node_path96.default.join(homeDir(), ".cursor", "mcp.json"),
|
|
31973
32122
|
mcpContainerKey: "mcpServers",
|
|
31974
32123
|
format: "json",
|
|
31975
32124
|
// Cursor still reads a single `.cursorrules` at the project root (the modern
|
|
@@ -31981,7 +32130,7 @@ var DEVIN_CLIENT = {
|
|
|
31981
32130
|
id: "devin",
|
|
31982
32131
|
label: "Devin Desktop (Cascade)",
|
|
31983
32132
|
docsUrl: "https://docs.devin.ai/desktop/cascade/mcp",
|
|
31984
|
-
mcpConfigPath: () => envOverride("NEAT_DEVIN_CONFIG") ??
|
|
32133
|
+
mcpConfigPath: () => envOverride("NEAT_DEVIN_CONFIG") ?? import_node_path96.default.join(homeDir(), ".codeium", "windsurf", "mcp_config.json"),
|
|
31985
32134
|
mcpContainerKey: "mcpServers",
|
|
31986
32135
|
format: "json",
|
|
31987
32136
|
rulesFileName: ".windsurfrules"
|
|
@@ -31990,7 +32139,7 @@ var GEMINI_CLIENT = {
|
|
|
31990
32139
|
id: "gemini",
|
|
31991
32140
|
label: "Gemini CLI",
|
|
31992
32141
|
docsUrl: "https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md",
|
|
31993
|
-
mcpConfigPath: () => envOverride("NEAT_GEMINI_CONFIG") ??
|
|
32142
|
+
mcpConfigPath: () => envOverride("NEAT_GEMINI_CONFIG") ?? import_node_path96.default.join(homeDir(), ".gemini", "settings.json"),
|
|
31994
32143
|
mcpContainerKey: "mcpServers",
|
|
31995
32144
|
format: "json",
|
|
31996
32145
|
rulesFileName: "GEMINI.md"
|
|
@@ -31999,7 +32148,7 @@ var QWEN_CLIENT = {
|
|
|
31999
32148
|
id: "qwen",
|
|
32000
32149
|
label: "Qwen Code",
|
|
32001
32150
|
docsUrl: "https://qwenlm.github.io/qwen-code-docs/en/users/features/mcp/",
|
|
32002
|
-
mcpConfigPath: () => envOverride("NEAT_QWEN_CONFIG") ??
|
|
32151
|
+
mcpConfigPath: () => envOverride("NEAT_QWEN_CONFIG") ?? import_node_path96.default.join(homeDir(), ".qwen", "settings.json"),
|
|
32003
32152
|
mcpContainerKey: "mcpServers",
|
|
32004
32153
|
format: "json",
|
|
32005
32154
|
rulesFileName: "QWEN.md"
|
|
@@ -32008,7 +32157,7 @@ var AMAZONQ_CLIENT = {
|
|
|
32008
32157
|
id: "amazonq",
|
|
32009
32158
|
label: "Amazon Q Developer CLI",
|
|
32010
32159
|
docsUrl: "https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-mcp-configuration.html",
|
|
32011
|
-
mcpConfigPath: () => envOverride("NEAT_AMAZONQ_CONFIG") ??
|
|
32160
|
+
mcpConfigPath: () => envOverride("NEAT_AMAZONQ_CONFIG") ?? import_node_path96.default.join(homeDir(), ".aws", "amazonq", "mcp.json"),
|
|
32012
32161
|
mcpContainerKey: "mcpServers",
|
|
32013
32162
|
format: "json"
|
|
32014
32163
|
};
|
|
@@ -32016,7 +32165,7 @@ var ROOCODE_CLIENT = {
|
|
|
32016
32165
|
id: "roocode",
|
|
32017
32166
|
label: "Roo Code",
|
|
32018
32167
|
docsUrl: "https://roocodeinc.github.io/Roo-Code/features/mcp/using-mcp-in-roo",
|
|
32019
|
-
mcpConfigPath: () => envOverride("NEAT_ROOCODE_CONFIG") ??
|
|
32168
|
+
mcpConfigPath: () => envOverride("NEAT_ROOCODE_CONFIG") ?? import_node_path96.default.join(process.cwd(), ".roo", "mcp.json"),
|
|
32020
32169
|
mcpContainerKey: "mcpServers",
|
|
32021
32170
|
format: "json"
|
|
32022
32171
|
};
|
|
@@ -32029,9 +32178,9 @@ var ZED_CLIENT = {
|
|
|
32029
32178
|
if (override) return override;
|
|
32030
32179
|
if (process.platform === "win32") {
|
|
32031
32180
|
const appData = process.env.APPDATA;
|
|
32032
|
-
if (appData && appData.length > 0) return
|
|
32181
|
+
if (appData && appData.length > 0) return import_node_path96.default.join(appData, "Zed", "settings.json");
|
|
32033
32182
|
}
|
|
32034
|
-
return
|
|
32183
|
+
return import_node_path96.default.join(homeDir(), ".config", "zed", "settings.json");
|
|
32035
32184
|
},
|
|
32036
32185
|
mcpContainerKey: "context_servers",
|
|
32037
32186
|
format: "jsonc",
|
|
@@ -32041,7 +32190,7 @@ var OPENCODE_CLIENT = {
|
|
|
32041
32190
|
id: "opencode",
|
|
32042
32191
|
label: "OpenCode",
|
|
32043
32192
|
docsUrl: "https://opencode.ai/docs/mcp-servers/",
|
|
32044
|
-
mcpConfigPath: () => envOverride("NEAT_OPENCODE_CONFIG") ??
|
|
32193
|
+
mcpConfigPath: () => envOverride("NEAT_OPENCODE_CONFIG") ?? import_node_path96.default.join(xdgConfigDir(), "opencode", "opencode.json"),
|
|
32045
32194
|
mcpContainerKey: "mcp",
|
|
32046
32195
|
format: "json",
|
|
32047
32196
|
serverEntry: NEAT_OPENCODE_SERVER,
|
|
@@ -32051,7 +32200,7 @@ var CRUSH_CLIENT = {
|
|
|
32051
32200
|
id: "crush",
|
|
32052
32201
|
label: "Crush",
|
|
32053
32202
|
docsUrl: "https://charmbracelet-crush.mintlify.app/configuration/mcp",
|
|
32054
|
-
mcpConfigPath: () => envOverride("NEAT_CRUSH_CONFIG") ??
|
|
32203
|
+
mcpConfigPath: () => envOverride("NEAT_CRUSH_CONFIG") ?? import_node_path96.default.join(xdgConfigDir(), "crush", "crush.json"),
|
|
32055
32204
|
mcpContainerKey: "mcp",
|
|
32056
32205
|
format: "json",
|
|
32057
32206
|
serverEntry: NEAT_CRUSH_SERVER,
|
|
@@ -32156,7 +32305,7 @@ async function runEditorInstall(client, opts) {
|
|
|
32156
32305
|
const mcpPath = client.mcpConfigPath();
|
|
32157
32306
|
const serverEntry = client.serverEntry ?? NEAT_MCP_SERVER;
|
|
32158
32307
|
const hasRules = typeof client.rulesFileName === "string";
|
|
32159
|
-
const rulesPath = hasRules ?
|
|
32308
|
+
const rulesPath = hasRules ? import_node_path96.default.join(opts.projectDir, client.rulesFileName) : "";
|
|
32160
32309
|
const mcp = await planMcp(client, mcpPath);
|
|
32161
32310
|
if (mcp === null) return { exitCode: 1 };
|
|
32162
32311
|
let existingRules = "";
|
|
@@ -32199,10 +32348,10 @@ async function runEditorInstall(client, opts) {
|
|
|
32199
32348
|
);
|
|
32200
32349
|
return { exitCode: 0 };
|
|
32201
32350
|
}
|
|
32202
|
-
await import_node_fs58.promises.mkdir(
|
|
32351
|
+
await import_node_fs58.promises.mkdir(import_node_path96.default.dirname(mcpPath), { recursive: true });
|
|
32203
32352
|
await import_node_fs58.promises.writeFile(mcpPath, mcp.text, "utf8");
|
|
32204
32353
|
if (hasRules) {
|
|
32205
|
-
await import_node_fs58.promises.mkdir(
|
|
32354
|
+
await import_node_fs58.promises.mkdir(import_node_path96.default.dirname(rulesPath), { recursive: true });
|
|
32206
32355
|
await import_node_fs58.promises.writeFile(rulesPath, newRules, "utf8");
|
|
32207
32356
|
}
|
|
32208
32357
|
console.log(`neat ${client.id}: wired NEAT into ${client.label}`);
|
|
@@ -32266,12 +32415,12 @@ async function runEditorCommand(clientId, args, projectDir = process.cwd()) {
|
|
|
32266
32415
|
|
|
32267
32416
|
// src/monitor.ts
|
|
32268
32417
|
init_cjs_shims();
|
|
32269
|
-
var
|
|
32418
|
+
var import_types111 = require("@neat.is/types");
|
|
32270
32419
|
var OBSERVED_DEP_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
32271
|
-
|
|
32272
|
-
|
|
32273
|
-
|
|
32274
|
-
|
|
32420
|
+
import_types111.EdgeType.CALLS,
|
|
32421
|
+
import_types111.EdgeType.CONNECTS_TO,
|
|
32422
|
+
import_types111.EdgeType.PUBLISHES_TO,
|
|
32423
|
+
import_types111.EdgeType.CONSUMES_FROM
|
|
32275
32424
|
]);
|
|
32276
32425
|
function divergenceKey(d) {
|
|
32277
32426
|
const column = "column" in d && d.column ? d.column : "";
|
|
@@ -32341,7 +32490,7 @@ function formatDivergenceLine2(d) {
|
|
|
32341
32490
|
}
|
|
32342
32491
|
}
|
|
32343
32492
|
function formatStaleLine(edgeId) {
|
|
32344
|
-
const parsed = (0,
|
|
32493
|
+
const parsed = (0, import_types111.parseEdgeId)(edgeId);
|
|
32345
32494
|
if (parsed) {
|
|
32346
32495
|
return `\u22EF stale ${parsed.source} \u2192 ${parsed.target} (observed edge went quiet)`;
|
|
32347
32496
|
}
|
|
@@ -32354,7 +32503,7 @@ function divergenceJson(d) {
|
|
|
32354
32503
|
return JSON.stringify({ kind: "divergence", ...d });
|
|
32355
32504
|
}
|
|
32356
32505
|
function staleJson(edgeId) {
|
|
32357
|
-
const parsed = (0,
|
|
32506
|
+
const parsed = (0, import_types111.parseEdgeId)(edgeId);
|
|
32358
32507
|
return JSON.stringify({
|
|
32359
32508
|
kind: "stale",
|
|
32360
32509
|
edgeId,
|
|
@@ -32437,7 +32586,7 @@ var MonitorEmitter = class {
|
|
|
32437
32586
|
// ignores non-OBSERVED edges and non-dependency edge types (structural
|
|
32438
32587
|
// ownership), so only real runtime dependencies reach stdout.
|
|
32439
32588
|
emitObservedEdge(edge) {
|
|
32440
|
-
if (edge.provenance !==
|
|
32589
|
+
if (edge.provenance !== import_types111.Provenance.OBSERVED) return false;
|
|
32441
32590
|
if (!OBSERVED_DEP_EDGE_TYPES.has(edge.type)) return false;
|
|
32442
32591
|
const key = `edge|${edge.id}`;
|
|
32443
32592
|
if (this.seen.has(key)) return false;
|
|
@@ -32618,7 +32767,7 @@ async function runMonitor(opts) {
|
|
|
32618
32767
|
case "edge-added": {
|
|
32619
32768
|
const payload = safeParse(frame.data);
|
|
32620
32769
|
const edge = payload?.edge;
|
|
32621
|
-
if (edge && edge.provenance ===
|
|
32770
|
+
if (edge && edge.provenance === import_types111.Provenance.OBSERVED) {
|
|
32622
32771
|
emitter.emitObservedEdge(edge);
|
|
32623
32772
|
divergences.schedule();
|
|
32624
32773
|
}
|
|
@@ -32705,7 +32854,7 @@ function sleep(ms, signal) {
|
|
|
32705
32854
|
|
|
32706
32855
|
// src/cli-verbs.ts
|
|
32707
32856
|
init_cjs_shims();
|
|
32708
|
-
var
|
|
32857
|
+
var import_node_path97 = __toESM(require("path"), 1);
|
|
32709
32858
|
async function resolveProjectEntry(opts) {
|
|
32710
32859
|
const entries = await listProjects();
|
|
32711
32860
|
if (opts.project) {
|
|
@@ -32715,7 +32864,7 @@ async function resolveProjectEntry(opts) {
|
|
|
32715
32864
|
const cwd = opts.cwd ?? process.cwd();
|
|
32716
32865
|
const resolvedCwd = await normalizeProjectPath(cwd);
|
|
32717
32866
|
for (const entry2 of entries) {
|
|
32718
|
-
if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${
|
|
32867
|
+
if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${import_node_path97.default.sep}`)) {
|
|
32719
32868
|
return entry2;
|
|
32720
32869
|
}
|
|
32721
32870
|
}
|
|
@@ -32889,7 +33038,7 @@ async function runSync(opts) {
|
|
|
32889
33038
|
}
|
|
32890
33039
|
|
|
32891
33040
|
// src/cli.ts
|
|
32892
|
-
var
|
|
33041
|
+
var import_types112 = require("@neat.is/types");
|
|
32893
33042
|
function usage5() {
|
|
32894
33043
|
const neat = commandPrefix();
|
|
32895
33044
|
console.log("Installed via npx? Prefix commands with `npx neat.is`, or install once: `npm i -g neat.is`.");
|
|
@@ -33301,12 +33450,12 @@ async function runInit(opts) {
|
|
|
33301
33450
|
printDiscoveryReport(opts, services);
|
|
33302
33451
|
const sections = opts.noInstall ? [] : await buildPatchSections(services, opts.project);
|
|
33303
33452
|
const patch = renderPatch(sections);
|
|
33304
|
-
const patchPath =
|
|
33453
|
+
const patchPath = import_node_path98.default.join(opts.scanPath, "neat.patch");
|
|
33305
33454
|
if (opts.dryRun) {
|
|
33306
33455
|
await import_node_fs59.promises.writeFile(patchPath, patch, "utf8");
|
|
33307
33456
|
written.push(patchPath);
|
|
33308
33457
|
console.log(`dry-run: patch written to ${patchPath}`);
|
|
33309
|
-
const gitignorePath =
|
|
33458
|
+
const gitignorePath = import_node_path98.default.join(opts.scanPath, ".gitignore");
|
|
33310
33459
|
const gitignoreExists = await import_node_fs59.promises.stat(gitignorePath).then(() => true).catch(() => false);
|
|
33311
33460
|
const verb = gitignoreExists ? "append" : "create";
|
|
33312
33461
|
console.log(`dry-run: would ${verb} ${gitignorePath} (add neat-out/)`);
|
|
@@ -33318,9 +33467,9 @@ async function runInit(opts) {
|
|
|
33318
33467
|
const graph = getGraph(graphKey);
|
|
33319
33468
|
const projectPaths = pathsForProject(
|
|
33320
33469
|
graphKey,
|
|
33321
|
-
|
|
33470
|
+
import_node_path98.default.join(opts.scanPath, "neat-out")
|
|
33322
33471
|
);
|
|
33323
|
-
const errorsPath =
|
|
33472
|
+
const errorsPath = import_node_path98.default.join(import_node_path98.default.dirname(opts.outPath), import_node_path98.default.basename(projectPaths.errorsPath));
|
|
33324
33473
|
const result = await extractFromDirectory(graph, opts.scanPath, { errorsPath });
|
|
33325
33474
|
await saveGraphToDisk(graph, opts.outPath);
|
|
33326
33475
|
written.push(opts.outPath);
|
|
@@ -33440,9 +33589,9 @@ var CLAUDE_SKILL_CONFIG = {
|
|
|
33440
33589
|
};
|
|
33441
33590
|
function claudeConfigPath() {
|
|
33442
33591
|
const override = process.env.NEAT_CLAUDE_CONFIG;
|
|
33443
|
-
if (override && override.length > 0) return
|
|
33592
|
+
if (override && override.length > 0) return import_node_path98.default.resolve(override);
|
|
33444
33593
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
33445
|
-
return
|
|
33594
|
+
return import_node_path98.default.join(home, ".claude.json");
|
|
33446
33595
|
}
|
|
33447
33596
|
async function runSkill(opts) {
|
|
33448
33597
|
const snippet2 = JSON.stringify(CLAUDE_SKILL_CONFIG, null, 2) + "\n";
|
|
@@ -33466,7 +33615,7 @@ async function runSkill(opts) {
|
|
|
33466
33615
|
...existing,
|
|
33467
33616
|
mcpServers: { ...mcp, neat: CLAUDE_SKILL_CONFIG.mcpServers.neat }
|
|
33468
33617
|
};
|
|
33469
|
-
await import_node_fs59.promises.mkdir(
|
|
33618
|
+
await import_node_fs59.promises.mkdir(import_node_path98.default.dirname(target), { recursive: true });
|
|
33470
33619
|
await import_node_fs59.promises.writeFile(target, JSON.stringify(merged, null, 2) + "\n", "utf8");
|
|
33471
33620
|
console.log(`neat skill: wrote mcpServers.neat to ${target}`);
|
|
33472
33621
|
console.log("restart Claude Code to pick up the new MCP server.");
|
|
@@ -33588,12 +33737,12 @@ async function main() {
|
|
|
33588
33737
|
console.error("neat init: --apply and --dry-run are mutually exclusive");
|
|
33589
33738
|
process.exit(2);
|
|
33590
33739
|
}
|
|
33591
|
-
const scanPath =
|
|
33740
|
+
const scanPath = import_node_path98.default.resolve(target);
|
|
33592
33741
|
const projectExplicit = parsed.project !== null;
|
|
33593
|
-
const projectName = projectExplicit ? project :
|
|
33742
|
+
const projectName = projectExplicit ? project : import_node_path98.default.basename(scanPath);
|
|
33594
33743
|
const projectKey = projectExplicit ? project : DEFAULT_PROJECT;
|
|
33595
|
-
const fallback = pathsForProject(projectKey,
|
|
33596
|
-
const outPath =
|
|
33744
|
+
const fallback = pathsForProject(projectKey, import_node_path98.default.join(scanPath, "neat-out")).snapshotPath;
|
|
33745
|
+
const outPath = import_node_path98.default.resolve(process.env.NEAT_OUT_PATH ?? fallback);
|
|
33597
33746
|
const result = await runInit({
|
|
33598
33747
|
scanPath,
|
|
33599
33748
|
outPath,
|
|
@@ -33614,21 +33763,21 @@ async function main() {
|
|
|
33614
33763
|
usage5();
|
|
33615
33764
|
process.exit(2);
|
|
33616
33765
|
}
|
|
33617
|
-
const scanPath =
|
|
33766
|
+
const scanPath = import_node_path98.default.resolve(target);
|
|
33618
33767
|
const stat = await import_node_fs59.promises.stat(scanPath).catch(() => null);
|
|
33619
33768
|
if (!stat || !stat.isDirectory()) {
|
|
33620
33769
|
console.error(`neat watch: ${scanPath} is not a directory`);
|
|
33621
33770
|
process.exit(2);
|
|
33622
33771
|
}
|
|
33623
|
-
const projectPaths = pathsForProject(project,
|
|
33624
|
-
const outPath =
|
|
33625
|
-
const errorsPath =
|
|
33626
|
-
process.env.NEAT_ERRORS_PATH ??
|
|
33772
|
+
const projectPaths = pathsForProject(project, import_node_path98.default.join(scanPath, "neat-out"));
|
|
33773
|
+
const outPath = import_node_path98.default.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath);
|
|
33774
|
+
const errorsPath = import_node_path98.default.resolve(
|
|
33775
|
+
process.env.NEAT_ERRORS_PATH ?? import_node_path98.default.join(import_node_path98.default.dirname(outPath), import_node_path98.default.basename(projectPaths.errorsPath))
|
|
33627
33776
|
);
|
|
33628
|
-
const staleEventsPath =
|
|
33629
|
-
process.env.NEAT_STALE_EVENTS_PATH ??
|
|
33777
|
+
const staleEventsPath = import_node_path98.default.resolve(
|
|
33778
|
+
process.env.NEAT_STALE_EVENTS_PATH ?? import_node_path98.default.join(import_node_path98.default.dirname(outPath), import_node_path98.default.basename(projectPaths.staleEventsPath))
|
|
33630
33779
|
);
|
|
33631
|
-
const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ?
|
|
33780
|
+
const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ? import_node_path98.default.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH) : void 0;
|
|
33632
33781
|
const handle = await startWatch(getGraph(project), {
|
|
33633
33782
|
scanPath,
|
|
33634
33783
|
outPath,
|
|
@@ -33637,7 +33786,7 @@ async function main() {
|
|
|
33637
33786
|
project,
|
|
33638
33787
|
// Resolve NEAT_HOME so a `neat watch` picks up connectors added to
|
|
33639
33788
|
// ~/.neat/connectors.json (#871). Same resolution the rest of the CLI uses.
|
|
33640
|
-
neatHome: process.env.NEAT_HOME ?
|
|
33789
|
+
neatHome: process.env.NEAT_HOME ? import_node_path98.default.resolve(process.env.NEAT_HOME) : import_node_path98.default.join(import_node_os11.default.homedir(), ".neat"),
|
|
33641
33790
|
...embeddingsCachePath ? { embeddingsCachePath } : {},
|
|
33642
33791
|
host: process.env.HOST ?? "0.0.0.0",
|
|
33643
33792
|
port: Number(process.env.PORT ?? 8080),
|
|
@@ -33819,11 +33968,11 @@ async function main() {
|
|
|
33819
33968
|
process.exit(1);
|
|
33820
33969
|
}
|
|
33821
33970
|
async function tryOrchestrator(cmd, parsed) {
|
|
33822
|
-
const scanPath =
|
|
33971
|
+
const scanPath = import_node_path98.default.resolve(cmd);
|
|
33823
33972
|
const stat = await import_node_fs59.promises.stat(scanPath).catch(() => null);
|
|
33824
33973
|
if (!stat || !stat.isDirectory()) return null;
|
|
33825
33974
|
const projectExplicit = parsed.project !== null;
|
|
33826
|
-
const projectName = projectExplicit ? parsed.project :
|
|
33975
|
+
const projectName = projectExplicit ? parsed.project : import_node_path98.default.basename(scanPath);
|
|
33827
33976
|
const result = await runOrchestrator({
|
|
33828
33977
|
scanPath,
|
|
33829
33978
|
project: projectName,
|
|
@@ -34062,10 +34211,10 @@ async function runQueryVerb(cmd, parsed) {
|
|
|
34062
34211
|
const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
34063
34212
|
const out = [];
|
|
34064
34213
|
for (const p of parts) {
|
|
34065
|
-
const r =
|
|
34214
|
+
const r = import_types112.DivergenceTypeSchema.safeParse(p);
|
|
34066
34215
|
if (!r.success) {
|
|
34067
34216
|
console.error(
|
|
34068
|
-
`neat divergences: unknown --type "${p}". allowed: ${
|
|
34217
|
+
`neat divergences: unknown --type "${p}". allowed: ${import_types112.DivergenceTypeSchema.options.join(", ")}`
|
|
34069
34218
|
);
|
|
34070
34219
|
return 2;
|
|
34071
34220
|
}
|