@osfactory/har 1.14.2 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +48 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38722,6 +38722,26 @@ function substituteEnvTemplate(template, values) {
|
|
|
38722
38722
|
}
|
|
38723
38723
|
);
|
|
38724
38724
|
}
|
|
38725
|
+
function findUnsubstitutedTemplateVars(template) {
|
|
38726
|
+
const allowed = new Set(AGENT_ENV_TEMPLATE_VARS);
|
|
38727
|
+
const found = /* @__PURE__ */ new Map();
|
|
38728
|
+
template.split("\n").forEach((line, idx) => {
|
|
38729
|
+
if (/^\s*#/.test(line)) return;
|
|
38730
|
+
const re2 = /\$(?:\{([A-Za-z_][A-Za-z0-9_]*)([^}]*)(\}?)|([A-Za-z_][A-Za-z0-9_]*))/g;
|
|
38731
|
+
for (let m = re2.exec(line); m !== null; m = re2.exec(line)) {
|
|
38732
|
+
const braced = m[1] !== void 0;
|
|
38733
|
+
const name = braced ? m[1] : m[4];
|
|
38734
|
+
const plain = !braced || m[2] === "" && m[3] === "}";
|
|
38735
|
+
const reason = plain ? "not-substituted" : "parameter-syntax";
|
|
38736
|
+
if (plain && allowed.has(name)) continue;
|
|
38737
|
+
const key = `${reason}:${name}`;
|
|
38738
|
+
const entry = found.get(key) ?? { name, reason, lines: [] };
|
|
38739
|
+
if (!entry.lines.includes(idx + 1)) entry.lines.push(idx + 1);
|
|
38740
|
+
found.set(key, entry);
|
|
38741
|
+
}
|
|
38742
|
+
});
|
|
38743
|
+
return [...found.values()];
|
|
38744
|
+
}
|
|
38725
38745
|
function generateAgentEnvFile(options) {
|
|
38726
38746
|
const templatePath = options.templatePath ?? path24.join(options.harnessDir, "env.template");
|
|
38727
38747
|
if (!fs24.existsSync(templatePath)) return false;
|
|
@@ -39011,7 +39031,7 @@ function defaultAppPort(base, agentId, step) {
|
|
|
39011
39031
|
function slotPortLaneEnd(defaultPort, step) {
|
|
39012
39032
|
return defaultPort + step - 1;
|
|
39013
39033
|
}
|
|
39014
|
-
function
|
|
39034
|
+
function probeTcpPort(port, host) {
|
|
39015
39035
|
try {
|
|
39016
39036
|
(0, import_child_process6.execSync)(`bash -c 'exec 3<>/dev/tcp/${host}/${port}'`, { stdio: "ignore" });
|
|
39017
39037
|
return true;
|
|
@@ -39019,6 +39039,10 @@ function isPortInUse(port, host = "127.0.0.1") {
|
|
|
39019
39039
|
return false;
|
|
39020
39040
|
}
|
|
39021
39041
|
}
|
|
39042
|
+
function isPortInUse(port, host) {
|
|
39043
|
+
if (host !== void 0) return probeTcpPort(port, host);
|
|
39044
|
+
return probeTcpPort(port, "127.0.0.1") || probeTcpPort(port, "::1");
|
|
39045
|
+
}
|
|
39022
39046
|
function pickFreePort(start, end) {
|
|
39023
39047
|
for (let port = start; port <= end; port++) {
|
|
39024
39048
|
if (!isPortInUse(port)) return port;
|
|
@@ -84481,6 +84505,7 @@ function applyLine(repoPath, lineSpec, options = {}) {
|
|
|
84481
84505
|
// src/harness/doctor.ts
|
|
84482
84506
|
init_stages();
|
|
84483
84507
|
init_hooks2();
|
|
84508
|
+
init_agent_env();
|
|
84484
84509
|
|
|
84485
84510
|
// src/harness/migrations.ts
|
|
84486
84511
|
var fs64 = __toESM(require("fs"));
|
|
@@ -84965,6 +84990,7 @@ var CHECK_LABELS = {
|
|
|
84965
84990
|
"lifecycle-stages": "lifecycle stages (launch/verify/teardown)",
|
|
84966
84991
|
"verification-ids": "verificationStages ids",
|
|
84967
84992
|
"port-lanes": "infra port lanes",
|
|
84993
|
+
"env-template": "env.template placeholders",
|
|
84968
84994
|
"slot-registry": "slot registry worktrees",
|
|
84969
84995
|
hooks: "lifecycle hooks (.har/hooks)",
|
|
84970
84996
|
"retired-machinery": "no references to retired runtime machinery",
|
|
@@ -85192,6 +85218,27 @@ function runDoctor(repoPath) {
|
|
|
85192
85218
|
}
|
|
85193
85219
|
}
|
|
85194
85220
|
}
|
|
85221
|
+
const envTemplatePath = path73.join(harnessDir, "env.template");
|
|
85222
|
+
if (!fs65.existsSync(envTemplatePath)) {
|
|
85223
|
+
skipped.add("env-template");
|
|
85224
|
+
} else {
|
|
85225
|
+
const allowed = new Set(AGENT_ENV_TEMPLATE_VARS);
|
|
85226
|
+
const allowedVars = AGENT_ENV_TEMPLATE_VARS.join(", ");
|
|
85227
|
+
const template = fs65.readFileSync(envTemplatePath, "utf8");
|
|
85228
|
+
for (const { name, reason, lines } of findUnsubstitutedTemplateVars(template)) {
|
|
85229
|
+
const rest = lines.slice(1);
|
|
85230
|
+
const more = rest.length ? ` (also line${rest.length > 1 ? "s" : ""} ${rest.join(", ")})` : "";
|
|
85231
|
+
const literalDollar = "A literal `$` cannot be written in env.template: envsubst has no escape and keeps `\\$` as-is";
|
|
85232
|
+
findings.push({
|
|
85233
|
+
check: "env-template",
|
|
85234
|
+
severity: "warning",
|
|
85235
|
+
file: "env.template",
|
|
85236
|
+
line: lines[0],
|
|
85237
|
+
message: reason === "parameter-syntax" ? `\${${name}\u2026} uses shell parameter syntax, which launch never expands \u2014 the whole reference is written literally to .env.agent.<id>${more}` : `\${${name}} is not substituted at launch and will be written literally to .env.agent.<id>${more}`,
|
|
85238
|
+
remedy: reason === "parameter-syntax" && allowed.has(name) ? `Write a plain \${${name}}; :- / :? / # / % are not supported by envsubst` : `Use one of ${allowedVars} (plain \${NAME}, no modifiers), or hard-code the value (variables in harness.env are not substituted into env.template). ${literalDollar}`
|
|
85239
|
+
});
|
|
85240
|
+
}
|
|
85241
|
+
}
|
|
85195
85242
|
const manifest = readManifest(repoPath);
|
|
85196
85243
|
if (!manifest?.ejected) {
|
|
85197
85244
|
skipped.add("ejected-runtime");
|