@probelabs/visor 0.1.170-ee → 0.1.171
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/defaults/code-talk.yaml +39 -238
- package/defaults/intent-router.yaml +1 -0
- package/dist/agent-protocol/task-store.d.ts +5 -0
- package/dist/agent-protocol/task-store.d.ts.map +1 -1
- package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts +34 -0
- package/dist/agent-protocol/track-execution.d.ts.map +1 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/defaults/code-talk.yaml +39 -238
- package/dist/defaults/intent-router.yaml +1 -0
- package/dist/frontends/host.d.ts +2 -0
- package/dist/frontends/host.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +10 -6
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +10 -6
- package/dist/index.js +717 -1933
- package/dist/output/traces/run-2026-03-08T07-55-35-120Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-08T07-56-13-035Z.ndjson +2266 -0
- package/dist/scheduler/scheduler.d.ts +4 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-YTXQGUDH.mjs → a2a-frontend-FGJ3UBHX.mjs} +20 -3
- package/dist/sdk/a2a-frontend-FGJ3UBHX.mjs.map +1 -0
- package/dist/sdk/a2a-frontend-GUEGI5SX.mjs +1622 -0
- package/dist/sdk/a2a-frontend-GUEGI5SX.mjs.map +1 -0
- package/dist/sdk/{check-provider-registry-T5FWS4SW.mjs → check-provider-registry-PVTV5G5R.mjs} +7 -7
- package/dist/sdk/{check-provider-registry-Q2OVYSBJ.mjs → check-provider-registry-YTI4PU5F.mjs} +7 -7
- package/dist/sdk/check-provider-registry-ZUU7KSKR.mjs +30 -0
- package/dist/sdk/{chunk-46P7AYHG.mjs → chunk-2VDUNKIP.mjs} +63 -24
- package/dist/sdk/chunk-2VDUNKIP.mjs.map +1 -0
- package/dist/sdk/{chunk-FTUGQP5L.mjs → chunk-5SBX4KLG.mjs} +2 -2
- package/dist/sdk/chunk-6FDBLSGV.mjs +739 -0
- package/dist/sdk/chunk-6FDBLSGV.mjs.map +1 -0
- package/dist/sdk/{chunk-2CNT2EB3.mjs → chunk-6FXVWL6M.mjs} +3 -3
- package/dist/sdk/{chunk-KFKHU6CM.mjs → chunk-6VVXKXTI.mjs} +19 -2
- package/dist/sdk/chunk-6VVXKXTI.mjs.map +1 -0
- package/dist/sdk/{chunk-SVBF7Y2R.mjs → chunk-A2YVTICA.mjs} +11 -7
- package/dist/sdk/chunk-A2YVTICA.mjs.map +1 -0
- package/dist/sdk/chunk-AJK3FAA2.mjs +1502 -0
- package/dist/sdk/chunk-AJK3FAA2.mjs.map +1 -0
- package/dist/sdk/{chunk-DLO46M5M.mjs → chunk-CXA3WUOB.mjs} +62 -23
- package/dist/sdk/chunk-CXA3WUOB.mjs.map +1 -0
- package/dist/sdk/{chunk-62PXPI6Q.mjs → chunk-GGNR347O.mjs} +8 -2
- package/dist/sdk/chunk-GGNR347O.mjs.map +1 -0
- package/dist/sdk/chunk-O72J3ORS.mjs +449 -0
- package/dist/sdk/chunk-O72J3ORS.mjs.map +1 -0
- package/dist/sdk/chunk-XUQSI5SR.mjs +44810 -0
- package/dist/sdk/chunk-XUQSI5SR.mjs.map +1 -0
- package/dist/sdk/{config-IHECYTNT.mjs → config-6GWD673K.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-NJO6DSL4.mjs → failure-condition-evaluator-5HRNHZCC.mjs} +4 -3
- package/dist/sdk/failure-condition-evaluator-EFMCQVAK.mjs +18 -0
- package/dist/sdk/{github-frontend-WPTKI4AY.mjs → github-frontend-XG55VJ4R.mjs} +7 -7
- package/dist/sdk/github-frontend-ZZRU6P43.mjs +1386 -0
- package/dist/sdk/github-frontend-ZZRU6P43.mjs.map +1 -0
- package/dist/sdk/{host-6HV5FMD7.mjs → host-A4GGQVEN.mjs} +3 -3
- package/dist/sdk/host-A4GGQVEN.mjs.map +1 -0
- package/dist/sdk/{host-RATJKJW5.mjs → host-A7UNRBQU.mjs} +3 -3
- package/dist/sdk/host-A7UNRBQU.mjs.map +1 -0
- package/dist/sdk/{routing-RWZEXSRZ.mjs → routing-AMRQYI7J.mjs} +5 -4
- package/dist/sdk/routing-BVEHVZHK.mjs +26 -0
- package/dist/sdk/{schedule-tool-VI5IUMEL.mjs → schedule-tool-4MTFIHCA.mjs} +7 -7
- package/dist/sdk/{schedule-tool-JCKV47FU.mjs → schedule-tool-DGVJDHJM.mjs} +7 -7
- package/dist/sdk/schedule-tool-PHSF5U2B.mjs +36 -0
- package/dist/sdk/{schedule-tool-handler-PIXYVVJY.mjs → schedule-tool-handler-EFNCZNS7.mjs} +7 -7
- package/dist/sdk/{schedule-tool-handler-ZDAD6SWM.mjs → schedule-tool-handler-LMXQ4BZQ.mjs} +7 -7
- package/dist/sdk/schedule-tool-handler-LMXQ4BZQ.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-XLCSBU3E.mjs +40 -0
- package/dist/sdk/schedule-tool-handler-XLCSBU3E.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +4 -0
- package/dist/sdk/sdk.d.ts +4 -0
- package/dist/sdk/sdk.js +552 -1782
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +6 -6
- package/dist/sdk/{trace-helpers-ZYN23GBG.mjs → trace-helpers-4ZBZWH5W.mjs} +3 -2
- package/dist/sdk/trace-helpers-4ZBZWH5W.mjs.map +1 -0
- package/dist/sdk/trace-helpers-P5L4COO4.mjs +26 -0
- package/dist/sdk/trace-helpers-P5L4COO4.mjs.map +1 -0
- package/dist/sdk/track-execution-VWLQIGY7.mjs +82 -0
- package/dist/sdk/track-execution-VWLQIGY7.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-OAOD3A5U.mjs → workflow-check-provider-KQNLEQEY.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-KQNLEQEY.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-W5FKQU5G.mjs → workflow-check-provider-WLMTCFRA.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-WLMTCFRA.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-X5EMAJUZ.mjs +30 -0
- package/dist/sdk/workflow-check-provider-X5EMAJUZ.mjs.map +1 -0
- package/dist/slack/socket-runner.d.ts +4 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/telemetry/trace-helpers.d.ts.map +1 -1
- package/dist/traces/run-2026-03-08T07-55-35-120Z.ndjson +138 -0
- package/dist/traces/run-2026-03-08T07-56-13-035Z.ndjson +2266 -0
- package/dist/tui/chat-runner.d.ts +4 -0
- package/dist/tui/chat-runner.d.ts.map +1 -1
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +4 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/instance-id.d.ts +9 -0
- package/dist/utils/instance-id.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/sdk/a2a-frontend-YTXQGUDH.mjs.map +0 -1
- package/dist/sdk/chunk-46P7AYHG.mjs.map +0 -1
- package/dist/sdk/chunk-62PXPI6Q.mjs.map +0 -1
- package/dist/sdk/chunk-DLO46M5M.mjs.map +0 -1
- package/dist/sdk/chunk-KFKHU6CM.mjs.map +0 -1
- package/dist/sdk/chunk-SVBF7Y2R.mjs.map +0 -1
- package/dist/sdk/host-6HV5FMD7.mjs.map +0 -1
- package/dist/sdk/host-RATJKJW5.mjs.map +0 -1
- package/dist/sdk/knex-store-CRORFJE6.mjs +0 -527
- package/dist/sdk/knex-store-CRORFJE6.mjs.map +0 -1
- package/dist/sdk/loader-NJCF7DUS.mjs +0 -89
- package/dist/sdk/loader-NJCF7DUS.mjs.map +0 -1
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +0 -655
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs.map +0 -1
- package/dist/sdk/validator-XTZJZZJH.mjs +0 -134
- package/dist/sdk/validator-XTZJZZJH.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-Q2OVYSBJ.mjs.map → check-provider-registry-PVTV5G5R.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-T5FWS4SW.mjs.map → check-provider-registry-YTI4PU5F.mjs.map} +0 -0
- /package/dist/sdk/{config-IHECYTNT.mjs.map → check-provider-registry-ZUU7KSKR.mjs.map} +0 -0
- /package/dist/sdk/{chunk-FTUGQP5L.mjs.map → chunk-5SBX4KLG.mjs.map} +0 -0
- /package/dist/sdk/{chunk-2CNT2EB3.mjs.map → chunk-6FXVWL6M.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-NJO6DSL4.mjs.map → config-6GWD673K.mjs.map} +0 -0
- /package/dist/sdk/{routing-RWZEXSRZ.mjs.map → failure-condition-evaluator-5HRNHZCC.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-JCKV47FU.mjs.map → failure-condition-evaluator-EFMCQVAK.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-WPTKI4AY.mjs.map → github-frontend-XG55VJ4R.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-VI5IUMEL.mjs.map → routing-AMRQYI7J.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-PIXYVVJY.mjs.map → routing-BVEHVZHK.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-ZDAD6SWM.mjs.map → schedule-tool-4MTFIHCA.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-ZYN23GBG.mjs.map → schedule-tool-DGVJDHJM.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-OAOD3A5U.mjs.map → schedule-tool-PHSF5U2B.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-W5FKQU5G.mjs.map → schedule-tool-handler-EFNCZNS7.mjs.map} +0 -0
package/dist/sdk/sdk.js
CHANGED
|
@@ -570,6 +570,21 @@ var init_logger = __esm({
|
|
|
570
570
|
}
|
|
571
571
|
});
|
|
572
572
|
|
|
573
|
+
// src/utils/instance-id.ts
|
|
574
|
+
function getInstanceId() {
|
|
575
|
+
if (!_instanceId) {
|
|
576
|
+
_instanceId = generateHumanId();
|
|
577
|
+
}
|
|
578
|
+
return _instanceId;
|
|
579
|
+
}
|
|
580
|
+
var _instanceId;
|
|
581
|
+
var init_instance_id = __esm({
|
|
582
|
+
"src/utils/instance-id.ts"() {
|
|
583
|
+
"use strict";
|
|
584
|
+
init_human_id();
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
|
|
573
588
|
// src/telemetry/fallback-ndjson.ts
|
|
574
589
|
var fallback_ndjson_exports = {};
|
|
575
590
|
__export(fallback_ndjson_exports, {
|
|
@@ -646,7 +661,7 @@ var require_package = __commonJS({
|
|
|
646
661
|
"package.json"(exports2, module2) {
|
|
647
662
|
module2.exports = {
|
|
648
663
|
name: "@probelabs/visor",
|
|
649
|
-
version: "0.1.
|
|
664
|
+
version: "0.1.171",
|
|
650
665
|
main: "dist/index.js",
|
|
651
666
|
bin: {
|
|
652
667
|
visor: "./dist/index.js"
|
|
@@ -760,7 +775,7 @@ var require_package = __commonJS({
|
|
|
760
775
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
761
776
|
"@opentelemetry/sdk-trace-base": "^1.30.1",
|
|
762
777
|
"@opentelemetry/semantic-conventions": "^1.30.1",
|
|
763
|
-
"@probelabs/probe": "^0.6.0-
|
|
778
|
+
"@probelabs/probe": "^0.6.0-rc290",
|
|
764
779
|
"@types/commander": "^2.12.0",
|
|
765
780
|
"@types/uuid": "^10.0.0",
|
|
766
781
|
acorn: "^8.16.0",
|
|
@@ -864,11 +879,11 @@ function getTracer() {
|
|
|
864
879
|
}
|
|
865
880
|
async function withActiveSpan(name, attrs, fn) {
|
|
866
881
|
const tracer = getTracer();
|
|
867
|
-
return await new Promise((
|
|
882
|
+
return await new Promise((resolve15, reject) => {
|
|
868
883
|
const callback = async (span) => {
|
|
869
884
|
try {
|
|
870
885
|
const res = await fn(span);
|
|
871
|
-
|
|
886
|
+
resolve15(res);
|
|
872
887
|
} catch (err) {
|
|
873
888
|
try {
|
|
874
889
|
if (err instanceof Error) span.recordException(err);
|
|
@@ -939,25 +954,26 @@ function getVisorRunAttributes() {
|
|
|
939
954
|
if (commitFull) {
|
|
940
955
|
attrs["visor.commit.sha"] = commitFull;
|
|
941
956
|
}
|
|
957
|
+
attrs["visor.instance_id"] = getInstanceId();
|
|
942
958
|
return attrs;
|
|
943
959
|
}
|
|
944
960
|
function __getOrCreateNdjsonPath() {
|
|
945
961
|
try {
|
|
946
962
|
if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
|
|
947
963
|
return null;
|
|
948
|
-
const
|
|
949
|
-
const
|
|
964
|
+
const path29 = require("path");
|
|
965
|
+
const fs25 = require("fs");
|
|
950
966
|
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
951
967
|
__ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
952
|
-
const dir =
|
|
953
|
-
if (!
|
|
968
|
+
const dir = path29.dirname(__ndjsonPath);
|
|
969
|
+
if (!fs25.existsSync(dir)) fs25.mkdirSync(dir, { recursive: true });
|
|
954
970
|
return __ndjsonPath;
|
|
955
971
|
}
|
|
956
|
-
const outDir = process.env.VISOR_TRACE_DIR ||
|
|
957
|
-
if (!
|
|
972
|
+
const outDir = process.env.VISOR_TRACE_DIR || path29.join(process.cwd(), "output", "traces");
|
|
973
|
+
if (!fs25.existsSync(outDir)) fs25.mkdirSync(outDir, { recursive: true });
|
|
958
974
|
if (!__ndjsonPath) {
|
|
959
975
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
960
|
-
__ndjsonPath =
|
|
976
|
+
__ndjsonPath = path29.join(outDir, `${ts}.ndjson`);
|
|
961
977
|
}
|
|
962
978
|
return __ndjsonPath;
|
|
963
979
|
} catch {
|
|
@@ -966,11 +982,11 @@ function __getOrCreateNdjsonPath() {
|
|
|
966
982
|
}
|
|
967
983
|
function _appendRunMarker() {
|
|
968
984
|
try {
|
|
969
|
-
const
|
|
985
|
+
const fs25 = require("fs");
|
|
970
986
|
const p = __getOrCreateNdjsonPath();
|
|
971
987
|
if (!p) return;
|
|
972
988
|
const line = { name: "visor.run", attributes: { started: true } };
|
|
973
|
-
|
|
989
|
+
fs25.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
|
|
974
990
|
} catch {
|
|
975
991
|
}
|
|
976
992
|
}
|
|
@@ -979,6 +995,7 @@ var init_trace_helpers = __esm({
|
|
|
979
995
|
"src/telemetry/trace-helpers.ts"() {
|
|
980
996
|
"use strict";
|
|
981
997
|
init_lazy_otel();
|
|
998
|
+
init_instance_id();
|
|
982
999
|
__ndjsonPath = null;
|
|
983
1000
|
}
|
|
984
1001
|
});
|
|
@@ -3193,7 +3210,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3193
3210
|
*/
|
|
3194
3211
|
evaluateExpression(condition, context2) {
|
|
3195
3212
|
try {
|
|
3196
|
-
const
|
|
3213
|
+
const normalize4 = (expr) => {
|
|
3197
3214
|
const trimmed = expr.trim();
|
|
3198
3215
|
if (!/[\n;]/.test(trimmed)) return trimmed;
|
|
3199
3216
|
const parts = trimmed.split(/[\n;]+/).map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("//"));
|
|
@@ -3351,7 +3368,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3351
3368
|
try {
|
|
3352
3369
|
exec2 = this.sandbox.compile(`return (${raw});`);
|
|
3353
3370
|
} catch {
|
|
3354
|
-
const normalizedExpr =
|
|
3371
|
+
const normalizedExpr = normalize4(condition);
|
|
3355
3372
|
exec2 = this.sandbox.compile(`return (${normalizedExpr});`);
|
|
3356
3373
|
}
|
|
3357
3374
|
const result = exec2(scope).run();
|
|
@@ -3734,9 +3751,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
3734
3751
|
});
|
|
3735
3752
|
liquid.registerFilter("get", (obj, pathExpr) => {
|
|
3736
3753
|
if (obj == null) return void 0;
|
|
3737
|
-
const
|
|
3738
|
-
if (!
|
|
3739
|
-
const parts =
|
|
3754
|
+
const path29 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
|
|
3755
|
+
if (!path29) return obj;
|
|
3756
|
+
const parts = path29.split(".");
|
|
3740
3757
|
let cur = obj;
|
|
3741
3758
|
for (const p of parts) {
|
|
3742
3759
|
if (cur == null) return void 0;
|
|
@@ -3855,9 +3872,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
3855
3872
|
}
|
|
3856
3873
|
}
|
|
3857
3874
|
const defaultRole = typeof rolesCfg.default === "string" && rolesCfg.default.trim() ? rolesCfg.default.trim() : void 0;
|
|
3858
|
-
const getNested = (obj,
|
|
3859
|
-
if (!obj || !
|
|
3860
|
-
const parts =
|
|
3875
|
+
const getNested = (obj, path29) => {
|
|
3876
|
+
if (!obj || !path29) return void 0;
|
|
3877
|
+
const parts = path29.split(".");
|
|
3861
3878
|
let cur = obj;
|
|
3862
3879
|
for (const p of parts) {
|
|
3863
3880
|
if (cur == null) return void 0;
|
|
@@ -6409,8 +6426,8 @@ var init_dependency_gating = __esm({
|
|
|
6409
6426
|
async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
6410
6427
|
try {
|
|
6411
6428
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
6412
|
-
const
|
|
6413
|
-
const
|
|
6429
|
+
const fs25 = await import("fs/promises");
|
|
6430
|
+
const path29 = await import("path");
|
|
6414
6431
|
const schemaRaw = checkConfig.schema || "plain";
|
|
6415
6432
|
const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
|
|
6416
6433
|
let templateContent;
|
|
@@ -6418,24 +6435,24 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
|
6418
6435
|
templateContent = String(checkConfig.template.content);
|
|
6419
6436
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
6420
6437
|
const file = String(checkConfig.template.file);
|
|
6421
|
-
const resolved =
|
|
6422
|
-
templateContent = await
|
|
6438
|
+
const resolved = path29.resolve(process.cwd(), file);
|
|
6439
|
+
templateContent = await fs25.readFile(resolved, "utf-8");
|
|
6423
6440
|
} else if (schema && schema !== "plain") {
|
|
6424
6441
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
6425
6442
|
if (sanitized) {
|
|
6426
6443
|
const candidatePaths = [
|
|
6427
|
-
|
|
6444
|
+
path29.join(__dirname, "output", sanitized, "template.liquid"),
|
|
6428
6445
|
// bundled: dist/output/
|
|
6429
|
-
|
|
6446
|
+
path29.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
6430
6447
|
// source: output/
|
|
6431
|
-
|
|
6448
|
+
path29.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
6432
6449
|
// fallback: cwd/output/
|
|
6433
|
-
|
|
6450
|
+
path29.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
6434
6451
|
// fallback: cwd/dist/output/
|
|
6435
6452
|
];
|
|
6436
6453
|
for (const p of candidatePaths) {
|
|
6437
6454
|
try {
|
|
6438
|
-
templateContent = await
|
|
6455
|
+
templateContent = await fs25.readFile(p, "utf-8");
|
|
6439
6456
|
if (templateContent) break;
|
|
6440
6457
|
} catch {
|
|
6441
6458
|
}
|
|
@@ -6840,7 +6857,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6840
6857
|
}
|
|
6841
6858
|
try {
|
|
6842
6859
|
const originalProbePath = process.env.PROBE_PATH;
|
|
6843
|
-
const
|
|
6860
|
+
const fs25 = require("fs");
|
|
6844
6861
|
const possiblePaths = [
|
|
6845
6862
|
// Relative to current working directory (most common in production)
|
|
6846
6863
|
path6.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
|
|
@@ -6851,7 +6868,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6851
6868
|
];
|
|
6852
6869
|
let probeBinaryPath;
|
|
6853
6870
|
for (const candidatePath of possiblePaths) {
|
|
6854
|
-
if (
|
|
6871
|
+
if (fs25.existsSync(candidatePath)) {
|
|
6855
6872
|
probeBinaryPath = candidatePath;
|
|
6856
6873
|
break;
|
|
6857
6874
|
}
|
|
@@ -6958,7 +6975,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
6958
6975
|
if (chromiumPath) {
|
|
6959
6976
|
env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
|
|
6960
6977
|
}
|
|
6961
|
-
const result = await new Promise((
|
|
6978
|
+
const result = await new Promise((resolve15) => {
|
|
6962
6979
|
const proc = (0, import_child_process.spawn)(
|
|
6963
6980
|
"npx",
|
|
6964
6981
|
[
|
|
@@ -6988,13 +7005,13 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
6988
7005
|
});
|
|
6989
7006
|
proc.on("close", (code) => {
|
|
6990
7007
|
if (code === 0) {
|
|
6991
|
-
|
|
7008
|
+
resolve15({ success: true });
|
|
6992
7009
|
} else {
|
|
6993
|
-
|
|
7010
|
+
resolve15({ success: false, error: stderr || `Exit code ${code}` });
|
|
6994
7011
|
}
|
|
6995
7012
|
});
|
|
6996
7013
|
proc.on("error", (err) => {
|
|
6997
|
-
|
|
7014
|
+
resolve15({ success: false, error: err.message });
|
|
6998
7015
|
});
|
|
6999
7016
|
});
|
|
7000
7017
|
if (!result.success) {
|
|
@@ -8156,8 +8173,8 @@ ${schemaString}`);
|
|
|
8156
8173
|
}
|
|
8157
8174
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8158
8175
|
try {
|
|
8159
|
-
const
|
|
8160
|
-
const
|
|
8176
|
+
const fs25 = require("fs");
|
|
8177
|
+
const path29 = require("path");
|
|
8161
8178
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8162
8179
|
const provider = this.config.provider || "auto";
|
|
8163
8180
|
const model = this.config.model || "default";
|
|
@@ -8271,20 +8288,20 @@ ${"=".repeat(60)}
|
|
|
8271
8288
|
`;
|
|
8272
8289
|
readableVersion += `${"=".repeat(60)}
|
|
8273
8290
|
`;
|
|
8274
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8275
|
-
if (!
|
|
8276
|
-
|
|
8291
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8292
|
+
if (!fs25.existsSync(debugArtifactsDir)) {
|
|
8293
|
+
fs25.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
8277
8294
|
}
|
|
8278
|
-
const debugFile =
|
|
8295
|
+
const debugFile = path29.join(
|
|
8279
8296
|
debugArtifactsDir,
|
|
8280
8297
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
8281
8298
|
);
|
|
8282
|
-
|
|
8283
|
-
const readableFile =
|
|
8299
|
+
fs25.writeFileSync(debugFile, debugJson, "utf-8");
|
|
8300
|
+
const readableFile = path29.join(
|
|
8284
8301
|
debugArtifactsDir,
|
|
8285
8302
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8286
8303
|
);
|
|
8287
|
-
|
|
8304
|
+
fs25.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
8288
8305
|
log(`
|
|
8289
8306
|
\u{1F4BE} Full debug info saved to:`);
|
|
8290
8307
|
log(` JSON: ${debugFile}`);
|
|
@@ -8317,8 +8334,8 @@ ${"=".repeat(60)}
|
|
|
8317
8334
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8318
8335
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8319
8336
|
try {
|
|
8320
|
-
const
|
|
8321
|
-
const
|
|
8337
|
+
const fs25 = require("fs");
|
|
8338
|
+
const path29 = require("path");
|
|
8322
8339
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8323
8340
|
const agentAny2 = agent;
|
|
8324
8341
|
let fullHistory = [];
|
|
@@ -8329,8 +8346,8 @@ ${"=".repeat(60)}
|
|
|
8329
8346
|
} else if (agentAny2._messages) {
|
|
8330
8347
|
fullHistory = agentAny2._messages;
|
|
8331
8348
|
}
|
|
8332
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8333
|
-
const sessionBase =
|
|
8349
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8350
|
+
const sessionBase = path29.join(
|
|
8334
8351
|
debugArtifactsDir,
|
|
8335
8352
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8336
8353
|
);
|
|
@@ -8342,7 +8359,7 @@ ${"=".repeat(60)}
|
|
|
8342
8359
|
schema: effectiveSchema,
|
|
8343
8360
|
totalMessages: fullHistory.length
|
|
8344
8361
|
};
|
|
8345
|
-
|
|
8362
|
+
fs25.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8346
8363
|
let readable = `=============================================================
|
|
8347
8364
|
`;
|
|
8348
8365
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8369,7 +8386,7 @@ ${"=".repeat(60)}
|
|
|
8369
8386
|
`;
|
|
8370
8387
|
readable += content + "\n";
|
|
8371
8388
|
});
|
|
8372
|
-
|
|
8389
|
+
fs25.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8373
8390
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8374
8391
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8375
8392
|
} catch (error) {
|
|
@@ -8378,11 +8395,11 @@ ${"=".repeat(60)}
|
|
|
8378
8395
|
}
|
|
8379
8396
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8380
8397
|
try {
|
|
8381
|
-
const
|
|
8382
|
-
const
|
|
8398
|
+
const fs25 = require("fs");
|
|
8399
|
+
const path29 = require("path");
|
|
8383
8400
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8384
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8385
|
-
const responseFile =
|
|
8401
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8402
|
+
const responseFile = path29.join(
|
|
8386
8403
|
debugArtifactsDir,
|
|
8387
8404
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8388
8405
|
);
|
|
@@ -8415,7 +8432,7 @@ ${"=".repeat(60)}
|
|
|
8415
8432
|
`;
|
|
8416
8433
|
responseContent += `${"=".repeat(60)}
|
|
8417
8434
|
`;
|
|
8418
|
-
|
|
8435
|
+
fs25.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8419
8436
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8420
8437
|
} catch (error) {
|
|
8421
8438
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8431,9 +8448,9 @@ ${"=".repeat(60)}
|
|
|
8431
8448
|
await agentAny._telemetryConfig.shutdown();
|
|
8432
8449
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
8433
8450
|
if (process.env.GITHUB_ACTIONS) {
|
|
8434
|
-
const
|
|
8435
|
-
if (
|
|
8436
|
-
const stats =
|
|
8451
|
+
const fs25 = require("fs");
|
|
8452
|
+
if (fs25.existsSync(agentAny._traceFilePath)) {
|
|
8453
|
+
const stats = fs25.statSync(agentAny._traceFilePath);
|
|
8437
8454
|
console.log(
|
|
8438
8455
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
8439
8456
|
);
|
|
@@ -8646,9 +8663,9 @@ ${schemaString}`);
|
|
|
8646
8663
|
const model = this.config.model || "default";
|
|
8647
8664
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8648
8665
|
try {
|
|
8649
|
-
const
|
|
8650
|
-
const
|
|
8651
|
-
const
|
|
8666
|
+
const fs25 = require("fs");
|
|
8667
|
+
const path29 = require("path");
|
|
8668
|
+
const os2 = require("os");
|
|
8652
8669
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8653
8670
|
const debugData = {
|
|
8654
8671
|
timestamp,
|
|
@@ -8720,19 +8737,19 @@ ${"=".repeat(60)}
|
|
|
8720
8737
|
`;
|
|
8721
8738
|
readableVersion += `${"=".repeat(60)}
|
|
8722
8739
|
`;
|
|
8723
|
-
const tempDir =
|
|
8724
|
-
const promptFile =
|
|
8725
|
-
|
|
8740
|
+
const tempDir = os2.tmpdir();
|
|
8741
|
+
const promptFile = path29.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8742
|
+
fs25.writeFileSync(promptFile, prompt, "utf-8");
|
|
8726
8743
|
log(`
|
|
8727
8744
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8728
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8745
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8729
8746
|
try {
|
|
8730
|
-
const base =
|
|
8747
|
+
const base = path29.join(
|
|
8731
8748
|
debugArtifactsDir,
|
|
8732
8749
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8733
8750
|
);
|
|
8734
|
-
|
|
8735
|
-
|
|
8751
|
+
fs25.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8752
|
+
fs25.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8736
8753
|
log(`
|
|
8737
8754
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8738
8755
|
} catch {
|
|
@@ -8777,8 +8794,8 @@ $ ${cliCommand}
|
|
|
8777
8794
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8778
8795
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8779
8796
|
try {
|
|
8780
|
-
const
|
|
8781
|
-
const
|
|
8797
|
+
const fs25 = require("fs");
|
|
8798
|
+
const path29 = require("path");
|
|
8782
8799
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8783
8800
|
const agentAny = agent;
|
|
8784
8801
|
let fullHistory = [];
|
|
@@ -8789,8 +8806,8 @@ $ ${cliCommand}
|
|
|
8789
8806
|
} else if (agentAny._messages) {
|
|
8790
8807
|
fullHistory = agentAny._messages;
|
|
8791
8808
|
}
|
|
8792
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8793
|
-
const sessionBase =
|
|
8809
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8810
|
+
const sessionBase = path29.join(
|
|
8794
8811
|
debugArtifactsDir,
|
|
8795
8812
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8796
8813
|
);
|
|
@@ -8802,7 +8819,7 @@ $ ${cliCommand}
|
|
|
8802
8819
|
schema: effectiveSchema,
|
|
8803
8820
|
totalMessages: fullHistory.length
|
|
8804
8821
|
};
|
|
8805
|
-
|
|
8822
|
+
fs25.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8806
8823
|
let readable = `=============================================================
|
|
8807
8824
|
`;
|
|
8808
8825
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8829,7 +8846,7 @@ ${"=".repeat(60)}
|
|
|
8829
8846
|
`;
|
|
8830
8847
|
readable += content + "\n";
|
|
8831
8848
|
});
|
|
8832
|
-
|
|
8849
|
+
fs25.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8833
8850
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8834
8851
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8835
8852
|
} catch (error) {
|
|
@@ -8838,11 +8855,11 @@ ${"=".repeat(60)}
|
|
|
8838
8855
|
}
|
|
8839
8856
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8840
8857
|
try {
|
|
8841
|
-
const
|
|
8842
|
-
const
|
|
8858
|
+
const fs25 = require("fs");
|
|
8859
|
+
const path29 = require("path");
|
|
8843
8860
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8844
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8845
|
-
const responseFile =
|
|
8861
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
|
|
8862
|
+
const responseFile = path29.join(
|
|
8846
8863
|
debugArtifactsDir,
|
|
8847
8864
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8848
8865
|
);
|
|
@@ -8875,7 +8892,7 @@ ${"=".repeat(60)}
|
|
|
8875
8892
|
`;
|
|
8876
8893
|
responseContent += `${"=".repeat(60)}
|
|
8877
8894
|
`;
|
|
8878
|
-
|
|
8895
|
+
fs25.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8879
8896
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8880
8897
|
} catch (error) {
|
|
8881
8898
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8893,9 +8910,9 @@ ${"=".repeat(60)}
|
|
|
8893
8910
|
await telemetry.shutdown();
|
|
8894
8911
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8895
8912
|
if (process.env.GITHUB_ACTIONS) {
|
|
8896
|
-
const
|
|
8897
|
-
if (
|
|
8898
|
-
const stats =
|
|
8913
|
+
const fs25 = require("fs");
|
|
8914
|
+
if (fs25.existsSync(traceFilePath)) {
|
|
8915
|
+
const stats = fs25.statSync(traceFilePath);
|
|
8899
8916
|
console.log(
|
|
8900
8917
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8901
8918
|
);
|
|
@@ -8933,8 +8950,8 @@ ${"=".repeat(60)}
|
|
|
8933
8950
|
* Load schema content from schema files or inline definitions
|
|
8934
8951
|
*/
|
|
8935
8952
|
async loadSchemaContent(schema) {
|
|
8936
|
-
const
|
|
8937
|
-
const
|
|
8953
|
+
const fs25 = require("fs").promises;
|
|
8954
|
+
const path29 = require("path");
|
|
8938
8955
|
if (typeof schema === "object" && schema !== null) {
|
|
8939
8956
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
8940
8957
|
return JSON.stringify(schema);
|
|
@@ -8947,14 +8964,14 @@ ${"=".repeat(60)}
|
|
|
8947
8964
|
}
|
|
8948
8965
|
} catch {
|
|
8949
8966
|
}
|
|
8950
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
8967
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path29.isAbsolute(schema)) {
|
|
8951
8968
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
8952
8969
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
8953
8970
|
}
|
|
8954
8971
|
try {
|
|
8955
|
-
const schemaPath =
|
|
8972
|
+
const schemaPath = path29.resolve(process.cwd(), schema);
|
|
8956
8973
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8957
|
-
const schemaContent = await
|
|
8974
|
+
const schemaContent = await fs25.readFile(schemaPath, "utf-8");
|
|
8958
8975
|
return schemaContent.trim();
|
|
8959
8976
|
} catch (error) {
|
|
8960
8977
|
throw new Error(
|
|
@@ -8968,22 +8985,22 @@ ${"=".repeat(60)}
|
|
|
8968
8985
|
}
|
|
8969
8986
|
const candidatePaths = [
|
|
8970
8987
|
// GitHub Action bundle location
|
|
8971
|
-
|
|
8988
|
+
path29.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
8972
8989
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
8973
|
-
|
|
8990
|
+
path29.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
8974
8991
|
// Local dev (repo root)
|
|
8975
|
-
|
|
8992
|
+
path29.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
8976
8993
|
];
|
|
8977
8994
|
for (const schemaPath of candidatePaths) {
|
|
8978
8995
|
try {
|
|
8979
|
-
const schemaContent = await
|
|
8996
|
+
const schemaContent = await fs25.readFile(schemaPath, "utf-8");
|
|
8980
8997
|
return schemaContent.trim();
|
|
8981
8998
|
} catch {
|
|
8982
8999
|
}
|
|
8983
9000
|
}
|
|
8984
|
-
const distPath =
|
|
8985
|
-
const distAltPath =
|
|
8986
|
-
const cwdPath =
|
|
9001
|
+
const distPath = path29.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
9002
|
+
const distAltPath = path29.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
9003
|
+
const cwdPath = path29.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
8987
9004
|
throw new Error(
|
|
8988
9005
|
`Failed to load schema '${sanitizedSchemaName}'. Tried: ${distPath}, ${distAltPath}, and ${cwdPath}. Ensure build copies 'output/' into dist (build:cli), or provide a custom schema file/path.`
|
|
8989
9006
|
);
|
|
@@ -9228,7 +9245,7 @@ ${"=".repeat(60)}
|
|
|
9228
9245
|
* Generate mock response for testing
|
|
9229
9246
|
*/
|
|
9230
9247
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
9231
|
-
await new Promise((
|
|
9248
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
9232
9249
|
const name = (_checkName || "").toLowerCase();
|
|
9233
9250
|
if (name.includes("extract-facts")) {
|
|
9234
9251
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -9589,7 +9606,7 @@ var init_command_executor = __esm({
|
|
|
9589
9606
|
* Execute command with stdin input
|
|
9590
9607
|
*/
|
|
9591
9608
|
executeWithStdin(command, options) {
|
|
9592
|
-
return new Promise((
|
|
9609
|
+
return new Promise((resolve15, reject) => {
|
|
9593
9610
|
const childProcess = (0, import_child_process2.exec)(
|
|
9594
9611
|
command,
|
|
9595
9612
|
{
|
|
@@ -9601,7 +9618,7 @@ var init_command_executor = __esm({
|
|
|
9601
9618
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
9602
9619
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
9603
9620
|
} else {
|
|
9604
|
-
|
|
9621
|
+
resolve15({
|
|
9605
9622
|
stdout: stdout || "",
|
|
9606
9623
|
stderr: stderr || "",
|
|
9607
9624
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -12432,6 +12449,10 @@ var init_config_schema = __esm({
|
|
|
12432
12449
|
agent_protocol: {
|
|
12433
12450
|
$ref: "#/definitions/AgentProtocolConfig",
|
|
12434
12451
|
description: "Agent protocol (A2A) server configuration"
|
|
12452
|
+
},
|
|
12453
|
+
task_tracking: {
|
|
12454
|
+
type: "boolean",
|
|
12455
|
+
description: "Enable cross-frontend task tracking (default: false). When true, all workflow executions (CLI, Slack, TUI, Scheduler) are recorded in a shared SQLite TaskStore visible via `visor tasks`."
|
|
12435
12456
|
}
|
|
12436
12457
|
},
|
|
12437
12458
|
required: ["version"],
|
|
@@ -13168,7 +13189,7 @@ var init_config_schema = __esm({
|
|
|
13168
13189
|
description: "Arguments/inputs for the workflow"
|
|
13169
13190
|
},
|
|
13170
13191
|
overrides: {
|
|
13171
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13192
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916%3E%3E",
|
|
13172
13193
|
description: "Override specific step configurations in the workflow"
|
|
13173
13194
|
},
|
|
13174
13195
|
output_mapping: {
|
|
@@ -13184,7 +13205,7 @@ var init_config_schema = __esm({
|
|
|
13184
13205
|
description: "Config file path - alternative to workflow ID (loads a Visor config file as workflow)"
|
|
13185
13206
|
},
|
|
13186
13207
|
workflow_overrides: {
|
|
13187
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13208
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916%3E%3E",
|
|
13188
13209
|
description: "Alias for overrides - workflow step overrides (backward compatibility)"
|
|
13189
13210
|
},
|
|
13190
13211
|
ref: {
|
|
@@ -13882,7 +13903,7 @@ var init_config_schema = __esm({
|
|
|
13882
13903
|
description: "Custom output name (defaults to workflow name)"
|
|
13883
13904
|
},
|
|
13884
13905
|
overrides: {
|
|
13885
|
-
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13906
|
+
$ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916%3E%3E",
|
|
13886
13907
|
description: "Step overrides"
|
|
13887
13908
|
},
|
|
13888
13909
|
output_mapping: {
|
|
@@ -13897,13 +13918,13 @@ var init_config_schema = __esm({
|
|
|
13897
13918
|
"^x-": {}
|
|
13898
13919
|
}
|
|
13899
13920
|
},
|
|
13900
|
-
"Record<string,Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13921
|
+
"Record<string,Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916>>": {
|
|
13901
13922
|
type: "object",
|
|
13902
13923
|
additionalProperties: {
|
|
13903
|
-
$ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13924
|
+
$ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916%3E"
|
|
13904
13925
|
}
|
|
13905
13926
|
},
|
|
13906
|
-
"Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-
|
|
13927
|
+
"Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-55916>": {
|
|
13907
13928
|
type: "object",
|
|
13908
13929
|
additionalProperties: false
|
|
13909
13930
|
},
|
|
@@ -17977,17 +17998,17 @@ var init_workflow_check_provider = __esm({
|
|
|
17977
17998
|
* so it can be executed by the state machine as a nested workflow.
|
|
17978
17999
|
*/
|
|
17979
18000
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
17980
|
-
const
|
|
17981
|
-
const
|
|
18001
|
+
const path29 = require("path");
|
|
18002
|
+
const fs25 = require("fs");
|
|
17982
18003
|
const yaml5 = require("js-yaml");
|
|
17983
|
-
const resolved =
|
|
17984
|
-
if (!
|
|
18004
|
+
const resolved = path29.isAbsolute(sourcePath) ? sourcePath : path29.resolve(baseDir, sourcePath);
|
|
18005
|
+
if (!fs25.existsSync(resolved)) {
|
|
17985
18006
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
17986
18007
|
}
|
|
17987
|
-
const rawContent =
|
|
18008
|
+
const rawContent = fs25.readFileSync(resolved, "utf8");
|
|
17988
18009
|
const rawData = yaml5.load(rawContent);
|
|
17989
18010
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
17990
|
-
const configDir =
|
|
18011
|
+
const configDir = path29.dirname(resolved);
|
|
17991
18012
|
for (const source of rawData.imports) {
|
|
17992
18013
|
const results = await this.registry.import(source, {
|
|
17993
18014
|
basePath: configDir,
|
|
@@ -18017,8 +18038,8 @@ ${errors}`);
|
|
|
18017
18038
|
if (!steps || Object.keys(steps).length === 0) {
|
|
18018
18039
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
18019
18040
|
}
|
|
18020
|
-
const id =
|
|
18021
|
-
const name = loaded.name || `Workflow from ${
|
|
18041
|
+
const id = path29.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
18042
|
+
const name = loaded.name || `Workflow from ${path29.basename(resolved)}`;
|
|
18022
18043
|
const workflowDef = {
|
|
18023
18044
|
id,
|
|
18024
18045
|
name,
|
|
@@ -18824,8 +18845,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
18824
18845
|
case "mssql": {
|
|
18825
18846
|
try {
|
|
18826
18847
|
const loaderPath = "../../enterprise/loader";
|
|
18827
|
-
const { loadEnterpriseStoreBackend
|
|
18828
|
-
return await
|
|
18848
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
18849
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
18829
18850
|
} catch (err) {
|
|
18830
18851
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18831
18852
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -19431,6 +19452,74 @@ var init_github_auth = __esm({
|
|
|
19431
19452
|
}
|
|
19432
19453
|
});
|
|
19433
19454
|
|
|
19455
|
+
// src/agent-protocol/track-execution.ts
|
|
19456
|
+
var track_execution_exports = {};
|
|
19457
|
+
__export(track_execution_exports, {
|
|
19458
|
+
trackExecution: () => trackExecution
|
|
19459
|
+
});
|
|
19460
|
+
async function trackExecution(opts, executor) {
|
|
19461
|
+
const { taskStore, source, configPath, metadata, messageText } = opts;
|
|
19462
|
+
const configName = configPath ? import_path7.default.basename(configPath, import_path7.default.extname(configPath)) : void 0;
|
|
19463
|
+
const workflowId = configName && opts.workflowId ? `${configName}#${opts.workflowId}` : opts.workflowId;
|
|
19464
|
+
const requestMessage = {
|
|
19465
|
+
message_id: import_crypto2.default.randomUUID(),
|
|
19466
|
+
role: "user",
|
|
19467
|
+
parts: [{ text: messageText }]
|
|
19468
|
+
};
|
|
19469
|
+
const task = taskStore.createTask({
|
|
19470
|
+
contextId: import_crypto2.default.randomUUID(),
|
|
19471
|
+
requestMessage,
|
|
19472
|
+
workflowId,
|
|
19473
|
+
requestMetadata: {
|
|
19474
|
+
source,
|
|
19475
|
+
instance_id: getInstanceId(),
|
|
19476
|
+
trace_id: trace.getActiveSpan()?.spanContext().traceId || void 0,
|
|
19477
|
+
...metadata
|
|
19478
|
+
}
|
|
19479
|
+
});
|
|
19480
|
+
const instanceId = getInstanceId();
|
|
19481
|
+
taskStore.updateTaskState(task.id, "working");
|
|
19482
|
+
taskStore.claimTask(task.id, instanceId);
|
|
19483
|
+
logger.info(
|
|
19484
|
+
`[TaskTracking] Task ${task.id} started (source=${source}, workflow=${workflowId || "-"}, instance=${instanceId})`
|
|
19485
|
+
);
|
|
19486
|
+
try {
|
|
19487
|
+
const result = await executor();
|
|
19488
|
+
const completedMsg = {
|
|
19489
|
+
message_id: import_crypto2.default.randomUUID(),
|
|
19490
|
+
role: "agent",
|
|
19491
|
+
parts: [{ text: "Execution completed" }]
|
|
19492
|
+
};
|
|
19493
|
+
taskStore.updateTaskState(task.id, "completed", completedMsg);
|
|
19494
|
+
logger.info(`[TaskTracking] Task ${task.id} completed`);
|
|
19495
|
+
return { task, result };
|
|
19496
|
+
} catch (err) {
|
|
19497
|
+
const errorText = err instanceof Error ? err.message : String(err);
|
|
19498
|
+
const failMessage = {
|
|
19499
|
+
message_id: import_crypto2.default.randomUUID(),
|
|
19500
|
+
role: "agent",
|
|
19501
|
+
parts: [{ text: errorText }]
|
|
19502
|
+
};
|
|
19503
|
+
try {
|
|
19504
|
+
taskStore.updateTaskState(task.id, "failed", failMessage);
|
|
19505
|
+
logger.info(`[TaskTracking] Task ${task.id} failed: ${errorText}`);
|
|
19506
|
+
} catch {
|
|
19507
|
+
}
|
|
19508
|
+
throw err;
|
|
19509
|
+
}
|
|
19510
|
+
}
|
|
19511
|
+
var import_crypto2, import_path7;
|
|
19512
|
+
var init_track_execution = __esm({
|
|
19513
|
+
"src/agent-protocol/track-execution.ts"() {
|
|
19514
|
+
"use strict";
|
|
19515
|
+
import_crypto2 = __toESM(require("crypto"));
|
|
19516
|
+
import_path7 = __toESM(require("path"));
|
|
19517
|
+
init_logger();
|
|
19518
|
+
init_lazy_otel();
|
|
19519
|
+
init_instance_id();
|
|
19520
|
+
}
|
|
19521
|
+
});
|
|
19522
|
+
|
|
19434
19523
|
// src/scheduler/scheduler.ts
|
|
19435
19524
|
function getScheduler(visorConfig, config) {
|
|
19436
19525
|
if (!schedulerInstance && visorConfig) {
|
|
@@ -19460,6 +19549,8 @@ var init_scheduler = __esm({
|
|
|
19460
19549
|
outputAdapters = /* @__PURE__ */ new Map();
|
|
19461
19550
|
executionContext = {};
|
|
19462
19551
|
contextEnricher;
|
|
19552
|
+
taskStore;
|
|
19553
|
+
configPath;
|
|
19463
19554
|
// HA fields
|
|
19464
19555
|
haConfig;
|
|
19465
19556
|
nodeId;
|
|
@@ -19485,6 +19576,11 @@ var init_scheduler = __esm({
|
|
|
19485
19576
|
setEngine(engine) {
|
|
19486
19577
|
this.engine = engine;
|
|
19487
19578
|
}
|
|
19579
|
+
/** Set shared task store for execution tracking. */
|
|
19580
|
+
setTaskStore(store, configPath) {
|
|
19581
|
+
this.taskStore = store;
|
|
19582
|
+
this.configPath = configPath;
|
|
19583
|
+
}
|
|
19488
19584
|
/**
|
|
19489
19585
|
* Set the execution context (e.g., Slack client) for workflow executions
|
|
19490
19586
|
*/
|
|
@@ -20026,7 +20122,7 @@ var init_scheduler = __esm({
|
|
|
20026
20122
|
} catch {
|
|
20027
20123
|
}
|
|
20028
20124
|
const { engine: runEngine, config: cfgForRun } = this.prepareExecution(schedule);
|
|
20029
|
-
|
|
20125
|
+
const schedExecFn = () => runEngine.executeChecks({
|
|
20030
20126
|
checks: checksToRun,
|
|
20031
20127
|
showDetails: true,
|
|
20032
20128
|
outputFormat: "json",
|
|
@@ -20035,6 +20131,22 @@ var init_scheduler = __esm({
|
|
|
20035
20131
|
debug: process.env.VISOR_DEBUG === "true",
|
|
20036
20132
|
inputs: schedule.workflowInputs
|
|
20037
20133
|
});
|
|
20134
|
+
if (this.taskStore) {
|
|
20135
|
+
const { trackExecution: trackExecution2 } = await Promise.resolve().then(() => (init_track_execution(), track_execution_exports));
|
|
20136
|
+
await trackExecution2(
|
|
20137
|
+
{
|
|
20138
|
+
taskStore: this.taskStore,
|
|
20139
|
+
source: "scheduler",
|
|
20140
|
+
workflowId: schedule.workflow,
|
|
20141
|
+
configPath: this.configPath,
|
|
20142
|
+
messageText: `Scheduled: ${schedule.workflow} (${schedule.id})`,
|
|
20143
|
+
metadata: { schedule_id: schedule.id, is_recurring: schedule.isRecurring }
|
|
20144
|
+
},
|
|
20145
|
+
schedExecFn
|
|
20146
|
+
);
|
|
20147
|
+
} else {
|
|
20148
|
+
await schedExecFn();
|
|
20149
|
+
}
|
|
20038
20150
|
return { message: "Workflow completed", workflow: schedule.workflow };
|
|
20039
20151
|
}
|
|
20040
20152
|
/**
|
|
@@ -20140,7 +20252,7 @@ Please provide an updated response based on the reminder above. You may referenc
|
|
|
20140
20252
|
responseRef
|
|
20141
20253
|
} = this.prepareExecution(schedule, reminderText);
|
|
20142
20254
|
try {
|
|
20143
|
-
|
|
20255
|
+
const reminderExecFn = () => runEngine.executeChecks({
|
|
20144
20256
|
checks: allChecks,
|
|
20145
20257
|
showDetails: true,
|
|
20146
20258
|
outputFormat: "json",
|
|
@@ -20148,6 +20260,22 @@ Please provide an updated response based on the reminder above. You may referenc
|
|
|
20148
20260
|
webhookContext: { webhookData, eventType: "schedule" },
|
|
20149
20261
|
debug: process.env.VISOR_DEBUG === "true"
|
|
20150
20262
|
});
|
|
20263
|
+
if (this.taskStore) {
|
|
20264
|
+
const { trackExecution: trackExecution2 } = await Promise.resolve().then(() => (init_track_execution(), track_execution_exports));
|
|
20265
|
+
await trackExecution2(
|
|
20266
|
+
{
|
|
20267
|
+
taskStore: this.taskStore,
|
|
20268
|
+
source: "scheduler",
|
|
20269
|
+
workflowId: schedule.workflow,
|
|
20270
|
+
configPath: this.configPath,
|
|
20271
|
+
messageText: reminderText || `Reminder: ${schedule.id}`,
|
|
20272
|
+
metadata: { schedule_id: schedule.id, is_recurring: schedule.isRecurring }
|
|
20273
|
+
},
|
|
20274
|
+
reminderExecFn
|
|
20275
|
+
);
|
|
20276
|
+
} else {
|
|
20277
|
+
await reminderExecFn();
|
|
20278
|
+
}
|
|
20151
20279
|
if (schedule.isRecurring && responseRef.captured) {
|
|
20152
20280
|
await this.store.updateAsync(schedule.id, { previousResponse: responseRef.captured });
|
|
20153
20281
|
logger.info(
|
|
@@ -21396,7 +21524,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21396
21524
|
* Returns the actual bound port number
|
|
21397
21525
|
*/
|
|
21398
21526
|
async start() {
|
|
21399
|
-
return new Promise((
|
|
21527
|
+
return new Promise((resolve15, reject) => {
|
|
21400
21528
|
try {
|
|
21401
21529
|
this.server = import_http.default.createServer((req, res) => {
|
|
21402
21530
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -21430,7 +21558,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21430
21558
|
);
|
|
21431
21559
|
}
|
|
21432
21560
|
this.startKeepalive();
|
|
21433
|
-
|
|
21561
|
+
resolve15(this.port);
|
|
21434
21562
|
});
|
|
21435
21563
|
} catch (error) {
|
|
21436
21564
|
reject(error);
|
|
@@ -21493,7 +21621,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21493
21621
|
logger.debug(
|
|
21494
21622
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
21495
21623
|
);
|
|
21496
|
-
await new Promise((
|
|
21624
|
+
await new Promise((resolve15) => setTimeout(resolve15, waitMs));
|
|
21497
21625
|
}
|
|
21498
21626
|
}
|
|
21499
21627
|
if (this.activeToolCalls > 0) {
|
|
@@ -21502,7 +21630,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21502
21630
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
21503
21631
|
);
|
|
21504
21632
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
21505
|
-
await new Promise((
|
|
21633
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
21506
21634
|
}
|
|
21507
21635
|
if (this.activeToolCalls > 0) {
|
|
21508
21636
|
logger.warn(
|
|
@@ -21527,21 +21655,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21527
21655
|
}
|
|
21528
21656
|
this.connections.clear();
|
|
21529
21657
|
if (this.server) {
|
|
21530
|
-
await new Promise((
|
|
21658
|
+
await new Promise((resolve15, reject) => {
|
|
21531
21659
|
const timeout = setTimeout(() => {
|
|
21532
21660
|
if (this.debug) {
|
|
21533
21661
|
logger.debug(
|
|
21534
21662
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
21535
21663
|
);
|
|
21536
21664
|
}
|
|
21537
|
-
this.server?.close(() =>
|
|
21665
|
+
this.server?.close(() => resolve15());
|
|
21538
21666
|
}, 5e3);
|
|
21539
21667
|
this.server.close((error) => {
|
|
21540
21668
|
clearTimeout(timeout);
|
|
21541
21669
|
if (error) {
|
|
21542
21670
|
reject(error);
|
|
21543
21671
|
} else {
|
|
21544
|
-
|
|
21672
|
+
resolve15();
|
|
21545
21673
|
}
|
|
21546
21674
|
});
|
|
21547
21675
|
});
|
|
@@ -21976,7 +22104,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21976
22104
|
logger.warn(
|
|
21977
22105
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
21978
22106
|
);
|
|
21979
|
-
await new Promise((
|
|
22107
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
21980
22108
|
attempt++;
|
|
21981
22109
|
}
|
|
21982
22110
|
}
|
|
@@ -22099,7 +22227,7 @@ var init_tool_resolver = __esm({
|
|
|
22099
22227
|
});
|
|
22100
22228
|
|
|
22101
22229
|
// src/providers/ai-check-provider.ts
|
|
22102
|
-
var import_promises4,
|
|
22230
|
+
var import_promises4, import_path8, AICheckProvider;
|
|
22103
22231
|
var init_ai_check_provider = __esm({
|
|
22104
22232
|
"src/providers/ai-check-provider.ts"() {
|
|
22105
22233
|
"use strict";
|
|
@@ -22109,7 +22237,7 @@ var init_ai_check_provider = __esm({
|
|
|
22109
22237
|
init_issue_filter();
|
|
22110
22238
|
init_liquid_extensions();
|
|
22111
22239
|
import_promises4 = __toESM(require("fs/promises"));
|
|
22112
|
-
|
|
22240
|
+
import_path8 = __toESM(require("path"));
|
|
22113
22241
|
init_lazy_otel();
|
|
22114
22242
|
init_state_capture();
|
|
22115
22243
|
init_mcp_custom_sse_server();
|
|
@@ -22274,7 +22402,7 @@ var init_ai_check_provider = __esm({
|
|
|
22274
22402
|
const hasFileExtension = /\.[a-zA-Z0-9]{1,10}$/i.test(str);
|
|
22275
22403
|
const hasPathSeparators = /[\/\\]/.test(str);
|
|
22276
22404
|
const isRelativePath = /^\.{1,2}\//.test(str);
|
|
22277
|
-
const isAbsolutePath =
|
|
22405
|
+
const isAbsolutePath = import_path8.default.isAbsolute(str);
|
|
22278
22406
|
const hasTypicalFileChars = /^[a-zA-Z0-9._\-\/\\:~]+$/.test(str);
|
|
22279
22407
|
if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {
|
|
22280
22408
|
return false;
|
|
@@ -22284,14 +22412,14 @@ var init_ai_check_provider = __esm({
|
|
|
22284
22412
|
}
|
|
22285
22413
|
try {
|
|
22286
22414
|
let resolvedPath;
|
|
22287
|
-
if (
|
|
22288
|
-
resolvedPath =
|
|
22415
|
+
if (import_path8.default.isAbsolute(str)) {
|
|
22416
|
+
resolvedPath = import_path8.default.normalize(str);
|
|
22289
22417
|
} else {
|
|
22290
|
-
resolvedPath =
|
|
22418
|
+
resolvedPath = import_path8.default.resolve(process.cwd(), str);
|
|
22291
22419
|
}
|
|
22292
|
-
const
|
|
22420
|
+
const fs25 = require("fs").promises;
|
|
22293
22421
|
try {
|
|
22294
|
-
const stat2 = await
|
|
22422
|
+
const stat2 = await fs25.stat(resolvedPath);
|
|
22295
22423
|
return stat2.isFile();
|
|
22296
22424
|
} catch {
|
|
22297
22425
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -22308,14 +22436,14 @@ var init_ai_check_provider = __esm({
|
|
|
22308
22436
|
throw new Error("Prompt file must have .liquid extension");
|
|
22309
22437
|
}
|
|
22310
22438
|
let resolvedPath;
|
|
22311
|
-
if (
|
|
22439
|
+
if (import_path8.default.isAbsolute(promptPath)) {
|
|
22312
22440
|
resolvedPath = promptPath;
|
|
22313
22441
|
} else {
|
|
22314
|
-
resolvedPath =
|
|
22442
|
+
resolvedPath = import_path8.default.resolve(process.cwd(), promptPath);
|
|
22315
22443
|
}
|
|
22316
|
-
if (!
|
|
22317
|
-
const normalizedPath =
|
|
22318
|
-
const currentDir =
|
|
22444
|
+
if (!import_path8.default.isAbsolute(promptPath)) {
|
|
22445
|
+
const normalizedPath = import_path8.default.normalize(resolvedPath);
|
|
22446
|
+
const currentDir = import_path8.default.resolve(process.cwd());
|
|
22319
22447
|
if (!normalizedPath.startsWith(currentDir)) {
|
|
22320
22448
|
throw new Error("Invalid prompt file path: path traversal detected");
|
|
22321
22449
|
}
|
|
@@ -24494,7 +24622,7 @@ var init_oauth2_token_cache = __esm({
|
|
|
24494
24622
|
});
|
|
24495
24623
|
|
|
24496
24624
|
// src/providers/http-client-provider.ts
|
|
24497
|
-
var fs15,
|
|
24625
|
+
var fs15, path19, HttpClientProvider;
|
|
24498
24626
|
var init_http_client_provider = __esm({
|
|
24499
24627
|
"src/providers/http-client-provider.ts"() {
|
|
24500
24628
|
"use strict";
|
|
@@ -24506,7 +24634,7 @@ var init_http_client_provider = __esm({
|
|
|
24506
24634
|
init_oauth2_token_cache();
|
|
24507
24635
|
init_logger();
|
|
24508
24636
|
fs15 = __toESM(require("fs"));
|
|
24509
|
-
|
|
24637
|
+
path19 = __toESM(require("path"));
|
|
24510
24638
|
HttpClientProvider = class extends CheckProvider {
|
|
24511
24639
|
liquid;
|
|
24512
24640
|
sandbox;
|
|
@@ -24629,8 +24757,8 @@ var init_http_client_provider = __esm({
|
|
|
24629
24757
|
const parentContext = context2?._parentContext;
|
|
24630
24758
|
const workingDirectory = parentContext?.workingDirectory;
|
|
24631
24759
|
const workspaceEnabled = parentContext?.workspace?.isEnabled?.();
|
|
24632
|
-
if (workspaceEnabled && workingDirectory && !
|
|
24633
|
-
resolvedOutputFile =
|
|
24760
|
+
if (workspaceEnabled && workingDirectory && !path19.isAbsolute(resolvedOutputFile)) {
|
|
24761
|
+
resolvedOutputFile = path19.join(workingDirectory, resolvedOutputFile);
|
|
24634
24762
|
logger.debug(
|
|
24635
24763
|
`[http_client] Resolved relative output_file to workspace: ${resolvedOutputFile}`
|
|
24636
24764
|
);
|
|
@@ -24847,7 +24975,7 @@ var init_http_client_provider = __esm({
|
|
|
24847
24975
|
]
|
|
24848
24976
|
};
|
|
24849
24977
|
}
|
|
24850
|
-
const parentDir =
|
|
24978
|
+
const parentDir = path19.dirname(outputFile);
|
|
24851
24979
|
if (parentDir && !fs15.existsSync(parentDir)) {
|
|
24852
24980
|
fs15.mkdirSync(parentDir, { recursive: true });
|
|
24853
24981
|
}
|
|
@@ -25617,7 +25745,7 @@ var init_claude_code_types = __esm({
|
|
|
25617
25745
|
function isClaudeCodeConstructor(value) {
|
|
25618
25746
|
return typeof value === "function";
|
|
25619
25747
|
}
|
|
25620
|
-
var import_promises5,
|
|
25748
|
+
var import_promises5, import_path9, ClaudeCodeSDKNotInstalledError, ClaudeCodeAPIKeyMissingError, ClaudeCodeCheckProvider;
|
|
25621
25749
|
var init_claude_code_check_provider = __esm({
|
|
25622
25750
|
"src/providers/claude-code-check-provider.ts"() {
|
|
25623
25751
|
"use strict";
|
|
@@ -25626,7 +25754,7 @@ var init_claude_code_check_provider = __esm({
|
|
|
25626
25754
|
init_issue_filter();
|
|
25627
25755
|
init_liquid_extensions();
|
|
25628
25756
|
import_promises5 = __toESM(require("fs/promises"));
|
|
25629
|
-
|
|
25757
|
+
import_path9 = __toESM(require("path"));
|
|
25630
25758
|
init_claude_code_types();
|
|
25631
25759
|
ClaudeCodeSDKNotInstalledError = class extends Error {
|
|
25632
25760
|
constructor() {
|
|
@@ -25774,7 +25902,7 @@ var init_claude_code_check_provider = __esm({
|
|
|
25774
25902
|
const hasFileExtension = /\.[a-zA-Z0-9]{1,10}$/i.test(str);
|
|
25775
25903
|
const hasPathSeparators = /[\/\\]/.test(str);
|
|
25776
25904
|
const isRelativePath = /^\.{1,2}\//.test(str);
|
|
25777
|
-
const isAbsolutePath =
|
|
25905
|
+
const isAbsolutePath = import_path9.default.isAbsolute(str);
|
|
25778
25906
|
const hasTypicalFileChars = /^[a-zA-Z0-9._\-\/\\:~]+$/.test(str);
|
|
25779
25907
|
if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {
|
|
25780
25908
|
return false;
|
|
@@ -25784,10 +25912,10 @@ var init_claude_code_check_provider = __esm({
|
|
|
25784
25912
|
}
|
|
25785
25913
|
try {
|
|
25786
25914
|
let resolvedPath;
|
|
25787
|
-
if (
|
|
25788
|
-
resolvedPath =
|
|
25915
|
+
if (import_path9.default.isAbsolute(str)) {
|
|
25916
|
+
resolvedPath = import_path9.default.normalize(str);
|
|
25789
25917
|
} else {
|
|
25790
|
-
resolvedPath =
|
|
25918
|
+
resolvedPath = import_path9.default.resolve(process.cwd(), str);
|
|
25791
25919
|
}
|
|
25792
25920
|
try {
|
|
25793
25921
|
const stat2 = await import_promises5.default.stat(resolvedPath);
|
|
@@ -25807,14 +25935,14 @@ var init_claude_code_check_provider = __esm({
|
|
|
25807
25935
|
throw new Error("Prompt file must have .liquid extension");
|
|
25808
25936
|
}
|
|
25809
25937
|
let resolvedPath;
|
|
25810
|
-
if (
|
|
25938
|
+
if (import_path9.default.isAbsolute(promptPath)) {
|
|
25811
25939
|
resolvedPath = promptPath;
|
|
25812
25940
|
} else {
|
|
25813
|
-
resolvedPath =
|
|
25941
|
+
resolvedPath = import_path9.default.resolve(process.cwd(), promptPath);
|
|
25814
25942
|
}
|
|
25815
|
-
if (!
|
|
25816
|
-
const normalizedPath =
|
|
25817
|
-
const currentDir =
|
|
25943
|
+
if (!import_path9.default.isAbsolute(promptPath)) {
|
|
25944
|
+
const normalizedPath = import_path9.default.normalize(resolvedPath);
|
|
25945
|
+
const currentDir = import_path9.default.resolve(process.cwd());
|
|
25818
25946
|
if (!normalizedPath.startsWith(currentDir)) {
|
|
25819
25947
|
throw new Error("Invalid prompt file path: path traversal detected");
|
|
25820
25948
|
}
|
|
@@ -28393,14 +28521,14 @@ var require_util = __commonJS({
|
|
|
28393
28521
|
}
|
|
28394
28522
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
28395
28523
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
28396
|
-
let
|
|
28524
|
+
let path29 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
28397
28525
|
if (origin.endsWith("/")) {
|
|
28398
28526
|
origin = origin.substring(0, origin.length - 1);
|
|
28399
28527
|
}
|
|
28400
|
-
if (
|
|
28401
|
-
|
|
28528
|
+
if (path29 && !path29.startsWith("/")) {
|
|
28529
|
+
path29 = `/${path29}`;
|
|
28402
28530
|
}
|
|
28403
|
-
url = new URL(origin +
|
|
28531
|
+
url = new URL(origin + path29);
|
|
28404
28532
|
}
|
|
28405
28533
|
return url;
|
|
28406
28534
|
}
|
|
@@ -30014,20 +30142,20 @@ var require_parseParams = __commonJS({
|
|
|
30014
30142
|
var require_basename = __commonJS({
|
|
30015
30143
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
30016
30144
|
"use strict";
|
|
30017
|
-
module2.exports = function basename4(
|
|
30018
|
-
if (typeof
|
|
30145
|
+
module2.exports = function basename4(path29) {
|
|
30146
|
+
if (typeof path29 !== "string") {
|
|
30019
30147
|
return "";
|
|
30020
30148
|
}
|
|
30021
|
-
for (var i =
|
|
30022
|
-
switch (
|
|
30149
|
+
for (var i = path29.length - 1; i >= 0; --i) {
|
|
30150
|
+
switch (path29.charCodeAt(i)) {
|
|
30023
30151
|
case 47:
|
|
30024
30152
|
// '/'
|
|
30025
30153
|
case 92:
|
|
30026
|
-
|
|
30027
|
-
return
|
|
30154
|
+
path29 = path29.slice(i + 1);
|
|
30155
|
+
return path29 === ".." || path29 === "." ? "" : path29;
|
|
30028
30156
|
}
|
|
30029
30157
|
}
|
|
30030
|
-
return
|
|
30158
|
+
return path29 === ".." || path29 === "." ? "" : path29;
|
|
30031
30159
|
};
|
|
30032
30160
|
}
|
|
30033
30161
|
});
|
|
@@ -31031,11 +31159,11 @@ var require_util2 = __commonJS({
|
|
|
31031
31159
|
var assert = require("assert");
|
|
31032
31160
|
var { isUint8Array } = require("util/types");
|
|
31033
31161
|
var supportedHashes = [];
|
|
31034
|
-
var
|
|
31162
|
+
var crypto7;
|
|
31035
31163
|
try {
|
|
31036
|
-
|
|
31164
|
+
crypto7 = require("crypto");
|
|
31037
31165
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
31038
|
-
supportedHashes =
|
|
31166
|
+
supportedHashes = crypto7.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
31039
31167
|
} catch {
|
|
31040
31168
|
}
|
|
31041
31169
|
function responseURL(response) {
|
|
@@ -31312,7 +31440,7 @@ var require_util2 = __commonJS({
|
|
|
31312
31440
|
}
|
|
31313
31441
|
}
|
|
31314
31442
|
function bytesMatch(bytes, metadataList) {
|
|
31315
|
-
if (
|
|
31443
|
+
if (crypto7 === void 0) {
|
|
31316
31444
|
return true;
|
|
31317
31445
|
}
|
|
31318
31446
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -31327,7 +31455,7 @@ var require_util2 = __commonJS({
|
|
|
31327
31455
|
for (const item of metadata) {
|
|
31328
31456
|
const algorithm = item.algo;
|
|
31329
31457
|
const expectedValue = item.hash;
|
|
31330
|
-
let actualValue =
|
|
31458
|
+
let actualValue = crypto7.createHash(algorithm).update(bytes).digest("base64");
|
|
31331
31459
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
31332
31460
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
31333
31461
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -31420,8 +31548,8 @@ var require_util2 = __commonJS({
|
|
|
31420
31548
|
function createDeferredPromise() {
|
|
31421
31549
|
let res;
|
|
31422
31550
|
let rej;
|
|
31423
|
-
const promise = new Promise((
|
|
31424
|
-
res =
|
|
31551
|
+
const promise = new Promise((resolve15, reject) => {
|
|
31552
|
+
res = resolve15;
|
|
31425
31553
|
rej = reject;
|
|
31426
31554
|
});
|
|
31427
31555
|
return { promise, resolve: res, reject: rej };
|
|
@@ -32674,8 +32802,8 @@ var require_body = __commonJS({
|
|
|
32674
32802
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
32675
32803
|
var random;
|
|
32676
32804
|
try {
|
|
32677
|
-
const
|
|
32678
|
-
random = (max) =>
|
|
32805
|
+
const crypto7 = require("crypto");
|
|
32806
|
+
random = (max) => crypto7.randomInt(0, max);
|
|
32679
32807
|
} catch {
|
|
32680
32808
|
random = (max) => Math.floor(Math.random(max));
|
|
32681
32809
|
}
|
|
@@ -32926,8 +33054,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
32926
33054
|
});
|
|
32927
33055
|
}
|
|
32928
33056
|
});
|
|
32929
|
-
const busboyResolve = new Promise((
|
|
32930
|
-
busboy.on("finish",
|
|
33057
|
+
const busboyResolve = new Promise((resolve15, reject) => {
|
|
33058
|
+
busboy.on("finish", resolve15);
|
|
32931
33059
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
32932
33060
|
});
|
|
32933
33061
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -33058,7 +33186,7 @@ var require_request = __commonJS({
|
|
|
33058
33186
|
}
|
|
33059
33187
|
var Request = class _Request {
|
|
33060
33188
|
constructor(origin, {
|
|
33061
|
-
path:
|
|
33189
|
+
path: path29,
|
|
33062
33190
|
method,
|
|
33063
33191
|
body,
|
|
33064
33192
|
headers,
|
|
@@ -33072,11 +33200,11 @@ var require_request = __commonJS({
|
|
|
33072
33200
|
throwOnError,
|
|
33073
33201
|
expectContinue
|
|
33074
33202
|
}, handler) {
|
|
33075
|
-
if (typeof
|
|
33203
|
+
if (typeof path29 !== "string") {
|
|
33076
33204
|
throw new InvalidArgumentError("path must be a string");
|
|
33077
|
-
} else if (
|
|
33205
|
+
} else if (path29[0] !== "/" && !(path29.startsWith("http://") || path29.startsWith("https://")) && method !== "CONNECT") {
|
|
33078
33206
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
33079
|
-
} else if (invalidPathRegex.exec(
|
|
33207
|
+
} else if (invalidPathRegex.exec(path29) !== null) {
|
|
33080
33208
|
throw new InvalidArgumentError("invalid request path");
|
|
33081
33209
|
}
|
|
33082
33210
|
if (typeof method !== "string") {
|
|
@@ -33139,7 +33267,7 @@ var require_request = __commonJS({
|
|
|
33139
33267
|
this.completed = false;
|
|
33140
33268
|
this.aborted = false;
|
|
33141
33269
|
this.upgrade = upgrade || null;
|
|
33142
|
-
this.path = query ? util.buildURL(
|
|
33270
|
+
this.path = query ? util.buildURL(path29, query) : path29;
|
|
33143
33271
|
this.origin = origin;
|
|
33144
33272
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
33145
33273
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -33461,9 +33589,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
33461
33589
|
}
|
|
33462
33590
|
close(callback) {
|
|
33463
33591
|
if (callback === void 0) {
|
|
33464
|
-
return new Promise((
|
|
33592
|
+
return new Promise((resolve15, reject) => {
|
|
33465
33593
|
this.close((err, data) => {
|
|
33466
|
-
return err ? reject(err) :
|
|
33594
|
+
return err ? reject(err) : resolve15(data);
|
|
33467
33595
|
});
|
|
33468
33596
|
});
|
|
33469
33597
|
}
|
|
@@ -33501,12 +33629,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
33501
33629
|
err = null;
|
|
33502
33630
|
}
|
|
33503
33631
|
if (callback === void 0) {
|
|
33504
|
-
return new Promise((
|
|
33632
|
+
return new Promise((resolve15, reject) => {
|
|
33505
33633
|
this.destroy(err, (err2, data) => {
|
|
33506
33634
|
return err2 ? (
|
|
33507
33635
|
/* istanbul ignore next: should never error */
|
|
33508
33636
|
reject(err2)
|
|
33509
|
-
) :
|
|
33637
|
+
) : resolve15(data);
|
|
33510
33638
|
});
|
|
33511
33639
|
});
|
|
33512
33640
|
}
|
|
@@ -34147,9 +34275,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
34147
34275
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
34148
34276
|
}
|
|
34149
34277
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
34150
|
-
const
|
|
34278
|
+
const path29 = search ? `${pathname}${search}` : pathname;
|
|
34151
34279
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
34152
|
-
this.opts.path =
|
|
34280
|
+
this.opts.path = path29;
|
|
34153
34281
|
this.opts.origin = origin;
|
|
34154
34282
|
this.opts.maxRedirections = 0;
|
|
34155
34283
|
this.opts.query = null;
|
|
@@ -34568,16 +34696,16 @@ var require_client = __commonJS({
|
|
|
34568
34696
|
return this[kNeedDrain] < 2;
|
|
34569
34697
|
}
|
|
34570
34698
|
async [kClose]() {
|
|
34571
|
-
return new Promise((
|
|
34699
|
+
return new Promise((resolve15) => {
|
|
34572
34700
|
if (!this[kSize]) {
|
|
34573
|
-
|
|
34701
|
+
resolve15(null);
|
|
34574
34702
|
} else {
|
|
34575
|
-
this[kClosedResolve] =
|
|
34703
|
+
this[kClosedResolve] = resolve15;
|
|
34576
34704
|
}
|
|
34577
34705
|
});
|
|
34578
34706
|
}
|
|
34579
34707
|
async [kDestroy](err) {
|
|
34580
|
-
return new Promise((
|
|
34708
|
+
return new Promise((resolve15) => {
|
|
34581
34709
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
34582
34710
|
for (let i = 0; i < requests.length; i++) {
|
|
34583
34711
|
const request = requests[i];
|
|
@@ -34588,7 +34716,7 @@ var require_client = __commonJS({
|
|
|
34588
34716
|
this[kClosedResolve]();
|
|
34589
34717
|
this[kClosedResolve] = null;
|
|
34590
34718
|
}
|
|
34591
|
-
|
|
34719
|
+
resolve15();
|
|
34592
34720
|
};
|
|
34593
34721
|
if (this[kHTTP2Session] != null) {
|
|
34594
34722
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -35168,7 +35296,7 @@ var require_client = __commonJS({
|
|
|
35168
35296
|
});
|
|
35169
35297
|
}
|
|
35170
35298
|
try {
|
|
35171
|
-
const socket = await new Promise((
|
|
35299
|
+
const socket = await new Promise((resolve15, reject) => {
|
|
35172
35300
|
client[kConnector]({
|
|
35173
35301
|
host,
|
|
35174
35302
|
hostname,
|
|
@@ -35180,7 +35308,7 @@ var require_client = __commonJS({
|
|
|
35180
35308
|
if (err) {
|
|
35181
35309
|
reject(err);
|
|
35182
35310
|
} else {
|
|
35183
|
-
|
|
35311
|
+
resolve15(socket2);
|
|
35184
35312
|
}
|
|
35185
35313
|
});
|
|
35186
35314
|
});
|
|
@@ -35391,7 +35519,7 @@ var require_client = __commonJS({
|
|
|
35391
35519
|
writeH2(client, client[kHTTP2Session], request);
|
|
35392
35520
|
return;
|
|
35393
35521
|
}
|
|
35394
|
-
const { body, method, path:
|
|
35522
|
+
const { body, method, path: path29, host, upgrade, headers, blocking, reset } = request;
|
|
35395
35523
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
35396
35524
|
if (body && typeof body.read === "function") {
|
|
35397
35525
|
body.read(0);
|
|
@@ -35441,7 +35569,7 @@ var require_client = __commonJS({
|
|
|
35441
35569
|
if (blocking) {
|
|
35442
35570
|
socket[kBlocking] = true;
|
|
35443
35571
|
}
|
|
35444
|
-
let header = `${method} ${
|
|
35572
|
+
let header = `${method} ${path29} HTTP/1.1\r
|
|
35445
35573
|
`;
|
|
35446
35574
|
if (typeof host === "string") {
|
|
35447
35575
|
header += `host: ${host}\r
|
|
@@ -35504,7 +35632,7 @@ upgrade: ${upgrade}\r
|
|
|
35504
35632
|
return true;
|
|
35505
35633
|
}
|
|
35506
35634
|
function writeH2(client, session, request) {
|
|
35507
|
-
const { body, method, path:
|
|
35635
|
+
const { body, method, path: path29, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
35508
35636
|
let headers;
|
|
35509
35637
|
if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
35510
35638
|
else headers = reqHeaders;
|
|
@@ -35547,7 +35675,7 @@ upgrade: ${upgrade}\r
|
|
|
35547
35675
|
});
|
|
35548
35676
|
return true;
|
|
35549
35677
|
}
|
|
35550
|
-
headers[HTTP2_HEADER_PATH] =
|
|
35678
|
+
headers[HTTP2_HEADER_PATH] = path29;
|
|
35551
35679
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
35552
35680
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
35553
35681
|
if (body && typeof body.read === "function") {
|
|
@@ -35804,12 +35932,12 @@ upgrade: ${upgrade}\r
|
|
|
35804
35932
|
cb();
|
|
35805
35933
|
}
|
|
35806
35934
|
}
|
|
35807
|
-
const waitForDrain = () => new Promise((
|
|
35935
|
+
const waitForDrain = () => new Promise((resolve15, reject) => {
|
|
35808
35936
|
assert(callback === null);
|
|
35809
35937
|
if (socket[kError]) {
|
|
35810
35938
|
reject(socket[kError]);
|
|
35811
35939
|
} else {
|
|
35812
|
-
callback =
|
|
35940
|
+
callback = resolve15;
|
|
35813
35941
|
}
|
|
35814
35942
|
});
|
|
35815
35943
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -36155,8 +36283,8 @@ var require_pool_base = __commonJS({
|
|
|
36155
36283
|
if (this[kQueue].isEmpty()) {
|
|
36156
36284
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
36157
36285
|
} else {
|
|
36158
|
-
return new Promise((
|
|
36159
|
-
this[kClosedResolve] =
|
|
36286
|
+
return new Promise((resolve15) => {
|
|
36287
|
+
this[kClosedResolve] = resolve15;
|
|
36160
36288
|
});
|
|
36161
36289
|
}
|
|
36162
36290
|
}
|
|
@@ -36734,7 +36862,7 @@ var require_readable = __commonJS({
|
|
|
36734
36862
|
if (this.closed) {
|
|
36735
36863
|
return Promise.resolve(null);
|
|
36736
36864
|
}
|
|
36737
|
-
return new Promise((
|
|
36865
|
+
return new Promise((resolve15, reject) => {
|
|
36738
36866
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
36739
36867
|
this.destroy();
|
|
36740
36868
|
}) : noop;
|
|
@@ -36743,7 +36871,7 @@ var require_readable = __commonJS({
|
|
|
36743
36871
|
if (signal && signal.aborted) {
|
|
36744
36872
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
36745
36873
|
} else {
|
|
36746
|
-
|
|
36874
|
+
resolve15(null);
|
|
36747
36875
|
}
|
|
36748
36876
|
}).on("error", noop).on("data", function(chunk) {
|
|
36749
36877
|
limit -= chunk.length;
|
|
@@ -36765,11 +36893,11 @@ var require_readable = __commonJS({
|
|
|
36765
36893
|
throw new TypeError("unusable");
|
|
36766
36894
|
}
|
|
36767
36895
|
assert(!stream[kConsume]);
|
|
36768
|
-
return new Promise((
|
|
36896
|
+
return new Promise((resolve15, reject) => {
|
|
36769
36897
|
stream[kConsume] = {
|
|
36770
36898
|
type,
|
|
36771
36899
|
stream,
|
|
36772
|
-
resolve:
|
|
36900
|
+
resolve: resolve15,
|
|
36773
36901
|
reject,
|
|
36774
36902
|
length: 0,
|
|
36775
36903
|
body: []
|
|
@@ -36804,12 +36932,12 @@ var require_readable = __commonJS({
|
|
|
36804
36932
|
}
|
|
36805
36933
|
}
|
|
36806
36934
|
function consumeEnd(consume2) {
|
|
36807
|
-
const { type, body, resolve:
|
|
36935
|
+
const { type, body, resolve: resolve15, stream, length } = consume2;
|
|
36808
36936
|
try {
|
|
36809
36937
|
if (type === "text") {
|
|
36810
|
-
|
|
36938
|
+
resolve15(toUSVString(Buffer.concat(body)));
|
|
36811
36939
|
} else if (type === "json") {
|
|
36812
|
-
|
|
36940
|
+
resolve15(JSON.parse(Buffer.concat(body)));
|
|
36813
36941
|
} else if (type === "arrayBuffer") {
|
|
36814
36942
|
const dst = new Uint8Array(length);
|
|
36815
36943
|
let pos = 0;
|
|
@@ -36817,12 +36945,12 @@ var require_readable = __commonJS({
|
|
|
36817
36945
|
dst.set(buf, pos);
|
|
36818
36946
|
pos += buf.byteLength;
|
|
36819
36947
|
}
|
|
36820
|
-
|
|
36948
|
+
resolve15(dst.buffer);
|
|
36821
36949
|
} else if (type === "blob") {
|
|
36822
36950
|
if (!Blob2) {
|
|
36823
36951
|
Blob2 = require("buffer").Blob;
|
|
36824
36952
|
}
|
|
36825
|
-
|
|
36953
|
+
resolve15(new Blob2(body, { type: stream[kContentType] }));
|
|
36826
36954
|
}
|
|
36827
36955
|
consumeFinish(consume2);
|
|
36828
36956
|
} catch (err) {
|
|
@@ -37079,9 +37207,9 @@ var require_api_request = __commonJS({
|
|
|
37079
37207
|
};
|
|
37080
37208
|
function request(opts, callback) {
|
|
37081
37209
|
if (callback === void 0) {
|
|
37082
|
-
return new Promise((
|
|
37210
|
+
return new Promise((resolve15, reject) => {
|
|
37083
37211
|
request.call(this, opts, (err, data) => {
|
|
37084
|
-
return err ? reject(err) :
|
|
37212
|
+
return err ? reject(err) : resolve15(data);
|
|
37085
37213
|
});
|
|
37086
37214
|
});
|
|
37087
37215
|
}
|
|
@@ -37254,9 +37382,9 @@ var require_api_stream = __commonJS({
|
|
|
37254
37382
|
};
|
|
37255
37383
|
function stream(opts, factory, callback) {
|
|
37256
37384
|
if (callback === void 0) {
|
|
37257
|
-
return new Promise((
|
|
37385
|
+
return new Promise((resolve15, reject) => {
|
|
37258
37386
|
stream.call(this, opts, factory, (err, data) => {
|
|
37259
|
-
return err ? reject(err) :
|
|
37387
|
+
return err ? reject(err) : resolve15(data);
|
|
37260
37388
|
});
|
|
37261
37389
|
});
|
|
37262
37390
|
}
|
|
@@ -37537,9 +37665,9 @@ var require_api_upgrade = __commonJS({
|
|
|
37537
37665
|
};
|
|
37538
37666
|
function upgrade(opts, callback) {
|
|
37539
37667
|
if (callback === void 0) {
|
|
37540
|
-
return new Promise((
|
|
37668
|
+
return new Promise((resolve15, reject) => {
|
|
37541
37669
|
upgrade.call(this, opts, (err, data) => {
|
|
37542
|
-
return err ? reject(err) :
|
|
37670
|
+
return err ? reject(err) : resolve15(data);
|
|
37543
37671
|
});
|
|
37544
37672
|
});
|
|
37545
37673
|
}
|
|
@@ -37628,9 +37756,9 @@ var require_api_connect = __commonJS({
|
|
|
37628
37756
|
};
|
|
37629
37757
|
function connect(opts, callback) {
|
|
37630
37758
|
if (callback === void 0) {
|
|
37631
|
-
return new Promise((
|
|
37759
|
+
return new Promise((resolve15, reject) => {
|
|
37632
37760
|
connect.call(this, opts, (err, data) => {
|
|
37633
|
-
return err ? reject(err) :
|
|
37761
|
+
return err ? reject(err) : resolve15(data);
|
|
37634
37762
|
});
|
|
37635
37763
|
});
|
|
37636
37764
|
}
|
|
@@ -37790,20 +37918,20 @@ var require_mock_utils = __commonJS({
|
|
|
37790
37918
|
}
|
|
37791
37919
|
return true;
|
|
37792
37920
|
}
|
|
37793
|
-
function safeUrl(
|
|
37794
|
-
if (typeof
|
|
37795
|
-
return
|
|
37921
|
+
function safeUrl(path29) {
|
|
37922
|
+
if (typeof path29 !== "string") {
|
|
37923
|
+
return path29;
|
|
37796
37924
|
}
|
|
37797
|
-
const pathSegments =
|
|
37925
|
+
const pathSegments = path29.split("?");
|
|
37798
37926
|
if (pathSegments.length !== 2) {
|
|
37799
|
-
return
|
|
37927
|
+
return path29;
|
|
37800
37928
|
}
|
|
37801
37929
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
37802
37930
|
qp.sort();
|
|
37803
37931
|
return [...pathSegments, qp.toString()].join("?");
|
|
37804
37932
|
}
|
|
37805
|
-
function matchKey(mockDispatch2, { path:
|
|
37806
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
37933
|
+
function matchKey(mockDispatch2, { path: path29, method, body, headers }) {
|
|
37934
|
+
const pathMatch = matchValue(mockDispatch2.path, path29);
|
|
37807
37935
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
37808
37936
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
37809
37937
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -37821,7 +37949,7 @@ var require_mock_utils = __commonJS({
|
|
|
37821
37949
|
function getMockDispatch(mockDispatches, key) {
|
|
37822
37950
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
37823
37951
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
37824
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
37952
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path29 }) => matchValue(safeUrl(path29), resolvedPath));
|
|
37825
37953
|
if (matchedMockDispatches.length === 0) {
|
|
37826
37954
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
37827
37955
|
}
|
|
@@ -37858,9 +37986,9 @@ var require_mock_utils = __commonJS({
|
|
|
37858
37986
|
}
|
|
37859
37987
|
}
|
|
37860
37988
|
function buildKey(opts) {
|
|
37861
|
-
const { path:
|
|
37989
|
+
const { path: path29, method, body, headers, query } = opts;
|
|
37862
37990
|
return {
|
|
37863
|
-
path:
|
|
37991
|
+
path: path29,
|
|
37864
37992
|
method,
|
|
37865
37993
|
body,
|
|
37866
37994
|
headers,
|
|
@@ -38309,10 +38437,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
38309
38437
|
}
|
|
38310
38438
|
format(pendingInterceptors) {
|
|
38311
38439
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
38312
|
-
({ method, path:
|
|
38440
|
+
({ method, path: path29, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
38313
38441
|
Method: method,
|
|
38314
38442
|
Origin: origin,
|
|
38315
|
-
Path:
|
|
38443
|
+
Path: path29,
|
|
38316
38444
|
"Status code": statusCode,
|
|
38317
38445
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
38318
38446
|
Invocations: timesInvoked,
|
|
@@ -41253,7 +41381,7 @@ var require_fetch = __commonJS({
|
|
|
41253
41381
|
async function dispatch({ body }) {
|
|
41254
41382
|
const url = requestCurrentURL(request);
|
|
41255
41383
|
const agent = fetchParams.controller.dispatcher;
|
|
41256
|
-
return new Promise((
|
|
41384
|
+
return new Promise((resolve15, reject) => agent.dispatch(
|
|
41257
41385
|
{
|
|
41258
41386
|
path: url.pathname + url.search,
|
|
41259
41387
|
origin: url.origin,
|
|
@@ -41329,7 +41457,7 @@ var require_fetch = __commonJS({
|
|
|
41329
41457
|
}
|
|
41330
41458
|
}
|
|
41331
41459
|
}
|
|
41332
|
-
|
|
41460
|
+
resolve15({
|
|
41333
41461
|
status,
|
|
41334
41462
|
statusText,
|
|
41335
41463
|
headersList: headers[kHeadersList],
|
|
@@ -41372,7 +41500,7 @@ var require_fetch = __commonJS({
|
|
|
41372
41500
|
const val = headersList[n + 1].toString("latin1");
|
|
41373
41501
|
headers[kHeadersList].append(key, val);
|
|
41374
41502
|
}
|
|
41375
|
-
|
|
41503
|
+
resolve15({
|
|
41376
41504
|
status,
|
|
41377
41505
|
statusText: STATUS_CODES[status],
|
|
41378
41506
|
headersList: headers[kHeadersList],
|
|
@@ -42933,8 +43061,8 @@ var require_util6 = __commonJS({
|
|
|
42933
43061
|
}
|
|
42934
43062
|
}
|
|
42935
43063
|
}
|
|
42936
|
-
function validateCookiePath(
|
|
42937
|
-
for (const char of
|
|
43064
|
+
function validateCookiePath(path29) {
|
|
43065
|
+
for (const char of path29) {
|
|
42938
43066
|
const code = char.charCodeAt(0);
|
|
42939
43067
|
if (code < 33 || char === ";") {
|
|
42940
43068
|
throw new Error("Invalid cookie path");
|
|
@@ -43731,9 +43859,9 @@ var require_connection = __commonJS({
|
|
|
43731
43859
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
43732
43860
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
43733
43861
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
43734
|
-
var
|
|
43862
|
+
var crypto7;
|
|
43735
43863
|
try {
|
|
43736
|
-
|
|
43864
|
+
crypto7 = require("crypto");
|
|
43737
43865
|
} catch {
|
|
43738
43866
|
}
|
|
43739
43867
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -43752,7 +43880,7 @@ var require_connection = __commonJS({
|
|
|
43752
43880
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
43753
43881
|
request.headersList = headersList;
|
|
43754
43882
|
}
|
|
43755
|
-
const keyValue =
|
|
43883
|
+
const keyValue = crypto7.randomBytes(16).toString("base64");
|
|
43756
43884
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
43757
43885
|
request.headersList.append("sec-websocket-version", "13");
|
|
43758
43886
|
for (const protocol of protocols) {
|
|
@@ -43781,7 +43909,7 @@ var require_connection = __commonJS({
|
|
|
43781
43909
|
return;
|
|
43782
43910
|
}
|
|
43783
43911
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
43784
|
-
const digest =
|
|
43912
|
+
const digest = crypto7.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
43785
43913
|
if (secWSAccept !== digest) {
|
|
43786
43914
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
43787
43915
|
return;
|
|
@@ -43861,9 +43989,9 @@ var require_frame = __commonJS({
|
|
|
43861
43989
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
43862
43990
|
"use strict";
|
|
43863
43991
|
var { maxUnsigned16Bit } = require_constants5();
|
|
43864
|
-
var
|
|
43992
|
+
var crypto7;
|
|
43865
43993
|
try {
|
|
43866
|
-
|
|
43994
|
+
crypto7 = require("crypto");
|
|
43867
43995
|
} catch {
|
|
43868
43996
|
}
|
|
43869
43997
|
var WebsocketFrameSend = class {
|
|
@@ -43872,7 +44000,7 @@ var require_frame = __commonJS({
|
|
|
43872
44000
|
*/
|
|
43873
44001
|
constructor(data) {
|
|
43874
44002
|
this.frameData = data;
|
|
43875
|
-
this.maskKey =
|
|
44003
|
+
this.maskKey = crypto7.randomBytes(4);
|
|
43876
44004
|
}
|
|
43877
44005
|
createFrame(opcode) {
|
|
43878
44006
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -44614,11 +44742,11 @@ var require_undici = __commonJS({
|
|
|
44614
44742
|
if (typeof opts.path !== "string") {
|
|
44615
44743
|
throw new InvalidArgumentError("invalid opts.path");
|
|
44616
44744
|
}
|
|
44617
|
-
let
|
|
44745
|
+
let path29 = opts.path;
|
|
44618
44746
|
if (!opts.path.startsWith("/")) {
|
|
44619
|
-
|
|
44747
|
+
path29 = `/${path29}`;
|
|
44620
44748
|
}
|
|
44621
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
44749
|
+
url = new URL(util.parseOrigin(url).origin + path29);
|
|
44622
44750
|
} else {
|
|
44623
44751
|
if (!opts) {
|
|
44624
44752
|
opts = typeof url === "object" ? url : {};
|
|
@@ -45167,7 +45295,7 @@ var init_mcp_check_provider = __esm({
|
|
|
45167
45295
|
logger.warn(
|
|
45168
45296
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
45169
45297
|
);
|
|
45170
|
-
await new Promise((
|
|
45298
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
45171
45299
|
attempt += 1;
|
|
45172
45300
|
} finally {
|
|
45173
45301
|
try {
|
|
@@ -45460,7 +45588,7 @@ async function acquirePromptLock() {
|
|
|
45460
45588
|
);
|
|
45461
45589
|
}, 1e4);
|
|
45462
45590
|
try {
|
|
45463
|
-
await new Promise((
|
|
45591
|
+
await new Promise((resolve15) => waiters.push(resolve15));
|
|
45464
45592
|
} finally {
|
|
45465
45593
|
clearInterval(reminder);
|
|
45466
45594
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -45479,7 +45607,7 @@ function releasePromptLock() {
|
|
|
45479
45607
|
}
|
|
45480
45608
|
async function interactivePrompt(options) {
|
|
45481
45609
|
await acquirePromptLock();
|
|
45482
|
-
return new Promise((
|
|
45610
|
+
return new Promise((resolve15, reject) => {
|
|
45483
45611
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
45484
45612
|
try {
|
|
45485
45613
|
if (dbg) {
|
|
@@ -45566,12 +45694,12 @@ async function interactivePrompt(options) {
|
|
|
45566
45694
|
};
|
|
45567
45695
|
const finish = (value) => {
|
|
45568
45696
|
cleanup();
|
|
45569
|
-
|
|
45697
|
+
resolve15(value);
|
|
45570
45698
|
};
|
|
45571
45699
|
if (options.timeout && options.timeout > 0) {
|
|
45572
45700
|
timeoutId = setTimeout(() => {
|
|
45573
45701
|
cleanup();
|
|
45574
|
-
if (defaultValue !== void 0) return
|
|
45702
|
+
if (defaultValue !== void 0) return resolve15(defaultValue);
|
|
45575
45703
|
return reject(new Error("Input timeout"));
|
|
45576
45704
|
}, options.timeout);
|
|
45577
45705
|
}
|
|
@@ -45703,7 +45831,7 @@ async function interactivePrompt(options) {
|
|
|
45703
45831
|
});
|
|
45704
45832
|
}
|
|
45705
45833
|
async function simplePrompt(prompt) {
|
|
45706
|
-
return new Promise((
|
|
45834
|
+
return new Promise((resolve15) => {
|
|
45707
45835
|
const rl = readline.createInterface({
|
|
45708
45836
|
input: process.stdin,
|
|
45709
45837
|
output: process.stdout
|
|
@@ -45719,7 +45847,7 @@ async function simplePrompt(prompt) {
|
|
|
45719
45847
|
rl.question(`${prompt}
|
|
45720
45848
|
> `, (answer) => {
|
|
45721
45849
|
rl.close();
|
|
45722
|
-
|
|
45850
|
+
resolve15(answer.trim());
|
|
45723
45851
|
});
|
|
45724
45852
|
});
|
|
45725
45853
|
}
|
|
@@ -45887,7 +46015,7 @@ function isStdinAvailable() {
|
|
|
45887
46015
|
return !process.stdin.isTTY;
|
|
45888
46016
|
}
|
|
45889
46017
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
45890
|
-
return new Promise((
|
|
46018
|
+
return new Promise((resolve15, reject) => {
|
|
45891
46019
|
let data = "";
|
|
45892
46020
|
let timeoutId;
|
|
45893
46021
|
if (timeout) {
|
|
@@ -45914,7 +46042,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
45914
46042
|
};
|
|
45915
46043
|
const onEnd = () => {
|
|
45916
46044
|
cleanup();
|
|
45917
|
-
|
|
46045
|
+
resolve15(data.trim());
|
|
45918
46046
|
};
|
|
45919
46047
|
const onError = (err) => {
|
|
45920
46048
|
cleanup();
|
|
@@ -45944,7 +46072,7 @@ var init_stdin_reader = __esm({
|
|
|
45944
46072
|
});
|
|
45945
46073
|
|
|
45946
46074
|
// src/providers/human-input-check-provider.ts
|
|
45947
|
-
var fs17,
|
|
46075
|
+
var fs17, path21, HumanInputCheckProvider;
|
|
45948
46076
|
var init_human_input_check_provider = __esm({
|
|
45949
46077
|
"src/providers/human-input-check-provider.ts"() {
|
|
45950
46078
|
"use strict";
|
|
@@ -45954,7 +46082,7 @@ var init_human_input_check_provider = __esm({
|
|
|
45954
46082
|
init_liquid_extensions();
|
|
45955
46083
|
init_stdin_reader();
|
|
45956
46084
|
fs17 = __toESM(require("fs"));
|
|
45957
|
-
|
|
46085
|
+
path21 = __toESM(require("path"));
|
|
45958
46086
|
HumanInputCheckProvider = class _HumanInputCheckProvider extends CheckProvider {
|
|
45959
46087
|
liquid;
|
|
45960
46088
|
/**
|
|
@@ -46128,10 +46256,10 @@ var init_human_input_check_provider = __esm({
|
|
|
46128
46256
|
*/
|
|
46129
46257
|
async tryReadFile(filePath) {
|
|
46130
46258
|
try {
|
|
46131
|
-
const absolutePath =
|
|
46132
|
-
const normalizedPath =
|
|
46259
|
+
const absolutePath = path21.isAbsolute(filePath) ? filePath : path21.resolve(process.cwd(), filePath);
|
|
46260
|
+
const normalizedPath = path21.normalize(absolutePath);
|
|
46133
46261
|
const cwd = process.cwd();
|
|
46134
|
-
if (!normalizedPath.startsWith(cwd +
|
|
46262
|
+
if (!normalizedPath.startsWith(cwd + path21.sep) && normalizedPath !== cwd) {
|
|
46135
46263
|
return null;
|
|
46136
46264
|
}
|
|
46137
46265
|
try {
|
|
@@ -47286,14 +47414,14 @@ var init_script_check_provider = __esm({
|
|
|
47286
47414
|
});
|
|
47287
47415
|
|
|
47288
47416
|
// src/utils/worktree-manager.ts
|
|
47289
|
-
var fs18, fsp,
|
|
47417
|
+
var fs18, fsp, path22, crypto2, WorktreeManager, worktreeManager;
|
|
47290
47418
|
var init_worktree_manager = __esm({
|
|
47291
47419
|
"src/utils/worktree-manager.ts"() {
|
|
47292
47420
|
"use strict";
|
|
47293
47421
|
fs18 = __toESM(require("fs"));
|
|
47294
47422
|
fsp = __toESM(require("fs/promises"));
|
|
47295
|
-
|
|
47296
|
-
|
|
47423
|
+
path22 = __toESM(require("path"));
|
|
47424
|
+
crypto2 = __toESM(require("crypto"));
|
|
47297
47425
|
init_command_executor();
|
|
47298
47426
|
init_logger();
|
|
47299
47427
|
WorktreeManager = class _WorktreeManager {
|
|
@@ -47308,7 +47436,7 @@ var init_worktree_manager = __esm({
|
|
|
47308
47436
|
} catch {
|
|
47309
47437
|
cwd = "/tmp";
|
|
47310
47438
|
}
|
|
47311
|
-
const defaultBasePath = process.env.VISOR_WORKTREE_PATH ||
|
|
47439
|
+
const defaultBasePath = process.env.VISOR_WORKTREE_PATH || path22.join(cwd, ".visor", "worktrees");
|
|
47312
47440
|
this.config = {
|
|
47313
47441
|
enabled: true,
|
|
47314
47442
|
base_path: defaultBasePath,
|
|
@@ -47355,10 +47483,10 @@ var init_worktree_manager = __esm({
|
|
|
47355
47483
|
}
|
|
47356
47484
|
}
|
|
47357
47485
|
getReposDir() {
|
|
47358
|
-
return
|
|
47486
|
+
return path22.join(this.config.base_path, "repos");
|
|
47359
47487
|
}
|
|
47360
47488
|
getWorktreesDir() {
|
|
47361
|
-
return
|
|
47489
|
+
return path22.join(this.config.base_path, "worktrees");
|
|
47362
47490
|
}
|
|
47363
47491
|
/**
|
|
47364
47492
|
* Generate a worktree ID based on repository, ref, and session.
|
|
@@ -47374,7 +47502,7 @@ var init_worktree_manager = __esm({
|
|
|
47374
47502
|
const sanitizedRepo = repository.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
47375
47503
|
const sanitizedRef = ref.replace(/[^a-zA-Z0-9-]/g, "-");
|
|
47376
47504
|
const hashInput = sessionId ? `${repository}:${ref}:${sessionId}` : `${repository}:${ref}`;
|
|
47377
|
-
const hash =
|
|
47505
|
+
const hash = crypto2.createHash("md5").update(hashInput).digest("hex").substring(0, 8);
|
|
47378
47506
|
return `${sanitizedRepo}-${sanitizedRef}-${hash}`;
|
|
47379
47507
|
}
|
|
47380
47508
|
/**
|
|
@@ -47383,7 +47511,7 @@ var init_worktree_manager = __esm({
|
|
|
47383
47511
|
async getOrCreateBareRepo(repository, repoUrl, _token, fetchDepth, cloneTimeoutMs) {
|
|
47384
47512
|
const reposDir = this.getReposDir();
|
|
47385
47513
|
const repoName = repository.replace(/\//g, "-");
|
|
47386
|
-
const bareRepoPath =
|
|
47514
|
+
const bareRepoPath = path22.join(reposDir, `${repoName}.git`);
|
|
47387
47515
|
if (fs18.existsSync(bareRepoPath)) {
|
|
47388
47516
|
logger.debug(`Bare repository already exists: ${bareRepoPath}`);
|
|
47389
47517
|
const verifyResult = await this.verifyBareRepoRemote(bareRepoPath, repoUrl);
|
|
@@ -47531,7 +47659,7 @@ var init_worktree_manager = __esm({
|
|
|
47531
47659
|
options.cloneTimeoutMs
|
|
47532
47660
|
);
|
|
47533
47661
|
const worktreeId = this.generateWorktreeId(repository, ref, options.sessionId);
|
|
47534
|
-
let worktreePath = options.workingDirectory ||
|
|
47662
|
+
let worktreePath = options.workingDirectory || path22.join(this.getWorktreesDir(), worktreeId);
|
|
47535
47663
|
if (options.workingDirectory) {
|
|
47536
47664
|
worktreePath = this.validatePath(options.workingDirectory);
|
|
47537
47665
|
}
|
|
@@ -47852,7 +47980,7 @@ var init_worktree_manager = __esm({
|
|
|
47852
47980
|
*/
|
|
47853
47981
|
async loadMetadata(worktreePath) {
|
|
47854
47982
|
const metadataPath = this.getMetadataPath(worktreePath);
|
|
47855
|
-
const legacyPath =
|
|
47983
|
+
const legacyPath = path22.join(worktreePath, ".visor-metadata.json");
|
|
47856
47984
|
const pathToRead = fs18.existsSync(metadataPath) ? metadataPath : fs18.existsSync(legacyPath) ? legacyPath : null;
|
|
47857
47985
|
if (!pathToRead) {
|
|
47858
47986
|
return null;
|
|
@@ -47877,7 +48005,7 @@ var init_worktree_manager = __esm({
|
|
|
47877
48005
|
const worktrees = [];
|
|
47878
48006
|
for (const entry of entries) {
|
|
47879
48007
|
if (!entry.isDirectory()) continue;
|
|
47880
|
-
const worktreePath =
|
|
48008
|
+
const worktreePath = path22.join(worktreesDir, entry.name);
|
|
47881
48009
|
const metadata = await this.loadMetadata(worktreePath);
|
|
47882
48010
|
if (metadata) {
|
|
47883
48011
|
worktrees.push({
|
|
@@ -48009,8 +48137,8 @@ var init_worktree_manager = __esm({
|
|
|
48009
48137
|
* Validate path to prevent directory traversal
|
|
48010
48138
|
*/
|
|
48011
48139
|
validatePath(userPath) {
|
|
48012
|
-
const resolvedPath =
|
|
48013
|
-
if (!
|
|
48140
|
+
const resolvedPath = path22.resolve(userPath);
|
|
48141
|
+
if (!path22.isAbsolute(resolvedPath)) {
|
|
48014
48142
|
throw new Error("Path must be absolute");
|
|
48015
48143
|
}
|
|
48016
48144
|
const sensitivePatterns = [
|
|
@@ -50605,23 +50733,23 @@ __export(renderer_schema_exports, {
|
|
|
50605
50733
|
});
|
|
50606
50734
|
async function loadRendererSchema(name) {
|
|
50607
50735
|
try {
|
|
50608
|
-
const
|
|
50609
|
-
const
|
|
50736
|
+
const fs25 = await import("fs/promises");
|
|
50737
|
+
const path29 = await import("path");
|
|
50610
50738
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
50611
50739
|
if (!sanitized) return void 0;
|
|
50612
50740
|
const candidates = [
|
|
50613
50741
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
50614
|
-
|
|
50742
|
+
path29.join(__dirname, "output", sanitized, "schema.json"),
|
|
50615
50743
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
50616
|
-
|
|
50744
|
+
path29.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
50617
50745
|
// When running from a checkout with output/ folder copied to CWD
|
|
50618
|
-
|
|
50746
|
+
path29.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
50619
50747
|
// Fallback: cwd/dist/output/
|
|
50620
|
-
|
|
50748
|
+
path29.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
50621
50749
|
];
|
|
50622
50750
|
for (const p of candidates) {
|
|
50623
50751
|
try {
|
|
50624
|
-
const raw = await
|
|
50752
|
+
const raw = await fs25.readFile(p, "utf-8");
|
|
50625
50753
|
return JSON.parse(raw);
|
|
50626
50754
|
} catch {
|
|
50627
50755
|
}
|
|
@@ -53062,8 +53190,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
53062
53190
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
53063
53191
|
try {
|
|
53064
53192
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
53065
|
-
const
|
|
53066
|
-
const
|
|
53193
|
+
const fs25 = await import("fs/promises");
|
|
53194
|
+
const path29 = await import("path");
|
|
53067
53195
|
const schemaRaw = checkConfig.schema || "plain";
|
|
53068
53196
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
53069
53197
|
let templateContent;
|
|
@@ -53072,27 +53200,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
53072
53200
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
53073
53201
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
53074
53202
|
const file = String(checkConfig.template.file);
|
|
53075
|
-
const resolved =
|
|
53076
|
-
templateContent = await
|
|
53203
|
+
const resolved = path29.resolve(process.cwd(), file);
|
|
53204
|
+
templateContent = await fs25.readFile(resolved, "utf-8");
|
|
53077
53205
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
53078
53206
|
} else if (schema && schema !== "plain") {
|
|
53079
53207
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
53080
53208
|
if (sanitized) {
|
|
53081
53209
|
const candidatePaths = [
|
|
53082
|
-
|
|
53210
|
+
path29.join(__dirname, "output", sanitized, "template.liquid"),
|
|
53083
53211
|
// bundled: dist/output/
|
|
53084
|
-
|
|
53212
|
+
path29.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
53085
53213
|
// source (from state-machine/states)
|
|
53086
|
-
|
|
53214
|
+
path29.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
53087
53215
|
// source (alternate)
|
|
53088
|
-
|
|
53216
|
+
path29.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
53089
53217
|
// fallback: cwd/output/
|
|
53090
|
-
|
|
53218
|
+
path29.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
53091
53219
|
// fallback: cwd/dist/output/
|
|
53092
53220
|
];
|
|
53093
53221
|
for (const p of candidatePaths) {
|
|
53094
53222
|
try {
|
|
53095
|
-
templateContent = await
|
|
53223
|
+
templateContent = await fs25.readFile(p, "utf-8");
|
|
53096
53224
|
if (templateContent) {
|
|
53097
53225
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
53098
53226
|
break;
|
|
@@ -53699,16 +53827,16 @@ var init_runner = __esm({
|
|
|
53699
53827
|
});
|
|
53700
53828
|
|
|
53701
53829
|
// src/sandbox/docker-image-sandbox.ts
|
|
53702
|
-
var import_util2, import_child_process3, import_fs5,
|
|
53830
|
+
var import_util2, import_child_process3, import_fs5, import_path10, import_os, import_crypto3, execFileAsync, EXEC_MAX_BUFFER, DockerImageSandbox;
|
|
53703
53831
|
var init_docker_image_sandbox = __esm({
|
|
53704
53832
|
"src/sandbox/docker-image-sandbox.ts"() {
|
|
53705
53833
|
"use strict";
|
|
53706
53834
|
import_util2 = require("util");
|
|
53707
53835
|
import_child_process3 = require("child_process");
|
|
53708
53836
|
import_fs5 = require("fs");
|
|
53709
|
-
|
|
53837
|
+
import_path10 = require("path");
|
|
53710
53838
|
import_os = require("os");
|
|
53711
|
-
|
|
53839
|
+
import_crypto3 = require("crypto");
|
|
53712
53840
|
init_logger();
|
|
53713
53841
|
init_sandbox_telemetry();
|
|
53714
53842
|
execFileAsync = (0, import_util2.promisify)(import_child_process3.execFile);
|
|
@@ -53726,7 +53854,7 @@ var init_docker_image_sandbox = __esm({
|
|
|
53726
53854
|
this.config = config;
|
|
53727
53855
|
this.repoPath = repoPath;
|
|
53728
53856
|
this.visorDistPath = visorDistPath;
|
|
53729
|
-
this.containerName = `visor-${name}-${(0,
|
|
53857
|
+
this.containerName = `visor-${name}-${(0, import_crypto3.randomUUID)().slice(0, 8)}`;
|
|
53730
53858
|
this.cacheVolumeMounts = cacheVolumeMounts;
|
|
53731
53859
|
}
|
|
53732
53860
|
/**
|
|
@@ -53751,8 +53879,8 @@ var init_docker_image_sandbox = __esm({
|
|
|
53751
53879
|
`Sandbox '${this.name}' has invalid dockerfile_inline: must contain a FROM instruction`
|
|
53752
53880
|
);
|
|
53753
53881
|
}
|
|
53754
|
-
const tmpDir = (0, import_fs5.mkdtempSync)((0,
|
|
53755
|
-
const dockerfilePath = (0,
|
|
53882
|
+
const tmpDir = (0, import_fs5.mkdtempSync)((0, import_path10.join)((0, import_os.tmpdir)(), "visor-build-"));
|
|
53883
|
+
const dockerfilePath = (0, import_path10.join)(tmpDir, "Dockerfile");
|
|
53756
53884
|
(0, import_fs5.writeFileSync)(dockerfilePath, this.config.dockerfile_inline, "utf8");
|
|
53757
53885
|
try {
|
|
53758
53886
|
logger.info(`Building sandbox image '${imageName}' from inline Dockerfile`);
|
|
@@ -53820,7 +53948,7 @@ var init_docker_image_sandbox = __esm({
|
|
|
53820
53948
|
}
|
|
53821
53949
|
if (this.config.bind_paths) {
|
|
53822
53950
|
for (const bp of this.config.bind_paths) {
|
|
53823
|
-
const hostPath = bp.host.startsWith("~") ? (0,
|
|
53951
|
+
const hostPath = bp.host.startsWith("~") ? (0, import_path10.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path10.resolve)(bp.host);
|
|
53824
53952
|
const containerPath = bp.container || hostPath;
|
|
53825
53953
|
const readOnly = bp.read_only !== false;
|
|
53826
53954
|
args.push("-v", `${hostPath}:${containerPath}${readOnly ? ":ro" : ""}`);
|
|
@@ -53891,13 +54019,13 @@ var init_docker_image_sandbox = __esm({
|
|
|
53891
54019
|
});
|
|
53892
54020
|
|
|
53893
54021
|
// src/sandbox/docker-compose-sandbox.ts
|
|
53894
|
-
var import_util3, import_child_process4,
|
|
54022
|
+
var import_util3, import_child_process4, import_crypto4, execFileAsync2, EXEC_MAX_BUFFER2, DockerComposeSandbox;
|
|
53895
54023
|
var init_docker_compose_sandbox = __esm({
|
|
53896
54024
|
"src/sandbox/docker-compose-sandbox.ts"() {
|
|
53897
54025
|
"use strict";
|
|
53898
54026
|
import_util3 = require("util");
|
|
53899
54027
|
import_child_process4 = require("child_process");
|
|
53900
|
-
|
|
54028
|
+
import_crypto4 = require("crypto");
|
|
53901
54029
|
init_logger();
|
|
53902
54030
|
execFileAsync2 = (0, import_util3.promisify)(import_child_process4.execFile);
|
|
53903
54031
|
EXEC_MAX_BUFFER2 = 50 * 1024 * 1024;
|
|
@@ -53909,7 +54037,7 @@ var init_docker_compose_sandbox = __esm({
|
|
|
53909
54037
|
constructor(name, config) {
|
|
53910
54038
|
this.name = name;
|
|
53911
54039
|
this.config = config;
|
|
53912
|
-
this.projectName = `visor-${name}-${(0,
|
|
54040
|
+
this.projectName = `visor-${name}-${(0, import_crypto4.randomUUID)().slice(0, 8)}`;
|
|
53913
54041
|
}
|
|
53914
54042
|
/**
|
|
53915
54043
|
* Start the compose services
|
|
@@ -54001,7 +54129,7 @@ var init_docker_compose_sandbox = __esm({
|
|
|
54001
54129
|
|
|
54002
54130
|
// src/sandbox/cache-volume-manager.ts
|
|
54003
54131
|
function pathHash(containerPath) {
|
|
54004
|
-
return (0,
|
|
54132
|
+
return (0, import_crypto5.createHash)("sha256").update(containerPath).digest("hex").slice(0, 8);
|
|
54005
54133
|
}
|
|
54006
54134
|
function parseTtl(ttl) {
|
|
54007
54135
|
let ms = 0;
|
|
@@ -54013,13 +54141,13 @@ function parseTtl(ttl) {
|
|
|
54013
54141
|
if (minMatch) ms += parseInt(minMatch[1], 10) * 6e4;
|
|
54014
54142
|
return ms || 6048e5;
|
|
54015
54143
|
}
|
|
54016
|
-
var import_util4, import_child_process5,
|
|
54144
|
+
var import_util4, import_child_process5, import_crypto5, execFileAsync3, EXEC_MAX_BUFFER3, CacheVolumeManager;
|
|
54017
54145
|
var init_cache_volume_manager = __esm({
|
|
54018
54146
|
"src/sandbox/cache-volume-manager.ts"() {
|
|
54019
54147
|
"use strict";
|
|
54020
54148
|
import_util4 = require("util");
|
|
54021
54149
|
import_child_process5 = require("child_process");
|
|
54022
|
-
|
|
54150
|
+
import_crypto5 = require("crypto");
|
|
54023
54151
|
init_logger();
|
|
54024
54152
|
execFileAsync3 = (0, import_util4.promisify)(import_child_process5.execFile);
|
|
54025
54153
|
EXEC_MAX_BUFFER3 = 10 * 1024 * 1024;
|
|
@@ -54201,14 +54329,14 @@ var bubblewrap_sandbox_exports = {};
|
|
|
54201
54329
|
__export(bubblewrap_sandbox_exports, {
|
|
54202
54330
|
BubblewrapSandbox: () => BubblewrapSandbox
|
|
54203
54331
|
});
|
|
54204
|
-
var import_util5, import_child_process6, import_fs6,
|
|
54332
|
+
var import_util5, import_child_process6, import_fs6, import_path11, execFileAsync4, EXEC_MAX_BUFFER4, BubblewrapSandbox;
|
|
54205
54333
|
var init_bubblewrap_sandbox = __esm({
|
|
54206
54334
|
"src/sandbox/bubblewrap-sandbox.ts"() {
|
|
54207
54335
|
"use strict";
|
|
54208
54336
|
import_util5 = require("util");
|
|
54209
54337
|
import_child_process6 = require("child_process");
|
|
54210
54338
|
import_fs6 = require("fs");
|
|
54211
|
-
|
|
54339
|
+
import_path11 = require("path");
|
|
54212
54340
|
init_logger();
|
|
54213
54341
|
init_sandbox_telemetry();
|
|
54214
54342
|
execFileAsync4 = (0, import_util5.promisify)(import_child_process6.execFile);
|
|
@@ -54221,8 +54349,8 @@ var init_bubblewrap_sandbox = __esm({
|
|
|
54221
54349
|
constructor(name, config, repoPath, visorDistPath) {
|
|
54222
54350
|
this.name = name;
|
|
54223
54351
|
this.config = config;
|
|
54224
|
-
this.repoPath = (0,
|
|
54225
|
-
this.visorDistPath = (0,
|
|
54352
|
+
this.repoPath = (0, import_path11.resolve)(repoPath);
|
|
54353
|
+
this.visorDistPath = (0, import_path11.resolve)(visorDistPath);
|
|
54226
54354
|
}
|
|
54227
54355
|
/**
|
|
54228
54356
|
* Check if bwrap binary is available on the system.
|
|
@@ -54307,7 +54435,7 @@ var init_bubblewrap_sandbox = __esm({
|
|
|
54307
54435
|
args.push("--ro-bind", this.visorDistPath, visorPath);
|
|
54308
54436
|
if (this.config.bind_paths) {
|
|
54309
54437
|
for (const bp of this.config.bind_paths) {
|
|
54310
|
-
const hostPath = bp.host.startsWith("~") ? (0,
|
|
54438
|
+
const hostPath = bp.host.startsWith("~") ? (0, import_path11.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path11.resolve)(bp.host);
|
|
54311
54439
|
const containerPath = bp.container || hostPath;
|
|
54312
54440
|
const readOnly = bp.read_only !== false;
|
|
54313
54441
|
args.push(readOnly ? "--ro-bind" : "--bind", hostPath, containerPath);
|
|
@@ -54338,13 +54466,13 @@ var seatbelt_sandbox_exports = {};
|
|
|
54338
54466
|
__export(seatbelt_sandbox_exports, {
|
|
54339
54467
|
SeatbeltSandbox: () => SeatbeltSandbox
|
|
54340
54468
|
});
|
|
54341
|
-
var import_util6, import_child_process7,
|
|
54469
|
+
var import_util6, import_child_process7, import_path12, import_fs7, execFileAsync5, EXEC_MAX_BUFFER5, SeatbeltSandbox;
|
|
54342
54470
|
var init_seatbelt_sandbox = __esm({
|
|
54343
54471
|
"src/sandbox/seatbelt-sandbox.ts"() {
|
|
54344
54472
|
"use strict";
|
|
54345
54473
|
import_util6 = require("util");
|
|
54346
54474
|
import_child_process7 = require("child_process");
|
|
54347
|
-
|
|
54475
|
+
import_path12 = require("path");
|
|
54348
54476
|
import_fs7 = require("fs");
|
|
54349
54477
|
init_logger();
|
|
54350
54478
|
init_sandbox_telemetry();
|
|
@@ -54358,8 +54486,8 @@ var init_seatbelt_sandbox = __esm({
|
|
|
54358
54486
|
constructor(name, config, repoPath, visorDistPath) {
|
|
54359
54487
|
this.name = name;
|
|
54360
54488
|
this.config = config;
|
|
54361
|
-
this.repoPath = (0, import_fs7.realpathSync)((0,
|
|
54362
|
-
this.visorDistPath = (0, import_fs7.realpathSync)((0,
|
|
54489
|
+
this.repoPath = (0, import_fs7.realpathSync)((0, import_path12.resolve)(repoPath));
|
|
54490
|
+
this.visorDistPath = (0, import_fs7.realpathSync)((0, import_path12.resolve)(visorDistPath));
|
|
54363
54491
|
}
|
|
54364
54492
|
/**
|
|
54365
54493
|
* Check if sandbox-exec binary is available on the system.
|
|
@@ -54464,7 +54592,7 @@ var init_seatbelt_sandbox = __esm({
|
|
|
54464
54592
|
lines.push(`(allow file-read* (subpath "${visorDistPath}"))`);
|
|
54465
54593
|
if (this.config.bind_paths) {
|
|
54466
54594
|
for (const bp of this.config.bind_paths) {
|
|
54467
|
-
const hostPath = bp.host.startsWith("~") ? (0,
|
|
54595
|
+
const hostPath = bp.host.startsWith("~") ? (0, import_path12.resolve)((process.env.HOME || "/root") + bp.host.slice(1)) : (0, import_path12.resolve)(bp.host);
|
|
54468
54596
|
const escapedPath = this.escapePath(hostPath);
|
|
54469
54597
|
lines.push(`(allow file-read* (subpath "${escapedPath}"))`);
|
|
54470
54598
|
if (bp.read_only === false) {
|
|
@@ -54485,11 +54613,11 @@ var init_seatbelt_sandbox = __esm({
|
|
|
54485
54613
|
});
|
|
54486
54614
|
|
|
54487
54615
|
// src/sandbox/sandbox-manager.ts
|
|
54488
|
-
var
|
|
54616
|
+
var import_path13, import_fs8, SandboxManager;
|
|
54489
54617
|
var init_sandbox_manager = __esm({
|
|
54490
54618
|
"src/sandbox/sandbox-manager.ts"() {
|
|
54491
54619
|
"use strict";
|
|
54492
|
-
|
|
54620
|
+
import_path13 = require("path");
|
|
54493
54621
|
import_fs8 = require("fs");
|
|
54494
54622
|
init_docker_image_sandbox();
|
|
54495
54623
|
init_docker_compose_sandbox();
|
|
@@ -54509,10 +54637,10 @@ var init_sandbox_manager = __esm({
|
|
|
54509
54637
|
}
|
|
54510
54638
|
constructor(sandboxDefs, repoPath, gitBranch) {
|
|
54511
54639
|
this.sandboxDefs = sandboxDefs;
|
|
54512
|
-
this.repoPath = (0,
|
|
54640
|
+
this.repoPath = (0, import_path13.resolve)(repoPath);
|
|
54513
54641
|
this.gitBranch = gitBranch;
|
|
54514
54642
|
this.cacheManager = new CacheVolumeManager();
|
|
54515
|
-
this.visorDistPath = (0, import_fs8.existsSync)((0,
|
|
54643
|
+
this.visorDistPath = (0, import_fs8.existsSync)((0, import_path13.join)(__dirname, "index.js")) ? __dirname : (0, import_path13.resolve)((0, import_path13.dirname)(__dirname));
|
|
54516
54644
|
}
|
|
54517
54645
|
/**
|
|
54518
54646
|
* Resolve which sandbox a check should use.
|
|
@@ -54641,13 +54769,13 @@ var init_sandbox_manager = __esm({
|
|
|
54641
54769
|
});
|
|
54642
54770
|
|
|
54643
54771
|
// src/utils/file-exclusion.ts
|
|
54644
|
-
var import_ignore, fs19,
|
|
54772
|
+
var import_ignore, fs19, path23, DEFAULT_EXCLUSION_PATTERNS, FileExclusionHelper;
|
|
54645
54773
|
var init_file_exclusion = __esm({
|
|
54646
54774
|
"src/utils/file-exclusion.ts"() {
|
|
54647
54775
|
"use strict";
|
|
54648
54776
|
import_ignore = __toESM(require("ignore"));
|
|
54649
54777
|
fs19 = __toESM(require("fs"));
|
|
54650
|
-
|
|
54778
|
+
path23 = __toESM(require("path"));
|
|
54651
54779
|
DEFAULT_EXCLUSION_PATTERNS = [
|
|
54652
54780
|
"dist/",
|
|
54653
54781
|
"build/",
|
|
@@ -54666,7 +54794,7 @@ var init_file_exclusion = __esm({
|
|
|
54666
54794
|
* @param additionalPatterns - Additional patterns to include (optional, defaults to common build artifacts)
|
|
54667
54795
|
*/
|
|
54668
54796
|
constructor(workingDirectory = process.cwd(), additionalPatterns = DEFAULT_EXCLUSION_PATTERNS) {
|
|
54669
|
-
const normalizedPath =
|
|
54797
|
+
const normalizedPath = path23.resolve(workingDirectory);
|
|
54670
54798
|
if (normalizedPath.includes("\0")) {
|
|
54671
54799
|
throw new Error("Invalid workingDirectory: contains null bytes");
|
|
54672
54800
|
}
|
|
@@ -54678,11 +54806,11 @@ var init_file_exclusion = __esm({
|
|
|
54678
54806
|
* @param additionalPatterns - Additional patterns to add to gitignore rules
|
|
54679
54807
|
*/
|
|
54680
54808
|
loadGitignore(additionalPatterns) {
|
|
54681
|
-
const gitignorePath =
|
|
54682
|
-
const resolvedWorkingDir =
|
|
54809
|
+
const gitignorePath = path23.resolve(this.workingDirectory, ".gitignore");
|
|
54810
|
+
const resolvedWorkingDir = path23.resolve(this.workingDirectory);
|
|
54683
54811
|
try {
|
|
54684
|
-
const relativePath =
|
|
54685
|
-
if (relativePath.startsWith("..") ||
|
|
54812
|
+
const relativePath = path23.relative(resolvedWorkingDir, gitignorePath);
|
|
54813
|
+
if (relativePath.startsWith("..") || path23.isAbsolute(relativePath)) {
|
|
54686
54814
|
throw new Error("Invalid gitignore path: path traversal detected");
|
|
54687
54815
|
}
|
|
54688
54816
|
if (relativePath !== ".gitignore") {
|
|
@@ -54725,12 +54853,12 @@ var git_repository_analyzer_exports = {};
|
|
|
54725
54853
|
__export(git_repository_analyzer_exports, {
|
|
54726
54854
|
GitRepositoryAnalyzer: () => GitRepositoryAnalyzer
|
|
54727
54855
|
});
|
|
54728
|
-
var import_simple_git2,
|
|
54856
|
+
var import_simple_git2, path24, fs20, MAX_PATCH_SIZE, GitRepositoryAnalyzer;
|
|
54729
54857
|
var init_git_repository_analyzer = __esm({
|
|
54730
54858
|
"src/git-repository-analyzer.ts"() {
|
|
54731
54859
|
"use strict";
|
|
54732
54860
|
import_simple_git2 = require("simple-git");
|
|
54733
|
-
|
|
54861
|
+
path24 = __toESM(require("path"));
|
|
54734
54862
|
fs20 = __toESM(require("fs"));
|
|
54735
54863
|
init_file_exclusion();
|
|
54736
54864
|
MAX_PATCH_SIZE = 50 * 1024;
|
|
@@ -54920,7 +55048,7 @@ ${file.patch}`).join("\n\n");
|
|
|
54920
55048
|
console.error(`\u23ED\uFE0F Skipping excluded file: ${file}`);
|
|
54921
55049
|
continue;
|
|
54922
55050
|
}
|
|
54923
|
-
const filePath =
|
|
55051
|
+
const filePath = path24.join(this.cwd, file);
|
|
54924
55052
|
const fileChange = await this.analyzeFileChange(file, status2, filePath, includeContext);
|
|
54925
55053
|
changes.push(fileChange);
|
|
54926
55054
|
}
|
|
@@ -55146,12 +55274,12 @@ function shellEscape(str) {
|
|
|
55146
55274
|
function sanitizePathComponent(name) {
|
|
55147
55275
|
return name.replace(/\.\./g, "").replace(/[\/\\]/g, "-").replace(/^\.+/, "").trim() || "unnamed";
|
|
55148
55276
|
}
|
|
55149
|
-
var fsp2,
|
|
55277
|
+
var fsp2, path25, WorkspaceManager;
|
|
55150
55278
|
var init_workspace_manager = __esm({
|
|
55151
55279
|
"src/utils/workspace-manager.ts"() {
|
|
55152
55280
|
"use strict";
|
|
55153
55281
|
fsp2 = __toESM(require("fs/promises"));
|
|
55154
|
-
|
|
55282
|
+
path25 = __toESM(require("path"));
|
|
55155
55283
|
init_command_executor();
|
|
55156
55284
|
init_logger();
|
|
55157
55285
|
WorkspaceManager = class _WorkspaceManager {
|
|
@@ -55185,7 +55313,7 @@ var init_workspace_manager = __esm({
|
|
|
55185
55313
|
};
|
|
55186
55314
|
this.basePath = this.config.basePath;
|
|
55187
55315
|
const workspaceDirName = sanitizePathComponent(this.config.name || this.sessionId);
|
|
55188
|
-
this.workspacePath =
|
|
55316
|
+
this.workspacePath = path25.join(this.basePath, workspaceDirName);
|
|
55189
55317
|
}
|
|
55190
55318
|
/**
|
|
55191
55319
|
* Get or create a WorkspaceManager instance for a session
|
|
@@ -55232,8 +55360,8 @@ var init_workspace_manager = __esm({
|
|
|
55232
55360
|
);
|
|
55233
55361
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
55234
55362
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
55235
|
-
for (const
|
|
55236
|
-
|
|
55363
|
+
for (const resolve15 of this.cleanupResolvers) {
|
|
55364
|
+
resolve15();
|
|
55237
55365
|
}
|
|
55238
55366
|
this.cleanupResolvers = [];
|
|
55239
55367
|
}
|
|
@@ -55280,7 +55408,7 @@ var init_workspace_manager = __esm({
|
|
|
55280
55408
|
configuredMainProjectName || this.extractProjectName(this.originalPath)
|
|
55281
55409
|
);
|
|
55282
55410
|
this.usedNames.add(mainProjectName);
|
|
55283
|
-
const mainProjectPath =
|
|
55411
|
+
const mainProjectPath = path25.join(this.workspacePath, mainProjectName);
|
|
55284
55412
|
const isGitRepo = await this.isGitRepository(this.originalPath);
|
|
55285
55413
|
if (isGitRepo) {
|
|
55286
55414
|
const exists = await this.pathExists(mainProjectPath);
|
|
@@ -55366,7 +55494,7 @@ var init_workspace_manager = __esm({
|
|
|
55366
55494
|
let projectName = sanitizePathComponent(description || this.extractRepoName(repository));
|
|
55367
55495
|
projectName = this.getUniqueName(projectName);
|
|
55368
55496
|
this.usedNames.add(projectName);
|
|
55369
|
-
const workspacePath =
|
|
55497
|
+
const workspacePath = path25.join(this.workspacePath, projectName);
|
|
55370
55498
|
await fsp2.rm(workspacePath, { recursive: true, force: true });
|
|
55371
55499
|
try {
|
|
55372
55500
|
await fsp2.symlink(worktreePath, workspacePath);
|
|
@@ -55412,19 +55540,19 @@ var init_workspace_manager = __esm({
|
|
|
55412
55540
|
);
|
|
55413
55541
|
this.cleanupRequested = true;
|
|
55414
55542
|
await Promise.race([
|
|
55415
|
-
new Promise((
|
|
55543
|
+
new Promise((resolve15) => {
|
|
55416
55544
|
if (this.activeOperations === 0) {
|
|
55417
|
-
|
|
55545
|
+
resolve15();
|
|
55418
55546
|
} else {
|
|
55419
|
-
this.cleanupResolvers.push(
|
|
55547
|
+
this.cleanupResolvers.push(resolve15);
|
|
55420
55548
|
}
|
|
55421
55549
|
}),
|
|
55422
|
-
new Promise((
|
|
55550
|
+
new Promise((resolve15) => {
|
|
55423
55551
|
setTimeout(() => {
|
|
55424
55552
|
logger.warn(
|
|
55425
55553
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
55426
55554
|
);
|
|
55427
|
-
|
|
55555
|
+
resolve15();
|
|
55428
55556
|
}, timeout);
|
|
55429
55557
|
})
|
|
55430
55558
|
]);
|
|
@@ -55476,7 +55604,7 @@ var init_workspace_manager = __esm({
|
|
|
55476
55604
|
const now = Date.now();
|
|
55477
55605
|
for (const entry of entries) {
|
|
55478
55606
|
if (!entry.isDirectory()) continue;
|
|
55479
|
-
const dirPath =
|
|
55607
|
+
const dirPath = path25.join(basePath, entry.name);
|
|
55480
55608
|
try {
|
|
55481
55609
|
const stat2 = await fsp2.stat(dirPath);
|
|
55482
55610
|
if (now - stat2.mtimeMs > maxAgeMs) {
|
|
@@ -55484,8 +55612,8 @@ var init_workspace_manager = __esm({
|
|
|
55484
55612
|
const subdirs = await fsp2.readdir(dirPath, { withFileTypes: true });
|
|
55485
55613
|
for (const sub of subdirs) {
|
|
55486
55614
|
if (!sub.isDirectory()) continue;
|
|
55487
|
-
const subPath =
|
|
55488
|
-
const gitFilePath =
|
|
55615
|
+
const subPath = path25.join(dirPath, sub.name);
|
|
55616
|
+
const gitFilePath = path25.join(subPath, ".git");
|
|
55489
55617
|
try {
|
|
55490
55618
|
const gitContent = await fsp2.readFile(gitFilePath, "utf-8");
|
|
55491
55619
|
const match = gitContent.match(/gitdir:\s*(.+)/);
|
|
@@ -55710,7 +55838,7 @@ var init_workspace_manager = __esm({
|
|
|
55710
55838
|
* Extract project name from path
|
|
55711
55839
|
*/
|
|
55712
55840
|
extractProjectName(dirPath) {
|
|
55713
|
-
return
|
|
55841
|
+
return path25.basename(dirPath);
|
|
55714
55842
|
}
|
|
55715
55843
|
/**
|
|
55716
55844
|
* Extract repository name from owner/repo format
|
|
@@ -55818,8 +55946,8 @@ var init_fair_concurrency_limiter = __esm({
|
|
|
55818
55946
|
);
|
|
55819
55947
|
const queuedAt = Date.now();
|
|
55820
55948
|
const effectiveTimeout = queueTimeout ?? 12e4;
|
|
55821
|
-
return new Promise((
|
|
55822
|
-
const entry = { resolve:
|
|
55949
|
+
return new Promise((resolve15, reject) => {
|
|
55950
|
+
const entry = { resolve: resolve15, reject, queuedAt };
|
|
55823
55951
|
entry.reminder = setInterval(() => {
|
|
55824
55952
|
const waited = Math.round((Date.now() - queuedAt) / 1e3);
|
|
55825
55953
|
const curQueued = this._totalQueued();
|
|
@@ -56126,1380 +56254,6 @@ var init_build_engine_context = __esm({
|
|
|
56126
56254
|
}
|
|
56127
56255
|
});
|
|
56128
56256
|
|
|
56129
|
-
// src/policy/default-engine.ts
|
|
56130
|
-
var DefaultPolicyEngine;
|
|
56131
|
-
var init_default_engine = __esm({
|
|
56132
|
-
"src/policy/default-engine.ts"() {
|
|
56133
|
-
"use strict";
|
|
56134
|
-
DefaultPolicyEngine = class {
|
|
56135
|
-
async initialize(_config) {
|
|
56136
|
-
}
|
|
56137
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
56138
|
-
return { allowed: true };
|
|
56139
|
-
}
|
|
56140
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
56141
|
-
return { allowed: true };
|
|
56142
|
-
}
|
|
56143
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
56144
|
-
return { allowed: true };
|
|
56145
|
-
}
|
|
56146
|
-
async shutdown() {
|
|
56147
|
-
}
|
|
56148
|
-
};
|
|
56149
|
-
}
|
|
56150
|
-
});
|
|
56151
|
-
|
|
56152
|
-
// src/enterprise/license/validator.ts
|
|
56153
|
-
var validator_exports = {};
|
|
56154
|
-
__export(validator_exports, {
|
|
56155
|
-
LicenseValidator: () => LicenseValidator
|
|
56156
|
-
});
|
|
56157
|
-
var crypto2, fs21, path25, LicenseValidator;
|
|
56158
|
-
var init_validator = __esm({
|
|
56159
|
-
"src/enterprise/license/validator.ts"() {
|
|
56160
|
-
"use strict";
|
|
56161
|
-
crypto2 = __toESM(require("crypto"));
|
|
56162
|
-
fs21 = __toESM(require("fs"));
|
|
56163
|
-
path25 = __toESM(require("path"));
|
|
56164
|
-
LicenseValidator = class _LicenseValidator {
|
|
56165
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
56166
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
56167
|
-
cache = null;
|
|
56168
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
56169
|
-
// 5 minutes
|
|
56170
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
56171
|
-
// 72 hours after expiry
|
|
56172
|
-
/**
|
|
56173
|
-
* Load and validate license from environment or file.
|
|
56174
|
-
*
|
|
56175
|
-
* Resolution order:
|
|
56176
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
56177
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
56178
|
-
* 3. .visor-license in project root (cwd)
|
|
56179
|
-
* 4. .visor-license in ~/.config/visor/
|
|
56180
|
-
*/
|
|
56181
|
-
async loadAndValidate() {
|
|
56182
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
56183
|
-
return this.cache.payload;
|
|
56184
|
-
}
|
|
56185
|
-
const token = this.resolveToken();
|
|
56186
|
-
if (!token) return null;
|
|
56187
|
-
const payload = this.verifyAndDecode(token);
|
|
56188
|
-
if (!payload) return null;
|
|
56189
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
56190
|
-
return payload;
|
|
56191
|
-
}
|
|
56192
|
-
/** Check if a specific feature is licensed */
|
|
56193
|
-
hasFeature(feature) {
|
|
56194
|
-
if (!this.cache) return false;
|
|
56195
|
-
return this.cache.payload.features.includes(feature);
|
|
56196
|
-
}
|
|
56197
|
-
/** Check if license is valid (with grace period) */
|
|
56198
|
-
isValid() {
|
|
56199
|
-
if (!this.cache) return false;
|
|
56200
|
-
const now = Date.now();
|
|
56201
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
56202
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
56203
|
-
}
|
|
56204
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
56205
|
-
isInGracePeriod() {
|
|
56206
|
-
if (!this.cache) return false;
|
|
56207
|
-
const now = Date.now();
|
|
56208
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
56209
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
56210
|
-
}
|
|
56211
|
-
resolveToken() {
|
|
56212
|
-
if (process.env.VISOR_LICENSE) {
|
|
56213
|
-
return process.env.VISOR_LICENSE.trim();
|
|
56214
|
-
}
|
|
56215
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
56216
|
-
const resolved = path25.resolve(process.env.VISOR_LICENSE_FILE);
|
|
56217
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
56218
|
-
const allowedPrefixes = [path25.normalize(process.cwd())];
|
|
56219
|
-
if (home2) allowedPrefixes.push(path25.normalize(path25.join(home2, ".config", "visor")));
|
|
56220
|
-
let realPath;
|
|
56221
|
-
try {
|
|
56222
|
-
realPath = fs21.realpathSync(resolved);
|
|
56223
|
-
} catch {
|
|
56224
|
-
return null;
|
|
56225
|
-
}
|
|
56226
|
-
const isSafe = allowedPrefixes.some(
|
|
56227
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path25.sep)
|
|
56228
|
-
);
|
|
56229
|
-
if (!isSafe) return null;
|
|
56230
|
-
return this.readFile(realPath);
|
|
56231
|
-
}
|
|
56232
|
-
const cwdPath = path25.join(process.cwd(), ".visor-license");
|
|
56233
|
-
const cwdToken = this.readFile(cwdPath);
|
|
56234
|
-
if (cwdToken) return cwdToken;
|
|
56235
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
56236
|
-
if (home) {
|
|
56237
|
-
const configPath = path25.join(home, ".config", "visor", ".visor-license");
|
|
56238
|
-
const configToken = this.readFile(configPath);
|
|
56239
|
-
if (configToken) return configToken;
|
|
56240
|
-
}
|
|
56241
|
-
return null;
|
|
56242
|
-
}
|
|
56243
|
-
readFile(filePath) {
|
|
56244
|
-
try {
|
|
56245
|
-
return fs21.readFileSync(filePath, "utf-8").trim();
|
|
56246
|
-
} catch {
|
|
56247
|
-
return null;
|
|
56248
|
-
}
|
|
56249
|
-
}
|
|
56250
|
-
verifyAndDecode(token) {
|
|
56251
|
-
try {
|
|
56252
|
-
const parts = token.split(".");
|
|
56253
|
-
if (parts.length !== 3) return null;
|
|
56254
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
56255
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
56256
|
-
if (header.alg !== "EdDSA") return null;
|
|
56257
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
56258
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
56259
|
-
const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
56260
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
56261
|
-
return null;
|
|
56262
|
-
}
|
|
56263
|
-
const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
|
|
56264
|
-
if (!isValid) return null;
|
|
56265
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
56266
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
56267
|
-
return null;
|
|
56268
|
-
}
|
|
56269
|
-
const now = Date.now();
|
|
56270
|
-
const expiryMs = payload.exp * 1e3;
|
|
56271
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
56272
|
-
return null;
|
|
56273
|
-
}
|
|
56274
|
-
return payload;
|
|
56275
|
-
} catch {
|
|
56276
|
-
return null;
|
|
56277
|
-
}
|
|
56278
|
-
}
|
|
56279
|
-
};
|
|
56280
|
-
}
|
|
56281
|
-
});
|
|
56282
|
-
|
|
56283
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
56284
|
-
var fs22, path26, os2, crypto3, import_child_process8, OpaCompiler;
|
|
56285
|
-
var init_opa_compiler = __esm({
|
|
56286
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
56287
|
-
"use strict";
|
|
56288
|
-
fs22 = __toESM(require("fs"));
|
|
56289
|
-
path26 = __toESM(require("path"));
|
|
56290
|
-
os2 = __toESM(require("os"));
|
|
56291
|
-
crypto3 = __toESM(require("crypto"));
|
|
56292
|
-
import_child_process8 = require("child_process");
|
|
56293
|
-
OpaCompiler = class _OpaCompiler {
|
|
56294
|
-
static CACHE_DIR = path26.join(os2.tmpdir(), "visor-opa-cache");
|
|
56295
|
-
/**
|
|
56296
|
-
* Resolve the input paths to WASM bytes.
|
|
56297
|
-
*
|
|
56298
|
-
* Strategy:
|
|
56299
|
-
* 1. If any path is a .wasm file, read it directly
|
|
56300
|
-
* 2. If a directory contains policy.wasm, read it
|
|
56301
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
56302
|
-
*/
|
|
56303
|
-
async resolveWasmBytes(paths) {
|
|
56304
|
-
const regoFiles = [];
|
|
56305
|
-
for (const p of paths) {
|
|
56306
|
-
const resolved = path26.resolve(p);
|
|
56307
|
-
if (path26.normalize(resolved).includes("..")) {
|
|
56308
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
56309
|
-
}
|
|
56310
|
-
if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
|
|
56311
|
-
return fs22.readFileSync(resolved);
|
|
56312
|
-
}
|
|
56313
|
-
if (!fs22.existsSync(resolved)) continue;
|
|
56314
|
-
const stat2 = fs22.statSync(resolved);
|
|
56315
|
-
if (stat2.isDirectory()) {
|
|
56316
|
-
const wasmCandidate = path26.join(resolved, "policy.wasm");
|
|
56317
|
-
if (fs22.existsSync(wasmCandidate)) {
|
|
56318
|
-
return fs22.readFileSync(wasmCandidate);
|
|
56319
|
-
}
|
|
56320
|
-
const files = fs22.readdirSync(resolved);
|
|
56321
|
-
for (const f of files) {
|
|
56322
|
-
if (f.endsWith(".rego")) {
|
|
56323
|
-
regoFiles.push(path26.join(resolved, f));
|
|
56324
|
-
}
|
|
56325
|
-
}
|
|
56326
|
-
} else if (resolved.endsWith(".rego")) {
|
|
56327
|
-
regoFiles.push(resolved);
|
|
56328
|
-
}
|
|
56329
|
-
}
|
|
56330
|
-
if (regoFiles.length === 0) {
|
|
56331
|
-
throw new Error(
|
|
56332
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
56333
|
-
);
|
|
56334
|
-
}
|
|
56335
|
-
return this.compileRego(regoFiles);
|
|
56336
|
-
}
|
|
56337
|
-
/**
|
|
56338
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
56339
|
-
*
|
|
56340
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
56341
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
56342
|
-
*/
|
|
56343
|
-
compileRego(regoFiles) {
|
|
56344
|
-
try {
|
|
56345
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
56346
|
-
} catch {
|
|
56347
|
-
throw new Error(
|
|
56348
|
-
"OPA CLI (`opa`) not found on PATH. Install it from https://www.openpolicyagent.org/docs/latest/#running-opa\nOr pre-compile your .rego files: opa build -t wasm -e visor -o bundle.tar.gz " + regoFiles.join(" ")
|
|
56349
|
-
);
|
|
56350
|
-
}
|
|
56351
|
-
const hash = crypto3.createHash("sha256");
|
|
56352
|
-
for (const f of regoFiles.sort()) {
|
|
56353
|
-
hash.update(fs22.readFileSync(f));
|
|
56354
|
-
hash.update(f);
|
|
56355
|
-
}
|
|
56356
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
56357
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
56358
|
-
const cachedWasm = path26.join(cacheDir, `${cacheKey}.wasm`);
|
|
56359
|
-
if (fs22.existsSync(cachedWasm)) {
|
|
56360
|
-
return fs22.readFileSync(cachedWasm);
|
|
56361
|
-
}
|
|
56362
|
-
fs22.mkdirSync(cacheDir, { recursive: true });
|
|
56363
|
-
const bundleTar = path26.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
56364
|
-
try {
|
|
56365
|
-
const args = [
|
|
56366
|
-
"build",
|
|
56367
|
-
"-t",
|
|
56368
|
-
"wasm",
|
|
56369
|
-
"-e",
|
|
56370
|
-
"visor",
|
|
56371
|
-
// entrypoint: the visor package tree
|
|
56372
|
-
"-o",
|
|
56373
|
-
bundleTar,
|
|
56374
|
-
...regoFiles
|
|
56375
|
-
];
|
|
56376
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
56377
|
-
stdio: "pipe",
|
|
56378
|
-
timeout: 3e4
|
|
56379
|
-
});
|
|
56380
|
-
} catch (err) {
|
|
56381
|
-
const stderr = err?.stderr?.toString() || "";
|
|
56382
|
-
throw new Error(
|
|
56383
|
-
`Failed to compile .rego files to WASM:
|
|
56384
|
-
${stderr}
|
|
56385
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
56386
|
-
);
|
|
56387
|
-
}
|
|
56388
|
-
try {
|
|
56389
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
56390
|
-
stdio: "pipe"
|
|
56391
|
-
});
|
|
56392
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
56393
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
56394
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
56395
|
-
}
|
|
56396
|
-
} catch {
|
|
56397
|
-
try {
|
|
56398
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
56399
|
-
stdio: "pipe"
|
|
56400
|
-
});
|
|
56401
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
56402
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
56403
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
56404
|
-
}
|
|
56405
|
-
} catch (err2) {
|
|
56406
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
56407
|
-
}
|
|
56408
|
-
}
|
|
56409
|
-
try {
|
|
56410
|
-
fs22.unlinkSync(bundleTar);
|
|
56411
|
-
} catch {
|
|
56412
|
-
}
|
|
56413
|
-
if (!fs22.existsSync(cachedWasm)) {
|
|
56414
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
56415
|
-
}
|
|
56416
|
-
return fs22.readFileSync(cachedWasm);
|
|
56417
|
-
}
|
|
56418
|
-
};
|
|
56419
|
-
}
|
|
56420
|
-
});
|
|
56421
|
-
|
|
56422
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
56423
|
-
var fs23, path27, OpaWasmEvaluator;
|
|
56424
|
-
var init_opa_wasm_evaluator = __esm({
|
|
56425
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
56426
|
-
"use strict";
|
|
56427
|
-
fs23 = __toESM(require("fs"));
|
|
56428
|
-
path27 = __toESM(require("path"));
|
|
56429
|
-
init_opa_compiler();
|
|
56430
|
-
OpaWasmEvaluator = class {
|
|
56431
|
-
policy = null;
|
|
56432
|
-
dataDocument = {};
|
|
56433
|
-
compiler = new OpaCompiler();
|
|
56434
|
-
async initialize(rulesPath) {
|
|
56435
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
56436
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
56437
|
-
try {
|
|
56438
|
-
const { createRequire } = require("module");
|
|
56439
|
-
const runtimeRequire = createRequire(__filename);
|
|
56440
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
56441
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
56442
|
-
if (!loadPolicy) {
|
|
56443
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
56444
|
-
}
|
|
56445
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
56446
|
-
} catch (err) {
|
|
56447
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
56448
|
-
throw new Error(
|
|
56449
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
56450
|
-
);
|
|
56451
|
-
}
|
|
56452
|
-
throw err;
|
|
56453
|
-
}
|
|
56454
|
-
}
|
|
56455
|
-
/**
|
|
56456
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
56457
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
56458
|
-
* making it available in Rego via `data.<key>`.
|
|
56459
|
-
*/
|
|
56460
|
-
loadData(dataPath) {
|
|
56461
|
-
const resolved = path27.resolve(dataPath);
|
|
56462
|
-
if (path27.normalize(resolved).includes("..")) {
|
|
56463
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
56464
|
-
}
|
|
56465
|
-
if (!fs23.existsSync(resolved)) {
|
|
56466
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
56467
|
-
}
|
|
56468
|
-
const stat2 = fs23.statSync(resolved);
|
|
56469
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
56470
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
56471
|
-
}
|
|
56472
|
-
const raw = fs23.readFileSync(resolved, "utf-8");
|
|
56473
|
-
try {
|
|
56474
|
-
const parsed = JSON.parse(raw);
|
|
56475
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
56476
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
56477
|
-
}
|
|
56478
|
-
this.dataDocument = parsed;
|
|
56479
|
-
} catch (err) {
|
|
56480
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
56481
|
-
throw err;
|
|
56482
|
-
}
|
|
56483
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
56484
|
-
}
|
|
56485
|
-
}
|
|
56486
|
-
async evaluate(input) {
|
|
56487
|
-
if (!this.policy) {
|
|
56488
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
56489
|
-
}
|
|
56490
|
-
this.policy.setData(this.dataDocument);
|
|
56491
|
-
const resultSet = this.policy.evaluate(input);
|
|
56492
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
56493
|
-
return resultSet[0].result;
|
|
56494
|
-
}
|
|
56495
|
-
return void 0;
|
|
56496
|
-
}
|
|
56497
|
-
async shutdown() {
|
|
56498
|
-
if (this.policy) {
|
|
56499
|
-
if (typeof this.policy.close === "function") {
|
|
56500
|
-
try {
|
|
56501
|
-
this.policy.close();
|
|
56502
|
-
} catch {
|
|
56503
|
-
}
|
|
56504
|
-
} else if (typeof this.policy.free === "function") {
|
|
56505
|
-
try {
|
|
56506
|
-
this.policy.free();
|
|
56507
|
-
} catch {
|
|
56508
|
-
}
|
|
56509
|
-
}
|
|
56510
|
-
}
|
|
56511
|
-
this.policy = null;
|
|
56512
|
-
}
|
|
56513
|
-
};
|
|
56514
|
-
}
|
|
56515
|
-
});
|
|
56516
|
-
|
|
56517
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
56518
|
-
var OpaHttpEvaluator;
|
|
56519
|
-
var init_opa_http_evaluator = __esm({
|
|
56520
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
56521
|
-
"use strict";
|
|
56522
|
-
OpaHttpEvaluator = class {
|
|
56523
|
-
baseUrl;
|
|
56524
|
-
timeout;
|
|
56525
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
56526
|
-
let parsed;
|
|
56527
|
-
try {
|
|
56528
|
-
parsed = new URL(baseUrl);
|
|
56529
|
-
} catch {
|
|
56530
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
56531
|
-
}
|
|
56532
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
56533
|
-
throw new Error(
|
|
56534
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
56535
|
-
);
|
|
56536
|
-
}
|
|
56537
|
-
const hostname = parsed.hostname;
|
|
56538
|
-
if (this.isBlockedHostname(hostname)) {
|
|
56539
|
-
throw new Error(
|
|
56540
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
56541
|
-
);
|
|
56542
|
-
}
|
|
56543
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
56544
|
-
this.timeout = timeout;
|
|
56545
|
-
}
|
|
56546
|
-
/**
|
|
56547
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
56548
|
-
*
|
|
56549
|
-
* Blocks:
|
|
56550
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
56551
|
-
* - Link-local addresses (169.254.x.x)
|
|
56552
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
56553
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
56554
|
-
* - Cloud metadata services (*.internal)
|
|
56555
|
-
*/
|
|
56556
|
-
isBlockedHostname(hostname) {
|
|
56557
|
-
if (!hostname) return true;
|
|
56558
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
56559
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
56560
|
-
return true;
|
|
56561
|
-
}
|
|
56562
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
56563
|
-
return true;
|
|
56564
|
-
}
|
|
56565
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
56566
|
-
return true;
|
|
56567
|
-
}
|
|
56568
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
56569
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
56570
|
-
if (ipv4Match) {
|
|
56571
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
56572
|
-
if (octets.some((octet) => octet > 255)) {
|
|
56573
|
-
return false;
|
|
56574
|
-
}
|
|
56575
|
-
const [a, b] = octets;
|
|
56576
|
-
if (a === 127) {
|
|
56577
|
-
return true;
|
|
56578
|
-
}
|
|
56579
|
-
if (a === 0) {
|
|
56580
|
-
return true;
|
|
56581
|
-
}
|
|
56582
|
-
if (a === 169 && b === 254) {
|
|
56583
|
-
return true;
|
|
56584
|
-
}
|
|
56585
|
-
if (a === 10) {
|
|
56586
|
-
return true;
|
|
56587
|
-
}
|
|
56588
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
56589
|
-
return true;
|
|
56590
|
-
}
|
|
56591
|
-
if (a === 192 && b === 168) {
|
|
56592
|
-
return true;
|
|
56593
|
-
}
|
|
56594
|
-
}
|
|
56595
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
56596
|
-
return true;
|
|
56597
|
-
}
|
|
56598
|
-
if (normalized.startsWith("fe80:")) {
|
|
56599
|
-
return true;
|
|
56600
|
-
}
|
|
56601
|
-
return false;
|
|
56602
|
-
}
|
|
56603
|
-
/**
|
|
56604
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
56605
|
-
*
|
|
56606
|
-
* @param input - The input document to evaluate
|
|
56607
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
56608
|
-
* @returns The result object from OPA, or undefined on error
|
|
56609
|
-
*/
|
|
56610
|
-
async evaluate(input, rulePath) {
|
|
56611
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
56612
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
56613
|
-
const controller = new AbortController();
|
|
56614
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
56615
|
-
try {
|
|
56616
|
-
const response = await fetch(url, {
|
|
56617
|
-
method: "POST",
|
|
56618
|
-
headers: { "Content-Type": "application/json" },
|
|
56619
|
-
body: JSON.stringify({ input }),
|
|
56620
|
-
signal: controller.signal
|
|
56621
|
-
});
|
|
56622
|
-
if (!response.ok) {
|
|
56623
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
56624
|
-
}
|
|
56625
|
-
let body;
|
|
56626
|
-
try {
|
|
56627
|
-
body = await response.json();
|
|
56628
|
-
} catch (jsonErr) {
|
|
56629
|
-
throw new Error(
|
|
56630
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
56631
|
-
);
|
|
56632
|
-
}
|
|
56633
|
-
return body?.result;
|
|
56634
|
-
} finally {
|
|
56635
|
-
clearTimeout(timer);
|
|
56636
|
-
}
|
|
56637
|
-
}
|
|
56638
|
-
async shutdown() {
|
|
56639
|
-
}
|
|
56640
|
-
};
|
|
56641
|
-
}
|
|
56642
|
-
});
|
|
56643
|
-
|
|
56644
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
56645
|
-
var PolicyInputBuilder;
|
|
56646
|
-
var init_policy_input_builder = __esm({
|
|
56647
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
56648
|
-
"use strict";
|
|
56649
|
-
PolicyInputBuilder = class {
|
|
56650
|
-
roles;
|
|
56651
|
-
actor;
|
|
56652
|
-
repository;
|
|
56653
|
-
pullRequest;
|
|
56654
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
56655
|
-
this.roles = policyConfig.roles || {};
|
|
56656
|
-
this.actor = actor;
|
|
56657
|
-
this.repository = repository;
|
|
56658
|
-
this.pullRequest = pullRequest;
|
|
56659
|
-
}
|
|
56660
|
-
/** Resolve which roles apply to the current actor. */
|
|
56661
|
-
resolveRoles() {
|
|
56662
|
-
const matched = [];
|
|
56663
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
56664
|
-
let identityMatch = false;
|
|
56665
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
56666
|
-
identityMatch = true;
|
|
56667
|
-
}
|
|
56668
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
56669
|
-
identityMatch = true;
|
|
56670
|
-
}
|
|
56671
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
56672
|
-
identityMatch = true;
|
|
56673
|
-
}
|
|
56674
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
56675
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
56676
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
56677
|
-
identityMatch = true;
|
|
56678
|
-
}
|
|
56679
|
-
}
|
|
56680
|
-
if (!identityMatch) continue;
|
|
56681
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
56682
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
56683
|
-
continue;
|
|
56684
|
-
}
|
|
56685
|
-
}
|
|
56686
|
-
matched.push(roleName);
|
|
56687
|
-
}
|
|
56688
|
-
return matched;
|
|
56689
|
-
}
|
|
56690
|
-
buildActor() {
|
|
56691
|
-
return {
|
|
56692
|
-
authorAssociation: this.actor.authorAssociation,
|
|
56693
|
-
login: this.actor.login,
|
|
56694
|
-
roles: this.resolveRoles(),
|
|
56695
|
-
isLocalMode: this.actor.isLocalMode,
|
|
56696
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
56697
|
-
};
|
|
56698
|
-
}
|
|
56699
|
-
forCheckExecution(check) {
|
|
56700
|
-
return {
|
|
56701
|
-
scope: "check.execute",
|
|
56702
|
-
check: {
|
|
56703
|
-
id: check.id,
|
|
56704
|
-
type: check.type,
|
|
56705
|
-
group: check.group,
|
|
56706
|
-
tags: check.tags,
|
|
56707
|
-
criticality: check.criticality,
|
|
56708
|
-
sandbox: check.sandbox,
|
|
56709
|
-
policy: check.policy
|
|
56710
|
-
},
|
|
56711
|
-
actor: this.buildActor(),
|
|
56712
|
-
repository: this.repository,
|
|
56713
|
-
pullRequest: this.pullRequest
|
|
56714
|
-
};
|
|
56715
|
-
}
|
|
56716
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
56717
|
-
return {
|
|
56718
|
-
scope: "tool.invoke",
|
|
56719
|
-
tool: { serverName, methodName, transport },
|
|
56720
|
-
actor: this.buildActor(),
|
|
56721
|
-
repository: this.repository,
|
|
56722
|
-
pullRequest: this.pullRequest
|
|
56723
|
-
};
|
|
56724
|
-
}
|
|
56725
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
56726
|
-
return {
|
|
56727
|
-
scope: "capability.resolve",
|
|
56728
|
-
check: { id: checkId, type: "ai" },
|
|
56729
|
-
capability: capabilities,
|
|
56730
|
-
actor: this.buildActor(),
|
|
56731
|
-
repository: this.repository,
|
|
56732
|
-
pullRequest: this.pullRequest
|
|
56733
|
-
};
|
|
56734
|
-
}
|
|
56735
|
-
};
|
|
56736
|
-
}
|
|
56737
|
-
});
|
|
56738
|
-
|
|
56739
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
56740
|
-
var opa_policy_engine_exports = {};
|
|
56741
|
-
__export(opa_policy_engine_exports, {
|
|
56742
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
56743
|
-
});
|
|
56744
|
-
var OpaPolicyEngine;
|
|
56745
|
-
var init_opa_policy_engine = __esm({
|
|
56746
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
56747
|
-
"use strict";
|
|
56748
|
-
init_opa_wasm_evaluator();
|
|
56749
|
-
init_opa_http_evaluator();
|
|
56750
|
-
init_policy_input_builder();
|
|
56751
|
-
OpaPolicyEngine = class {
|
|
56752
|
-
evaluator = null;
|
|
56753
|
-
fallback;
|
|
56754
|
-
timeout;
|
|
56755
|
-
config;
|
|
56756
|
-
inputBuilder = null;
|
|
56757
|
-
logger = null;
|
|
56758
|
-
constructor(config) {
|
|
56759
|
-
this.config = config;
|
|
56760
|
-
this.fallback = config.fallback || "deny";
|
|
56761
|
-
this.timeout = config.timeout || 5e3;
|
|
56762
|
-
}
|
|
56763
|
-
async initialize(config) {
|
|
56764
|
-
try {
|
|
56765
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
56766
|
-
} catch {
|
|
56767
|
-
}
|
|
56768
|
-
const actor = {
|
|
56769
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
56770
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
56771
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
56772
|
-
};
|
|
56773
|
-
const repo = {
|
|
56774
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
56775
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
56776
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
56777
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
56778
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
56779
|
-
};
|
|
56780
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
56781
|
-
const pullRequest = {
|
|
56782
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
56783
|
-
};
|
|
56784
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
56785
|
-
if (config.engine === "local") {
|
|
56786
|
-
if (!config.rules) {
|
|
56787
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
56788
|
-
}
|
|
56789
|
-
const wasm = new OpaWasmEvaluator();
|
|
56790
|
-
await wasm.initialize(config.rules);
|
|
56791
|
-
if (config.data) {
|
|
56792
|
-
wasm.loadData(config.data);
|
|
56793
|
-
}
|
|
56794
|
-
this.evaluator = wasm;
|
|
56795
|
-
} else if (config.engine === "remote") {
|
|
56796
|
-
if (!config.url) {
|
|
56797
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
56798
|
-
}
|
|
56799
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
56800
|
-
} else {
|
|
56801
|
-
this.evaluator = null;
|
|
56802
|
-
}
|
|
56803
|
-
}
|
|
56804
|
-
/**
|
|
56805
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
56806
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
56807
|
-
*/
|
|
56808
|
-
setActorContext(actor, repo, pullRequest) {
|
|
56809
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
56810
|
-
}
|
|
56811
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
56812
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
56813
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
56814
|
-
const policyOverride = cfg.policy;
|
|
56815
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
56816
|
-
id: checkId,
|
|
56817
|
-
type: cfg.type || "ai",
|
|
56818
|
-
group: cfg.group,
|
|
56819
|
-
tags: cfg.tags,
|
|
56820
|
-
criticality: cfg.criticality,
|
|
56821
|
-
sandbox: cfg.sandbox,
|
|
56822
|
-
policy: policyOverride
|
|
56823
|
-
});
|
|
56824
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
56825
|
-
}
|
|
56826
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
56827
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
56828
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
56829
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
56830
|
-
}
|
|
56831
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
56832
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
56833
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
56834
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
56835
|
-
}
|
|
56836
|
-
async shutdown() {
|
|
56837
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
56838
|
-
await this.evaluator.shutdown();
|
|
56839
|
-
}
|
|
56840
|
-
this.evaluator = null;
|
|
56841
|
-
this.inputBuilder = null;
|
|
56842
|
-
}
|
|
56843
|
-
resolveRulePath(defaultScope, override) {
|
|
56844
|
-
if (override) {
|
|
56845
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
56846
|
-
}
|
|
56847
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
56848
|
-
}
|
|
56849
|
-
async doEvaluate(input, rulePath) {
|
|
56850
|
-
try {
|
|
56851
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
56852
|
-
let timer;
|
|
56853
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
56854
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
56855
|
-
});
|
|
56856
|
-
try {
|
|
56857
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
56858
|
-
const decision = this.parseDecision(result);
|
|
56859
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
56860
|
-
decision.allowed = true;
|
|
56861
|
-
decision.warn = true;
|
|
56862
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
56863
|
-
}
|
|
56864
|
-
this.logger?.debug(
|
|
56865
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
56866
|
-
);
|
|
56867
|
-
return decision;
|
|
56868
|
-
} finally {
|
|
56869
|
-
if (timer) clearTimeout(timer);
|
|
56870
|
-
}
|
|
56871
|
-
} catch (err) {
|
|
56872
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
56873
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
56874
|
-
return {
|
|
56875
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
56876
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
56877
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
56878
|
-
};
|
|
56879
|
-
}
|
|
56880
|
-
}
|
|
56881
|
-
async rawEvaluate(input, rulePath) {
|
|
56882
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
56883
|
-
const result = await this.evaluator.evaluate(input);
|
|
56884
|
-
return this.navigateWasmResult(result, rulePath);
|
|
56885
|
-
}
|
|
56886
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
56887
|
-
}
|
|
56888
|
-
/**
|
|
56889
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
56890
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
56891
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
56892
|
-
*/
|
|
56893
|
-
navigateWasmResult(result, rulePath) {
|
|
56894
|
-
if (!result || typeof result !== "object") return result;
|
|
56895
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
56896
|
-
let current = result;
|
|
56897
|
-
for (const seg of segments) {
|
|
56898
|
-
if (current && typeof current === "object" && seg in current) {
|
|
56899
|
-
current = current[seg];
|
|
56900
|
-
} else {
|
|
56901
|
-
return void 0;
|
|
56902
|
-
}
|
|
56903
|
-
}
|
|
56904
|
-
return current;
|
|
56905
|
-
}
|
|
56906
|
-
parseDecision(result) {
|
|
56907
|
-
if (result === void 0 || result === null) {
|
|
56908
|
-
return {
|
|
56909
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
56910
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
56911
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
56912
|
-
};
|
|
56913
|
-
}
|
|
56914
|
-
const allowed = result.allowed !== false;
|
|
56915
|
-
const decision = {
|
|
56916
|
-
allowed,
|
|
56917
|
-
reason: result.reason
|
|
56918
|
-
};
|
|
56919
|
-
if (result.capabilities) {
|
|
56920
|
-
decision.capabilities = result.capabilities;
|
|
56921
|
-
}
|
|
56922
|
-
return decision;
|
|
56923
|
-
}
|
|
56924
|
-
};
|
|
56925
|
-
}
|
|
56926
|
-
});
|
|
56927
|
-
|
|
56928
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
56929
|
-
var knex_store_exports = {};
|
|
56930
|
-
__export(knex_store_exports, {
|
|
56931
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
56932
|
-
});
|
|
56933
|
-
function toNum(val) {
|
|
56934
|
-
if (val === null || val === void 0) return void 0;
|
|
56935
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
56936
|
-
}
|
|
56937
|
-
function safeJsonParse2(value) {
|
|
56938
|
-
if (!value) return void 0;
|
|
56939
|
-
try {
|
|
56940
|
-
return JSON.parse(value);
|
|
56941
|
-
} catch {
|
|
56942
|
-
return void 0;
|
|
56943
|
-
}
|
|
56944
|
-
}
|
|
56945
|
-
function fromTriggerRow2(row) {
|
|
56946
|
-
return {
|
|
56947
|
-
id: row.id,
|
|
56948
|
-
creatorId: row.creator_id,
|
|
56949
|
-
creatorContext: row.creator_context ?? void 0,
|
|
56950
|
-
creatorName: row.creator_name ?? void 0,
|
|
56951
|
-
description: row.description ?? void 0,
|
|
56952
|
-
channels: safeJsonParse2(row.channels),
|
|
56953
|
-
fromUsers: safeJsonParse2(row.from_users),
|
|
56954
|
-
fromBots: row.from_bots === true || row.from_bots === 1,
|
|
56955
|
-
contains: safeJsonParse2(row.contains),
|
|
56956
|
-
matchPattern: row.match_pattern ?? void 0,
|
|
56957
|
-
threads: row.threads,
|
|
56958
|
-
workflow: row.workflow,
|
|
56959
|
-
inputs: safeJsonParse2(row.inputs),
|
|
56960
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
56961
|
-
status: row.status,
|
|
56962
|
-
enabled: row.enabled === true || row.enabled === 1,
|
|
56963
|
-
createdAt: toNum(row.created_at)
|
|
56964
|
-
};
|
|
56965
|
-
}
|
|
56966
|
-
function toTriggerInsertRow(trigger) {
|
|
56967
|
-
return {
|
|
56968
|
-
id: trigger.id,
|
|
56969
|
-
creator_id: trigger.creatorId,
|
|
56970
|
-
creator_context: trigger.creatorContext ?? null,
|
|
56971
|
-
creator_name: trigger.creatorName ?? null,
|
|
56972
|
-
description: trigger.description ?? null,
|
|
56973
|
-
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
56974
|
-
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
56975
|
-
from_bots: trigger.fromBots,
|
|
56976
|
-
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
56977
|
-
match_pattern: trigger.matchPattern ?? null,
|
|
56978
|
-
threads: trigger.threads,
|
|
56979
|
-
workflow: trigger.workflow,
|
|
56980
|
-
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
56981
|
-
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
56982
|
-
status: trigger.status,
|
|
56983
|
-
enabled: trigger.enabled,
|
|
56984
|
-
created_at: trigger.createdAt
|
|
56985
|
-
};
|
|
56986
|
-
}
|
|
56987
|
-
function fromDbRow2(row) {
|
|
56988
|
-
return {
|
|
56989
|
-
id: row.id,
|
|
56990
|
-
creatorId: row.creator_id,
|
|
56991
|
-
creatorContext: row.creator_context ?? void 0,
|
|
56992
|
-
creatorName: row.creator_name ?? void 0,
|
|
56993
|
-
timezone: row.timezone,
|
|
56994
|
-
schedule: row.schedule_expr,
|
|
56995
|
-
runAt: toNum(row.run_at),
|
|
56996
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
56997
|
-
originalExpression: row.original_expression,
|
|
56998
|
-
workflow: row.workflow ?? void 0,
|
|
56999
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
57000
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
57001
|
-
status: row.status,
|
|
57002
|
-
createdAt: toNum(row.created_at),
|
|
57003
|
-
lastRunAt: toNum(row.last_run_at),
|
|
57004
|
-
nextRunAt: toNum(row.next_run_at),
|
|
57005
|
-
runCount: row.run_count,
|
|
57006
|
-
failureCount: row.failure_count,
|
|
57007
|
-
lastError: row.last_error ?? void 0,
|
|
57008
|
-
previousResponse: row.previous_response ?? void 0
|
|
57009
|
-
};
|
|
57010
|
-
}
|
|
57011
|
-
function toInsertRow(schedule) {
|
|
57012
|
-
return {
|
|
57013
|
-
id: schedule.id,
|
|
57014
|
-
creator_id: schedule.creatorId,
|
|
57015
|
-
creator_context: schedule.creatorContext ?? null,
|
|
57016
|
-
creator_name: schedule.creatorName ?? null,
|
|
57017
|
-
timezone: schedule.timezone,
|
|
57018
|
-
schedule_expr: schedule.schedule,
|
|
57019
|
-
run_at: schedule.runAt ?? null,
|
|
57020
|
-
is_recurring: schedule.isRecurring,
|
|
57021
|
-
original_expression: schedule.originalExpression,
|
|
57022
|
-
workflow: schedule.workflow ?? null,
|
|
57023
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
57024
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
57025
|
-
status: schedule.status,
|
|
57026
|
-
created_at: schedule.createdAt,
|
|
57027
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
57028
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
57029
|
-
run_count: schedule.runCount,
|
|
57030
|
-
failure_count: schedule.failureCount,
|
|
57031
|
-
last_error: schedule.lastError ?? null,
|
|
57032
|
-
previous_response: schedule.previousResponse ?? null
|
|
57033
|
-
};
|
|
57034
|
-
}
|
|
57035
|
-
var fs24, path28, import_uuid2, KnexStoreBackend;
|
|
57036
|
-
var init_knex_store = __esm({
|
|
57037
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
57038
|
-
"use strict";
|
|
57039
|
-
fs24 = __toESM(require("fs"));
|
|
57040
|
-
path28 = __toESM(require("path"));
|
|
57041
|
-
import_uuid2 = require("uuid");
|
|
57042
|
-
init_logger();
|
|
57043
|
-
KnexStoreBackend = class {
|
|
57044
|
-
knex = null;
|
|
57045
|
-
driver;
|
|
57046
|
-
connection;
|
|
57047
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
57048
|
-
this.driver = driver;
|
|
57049
|
-
this.connection = storageConfig.connection || {};
|
|
57050
|
-
}
|
|
57051
|
-
async initialize() {
|
|
57052
|
-
const { createRequire } = require("module");
|
|
57053
|
-
const runtimeRequire = createRequire(__filename);
|
|
57054
|
-
let knexFactory;
|
|
57055
|
-
try {
|
|
57056
|
-
knexFactory = runtimeRequire("knex");
|
|
57057
|
-
} catch (err) {
|
|
57058
|
-
const code = err?.code;
|
|
57059
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
57060
|
-
throw new Error(
|
|
57061
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
57062
|
-
);
|
|
57063
|
-
}
|
|
57064
|
-
throw err;
|
|
57065
|
-
}
|
|
57066
|
-
const clientMap = {
|
|
57067
|
-
postgresql: "pg",
|
|
57068
|
-
mysql: "mysql2",
|
|
57069
|
-
mssql: "tedious"
|
|
57070
|
-
};
|
|
57071
|
-
const client = clientMap[this.driver];
|
|
57072
|
-
let connection;
|
|
57073
|
-
if (this.connection.connection_string) {
|
|
57074
|
-
connection = this.connection.connection_string;
|
|
57075
|
-
} else if (this.driver === "mssql") {
|
|
57076
|
-
connection = this.buildMssqlConnection();
|
|
57077
|
-
} else {
|
|
57078
|
-
connection = this.buildStandardConnection();
|
|
57079
|
-
}
|
|
57080
|
-
this.knex = knexFactory({
|
|
57081
|
-
client,
|
|
57082
|
-
connection,
|
|
57083
|
-
pool: {
|
|
57084
|
-
min: this.connection.pool?.min ?? 0,
|
|
57085
|
-
max: this.connection.pool?.max ?? 10
|
|
57086
|
-
}
|
|
57087
|
-
});
|
|
57088
|
-
await this.migrateSchema();
|
|
57089
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
57090
|
-
}
|
|
57091
|
-
buildStandardConnection() {
|
|
57092
|
-
return {
|
|
57093
|
-
host: this.connection.host || "localhost",
|
|
57094
|
-
port: this.connection.port,
|
|
57095
|
-
database: this.connection.database || "visor",
|
|
57096
|
-
user: this.connection.user,
|
|
57097
|
-
password: this.connection.password,
|
|
57098
|
-
ssl: this.resolveSslConfig()
|
|
57099
|
-
};
|
|
57100
|
-
}
|
|
57101
|
-
buildMssqlConnection() {
|
|
57102
|
-
const ssl = this.connection.ssl;
|
|
57103
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
57104
|
-
return {
|
|
57105
|
-
server: this.connection.host || "localhost",
|
|
57106
|
-
port: this.connection.port,
|
|
57107
|
-
database: this.connection.database || "visor",
|
|
57108
|
-
user: this.connection.user,
|
|
57109
|
-
password: this.connection.password,
|
|
57110
|
-
options: {
|
|
57111
|
-
encrypt: sslEnabled,
|
|
57112
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
57113
|
-
}
|
|
57114
|
-
};
|
|
57115
|
-
}
|
|
57116
|
-
resolveSslConfig() {
|
|
57117
|
-
const ssl = this.connection.ssl;
|
|
57118
|
-
if (ssl === false || ssl === void 0) return false;
|
|
57119
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
57120
|
-
if (ssl.enabled === false) return false;
|
|
57121
|
-
const result = {
|
|
57122
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
57123
|
-
};
|
|
57124
|
-
if (ssl.ca) {
|
|
57125
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
57126
|
-
result.ca = fs24.readFileSync(caPath, "utf8");
|
|
57127
|
-
}
|
|
57128
|
-
if (ssl.cert) {
|
|
57129
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
57130
|
-
result.cert = fs24.readFileSync(certPath, "utf8");
|
|
57131
|
-
}
|
|
57132
|
-
if (ssl.key) {
|
|
57133
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
57134
|
-
result.key = fs24.readFileSync(keyPath, "utf8");
|
|
57135
|
-
}
|
|
57136
|
-
return result;
|
|
57137
|
-
}
|
|
57138
|
-
validateSslPath(filePath, label) {
|
|
57139
|
-
const resolved = path28.resolve(filePath);
|
|
57140
|
-
if (resolved !== path28.normalize(resolved)) {
|
|
57141
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
57142
|
-
}
|
|
57143
|
-
if (!fs24.existsSync(resolved)) {
|
|
57144
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
57145
|
-
}
|
|
57146
|
-
return resolved;
|
|
57147
|
-
}
|
|
57148
|
-
async shutdown() {
|
|
57149
|
-
if (this.knex) {
|
|
57150
|
-
await this.knex.destroy();
|
|
57151
|
-
this.knex = null;
|
|
57152
|
-
}
|
|
57153
|
-
}
|
|
57154
|
-
async migrateSchema() {
|
|
57155
|
-
const knex = this.getKnex();
|
|
57156
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
57157
|
-
if (!exists) {
|
|
57158
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
57159
|
-
table.string("id", 36).primary();
|
|
57160
|
-
table.string("creator_id", 255).notNullable().index();
|
|
57161
|
-
table.string("creator_context", 255);
|
|
57162
|
-
table.string("creator_name", 255);
|
|
57163
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
57164
|
-
table.string("schedule_expr", 255);
|
|
57165
|
-
table.bigInteger("run_at");
|
|
57166
|
-
table.boolean("is_recurring").notNullable();
|
|
57167
|
-
table.text("original_expression");
|
|
57168
|
-
table.string("workflow", 255);
|
|
57169
|
-
table.text("workflow_inputs");
|
|
57170
|
-
table.text("output_context");
|
|
57171
|
-
table.string("status", 20).notNullable().index();
|
|
57172
|
-
table.bigInteger("created_at").notNullable();
|
|
57173
|
-
table.bigInteger("last_run_at");
|
|
57174
|
-
table.bigInteger("next_run_at");
|
|
57175
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
57176
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
57177
|
-
table.text("last_error");
|
|
57178
|
-
table.text("previous_response");
|
|
57179
|
-
table.index(["status", "next_run_at"]);
|
|
57180
|
-
});
|
|
57181
|
-
}
|
|
57182
|
-
const triggersExist = await knex.schema.hasTable("message_triggers");
|
|
57183
|
-
if (!triggersExist) {
|
|
57184
|
-
await knex.schema.createTable("message_triggers", (table) => {
|
|
57185
|
-
table.string("id", 36).primary();
|
|
57186
|
-
table.string("creator_id", 255).notNullable().index();
|
|
57187
|
-
table.string("creator_context", 255);
|
|
57188
|
-
table.string("creator_name", 255);
|
|
57189
|
-
table.text("description");
|
|
57190
|
-
table.text("channels");
|
|
57191
|
-
table.text("from_users");
|
|
57192
|
-
table.boolean("from_bots").notNullable().defaultTo(false);
|
|
57193
|
-
table.text("contains");
|
|
57194
|
-
table.text("match_pattern");
|
|
57195
|
-
table.string("threads", 20).notNullable().defaultTo("any");
|
|
57196
|
-
table.string("workflow", 255).notNullable();
|
|
57197
|
-
table.text("inputs");
|
|
57198
|
-
table.text("output_context");
|
|
57199
|
-
table.string("status", 20).notNullable().defaultTo("active").index();
|
|
57200
|
-
table.boolean("enabled").notNullable().defaultTo(true);
|
|
57201
|
-
table.bigInteger("created_at").notNullable();
|
|
57202
|
-
});
|
|
57203
|
-
}
|
|
57204
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
57205
|
-
if (!locksExist) {
|
|
57206
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
57207
|
-
table.string("lock_id", 255).primary();
|
|
57208
|
-
table.string("node_id", 255).notNullable();
|
|
57209
|
-
table.string("lock_token", 36).notNullable();
|
|
57210
|
-
table.bigInteger("acquired_at").notNullable();
|
|
57211
|
-
table.bigInteger("expires_at").notNullable();
|
|
57212
|
-
});
|
|
57213
|
-
}
|
|
57214
|
-
}
|
|
57215
|
-
getKnex() {
|
|
57216
|
-
if (!this.knex) {
|
|
57217
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
57218
|
-
}
|
|
57219
|
-
return this.knex;
|
|
57220
|
-
}
|
|
57221
|
-
// --- CRUD ---
|
|
57222
|
-
async create(schedule) {
|
|
57223
|
-
const knex = this.getKnex();
|
|
57224
|
-
const newSchedule = {
|
|
57225
|
-
...schedule,
|
|
57226
|
-
id: (0, import_uuid2.v4)(),
|
|
57227
|
-
createdAt: Date.now(),
|
|
57228
|
-
runCount: 0,
|
|
57229
|
-
failureCount: 0,
|
|
57230
|
-
status: "active"
|
|
57231
|
-
};
|
|
57232
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
57233
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
57234
|
-
return newSchedule;
|
|
57235
|
-
}
|
|
57236
|
-
async importSchedule(schedule) {
|
|
57237
|
-
const knex = this.getKnex();
|
|
57238
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
57239
|
-
if (existing) return;
|
|
57240
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
57241
|
-
}
|
|
57242
|
-
async get(id) {
|
|
57243
|
-
const knex = this.getKnex();
|
|
57244
|
-
const row = await knex("schedules").where("id", id).first();
|
|
57245
|
-
return row ? fromDbRow2(row) : void 0;
|
|
57246
|
-
}
|
|
57247
|
-
async update(id, patch) {
|
|
57248
|
-
const knex = this.getKnex();
|
|
57249
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
57250
|
-
if (!existing) return void 0;
|
|
57251
|
-
const current = fromDbRow2(existing);
|
|
57252
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
57253
|
-
const row = toInsertRow(updated);
|
|
57254
|
-
delete row.id;
|
|
57255
|
-
await knex("schedules").where("id", id).update(row);
|
|
57256
|
-
return updated;
|
|
57257
|
-
}
|
|
57258
|
-
async delete(id) {
|
|
57259
|
-
const knex = this.getKnex();
|
|
57260
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
57261
|
-
if (deleted > 0) {
|
|
57262
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
57263
|
-
return true;
|
|
57264
|
-
}
|
|
57265
|
-
return false;
|
|
57266
|
-
}
|
|
57267
|
-
// --- Queries ---
|
|
57268
|
-
async getByCreator(creatorId) {
|
|
57269
|
-
const knex = this.getKnex();
|
|
57270
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
57271
|
-
return rows.map((r) => fromDbRow2(r));
|
|
57272
|
-
}
|
|
57273
|
-
async getActiveSchedules() {
|
|
57274
|
-
const knex = this.getKnex();
|
|
57275
|
-
const rows = await knex("schedules").where("status", "active");
|
|
57276
|
-
return rows.map((r) => fromDbRow2(r));
|
|
57277
|
-
}
|
|
57278
|
-
async getDueSchedules(now) {
|
|
57279
|
-
const ts = now ?? Date.now();
|
|
57280
|
-
const knex = this.getKnex();
|
|
57281
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
57282
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
57283
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
57284
|
-
this.where(function() {
|
|
57285
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
57286
|
-
}).orWhere(function() {
|
|
57287
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
57288
|
-
});
|
|
57289
|
-
});
|
|
57290
|
-
return rows.map((r) => fromDbRow2(r));
|
|
57291
|
-
}
|
|
57292
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
57293
|
-
const knex = this.getKnex();
|
|
57294
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
57295
|
-
const pattern = `%${escaped}%`;
|
|
57296
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
57297
|
-
return rows.map((r) => fromDbRow2(r));
|
|
57298
|
-
}
|
|
57299
|
-
async getAll() {
|
|
57300
|
-
const knex = this.getKnex();
|
|
57301
|
-
const rows = await knex("schedules");
|
|
57302
|
-
return rows.map((r) => fromDbRow2(r));
|
|
57303
|
-
}
|
|
57304
|
-
async getStats() {
|
|
57305
|
-
const knex = this.getKnex();
|
|
57306
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
57307
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
57308
|
-
const result = await knex("schedules").select(
|
|
57309
|
-
knex.raw("COUNT(*) as total"),
|
|
57310
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
57311
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
57312
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
57313
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
57314
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
57315
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
57316
|
-
).first();
|
|
57317
|
-
return {
|
|
57318
|
-
total: Number(result.total) || 0,
|
|
57319
|
-
active: Number(result.active) || 0,
|
|
57320
|
-
paused: Number(result.paused) || 0,
|
|
57321
|
-
completed: Number(result.completed) || 0,
|
|
57322
|
-
failed: Number(result.failed) || 0,
|
|
57323
|
-
recurring: Number(result.recurring) || 0,
|
|
57324
|
-
oneTime: Number(result.one_time) || 0
|
|
57325
|
-
};
|
|
57326
|
-
}
|
|
57327
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
57328
|
-
const knex = this.getKnex();
|
|
57329
|
-
if (limits.maxGlobal) {
|
|
57330
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
57331
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
57332
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
57333
|
-
}
|
|
57334
|
-
}
|
|
57335
|
-
if (limits.maxPerUser) {
|
|
57336
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
57337
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
57338
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
57339
|
-
}
|
|
57340
|
-
}
|
|
57341
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
57342
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
57343
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
57344
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
57345
|
-
throw new Error(
|
|
57346
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
57347
|
-
);
|
|
57348
|
-
}
|
|
57349
|
-
}
|
|
57350
|
-
}
|
|
57351
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
57352
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
57353
|
-
const knex = this.getKnex();
|
|
57354
|
-
const now = Date.now();
|
|
57355
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
57356
|
-
const token = (0, import_uuid2.v4)();
|
|
57357
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
57358
|
-
node_id: nodeId,
|
|
57359
|
-
lock_token: token,
|
|
57360
|
-
acquired_at: now,
|
|
57361
|
-
expires_at: expiresAt
|
|
57362
|
-
});
|
|
57363
|
-
if (updated > 0) return token;
|
|
57364
|
-
try {
|
|
57365
|
-
await knex("scheduler_locks").insert({
|
|
57366
|
-
lock_id: lockId,
|
|
57367
|
-
node_id: nodeId,
|
|
57368
|
-
lock_token: token,
|
|
57369
|
-
acquired_at: now,
|
|
57370
|
-
expires_at: expiresAt
|
|
57371
|
-
});
|
|
57372
|
-
return token;
|
|
57373
|
-
} catch {
|
|
57374
|
-
return null;
|
|
57375
|
-
}
|
|
57376
|
-
}
|
|
57377
|
-
async releaseLock(lockId, lockToken) {
|
|
57378
|
-
const knex = this.getKnex();
|
|
57379
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
57380
|
-
}
|
|
57381
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
57382
|
-
const knex = this.getKnex();
|
|
57383
|
-
const now = Date.now();
|
|
57384
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
57385
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
57386
|
-
return updated > 0;
|
|
57387
|
-
}
|
|
57388
|
-
async flush() {
|
|
57389
|
-
}
|
|
57390
|
-
// --- Message Trigger CRUD ---
|
|
57391
|
-
async createTrigger(trigger) {
|
|
57392
|
-
const knex = this.getKnex();
|
|
57393
|
-
const newTrigger = {
|
|
57394
|
-
...trigger,
|
|
57395
|
-
id: (0, import_uuid2.v4)(),
|
|
57396
|
-
createdAt: Date.now()
|
|
57397
|
-
};
|
|
57398
|
-
await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
|
|
57399
|
-
logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
|
|
57400
|
-
return newTrigger;
|
|
57401
|
-
}
|
|
57402
|
-
async getTrigger(id) {
|
|
57403
|
-
const knex = this.getKnex();
|
|
57404
|
-
const row = await knex("message_triggers").where("id", id).first();
|
|
57405
|
-
return row ? fromTriggerRow2(row) : void 0;
|
|
57406
|
-
}
|
|
57407
|
-
async updateTrigger(id, patch) {
|
|
57408
|
-
const knex = this.getKnex();
|
|
57409
|
-
const existing = await knex("message_triggers").where("id", id).first();
|
|
57410
|
-
if (!existing) return void 0;
|
|
57411
|
-
const current = fromTriggerRow2(existing);
|
|
57412
|
-
const updated = {
|
|
57413
|
-
...current,
|
|
57414
|
-
...patch,
|
|
57415
|
-
id: current.id,
|
|
57416
|
-
createdAt: current.createdAt
|
|
57417
|
-
};
|
|
57418
|
-
const row = toTriggerInsertRow(updated);
|
|
57419
|
-
delete row.id;
|
|
57420
|
-
await knex("message_triggers").where("id", id).update(row);
|
|
57421
|
-
return updated;
|
|
57422
|
-
}
|
|
57423
|
-
async deleteTrigger(id) {
|
|
57424
|
-
const knex = this.getKnex();
|
|
57425
|
-
const deleted = await knex("message_triggers").where("id", id).del();
|
|
57426
|
-
if (deleted > 0) {
|
|
57427
|
-
logger.info(`[KnexStore] Deleted trigger ${id}`);
|
|
57428
|
-
return true;
|
|
57429
|
-
}
|
|
57430
|
-
return false;
|
|
57431
|
-
}
|
|
57432
|
-
async getTriggersByCreator(creatorId) {
|
|
57433
|
-
const knex = this.getKnex();
|
|
57434
|
-
const rows = await knex("message_triggers").where("creator_id", creatorId);
|
|
57435
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
57436
|
-
}
|
|
57437
|
-
async getActiveTriggers() {
|
|
57438
|
-
const knex = this.getKnex();
|
|
57439
|
-
const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
|
|
57440
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
57441
|
-
}
|
|
57442
|
-
};
|
|
57443
|
-
}
|
|
57444
|
-
});
|
|
57445
|
-
|
|
57446
|
-
// src/enterprise/loader.ts
|
|
57447
|
-
var loader_exports = {};
|
|
57448
|
-
__export(loader_exports, {
|
|
57449
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
57450
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
57451
|
-
});
|
|
57452
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
57453
|
-
try {
|
|
57454
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
57455
|
-
const validator = new LicenseValidator2();
|
|
57456
|
-
const license = await validator.loadAndValidate();
|
|
57457
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
57458
|
-
return new DefaultPolicyEngine();
|
|
57459
|
-
}
|
|
57460
|
-
if (validator.isInGracePeriod()) {
|
|
57461
|
-
console.warn(
|
|
57462
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
57463
|
-
);
|
|
57464
|
-
}
|
|
57465
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
57466
|
-
const engine = new OpaPolicyEngine2(config);
|
|
57467
|
-
await engine.initialize(config);
|
|
57468
|
-
return engine;
|
|
57469
|
-
} catch (err) {
|
|
57470
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
57471
|
-
try {
|
|
57472
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
57473
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
57474
|
-
} catch {
|
|
57475
|
-
}
|
|
57476
|
-
return new DefaultPolicyEngine();
|
|
57477
|
-
}
|
|
57478
|
-
}
|
|
57479
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
57480
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
57481
|
-
const validator = new LicenseValidator2();
|
|
57482
|
-
const license = await validator.loadAndValidate();
|
|
57483
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
57484
|
-
throw new Error(
|
|
57485
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
57486
|
-
);
|
|
57487
|
-
}
|
|
57488
|
-
if (validator.isInGracePeriod()) {
|
|
57489
|
-
console.warn(
|
|
57490
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
57491
|
-
);
|
|
57492
|
-
}
|
|
57493
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
57494
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
57495
|
-
}
|
|
57496
|
-
var init_loader = __esm({
|
|
57497
|
-
"src/enterprise/loader.ts"() {
|
|
57498
|
-
"use strict";
|
|
57499
|
-
init_default_engine();
|
|
57500
|
-
}
|
|
57501
|
-
});
|
|
57502
|
-
|
|
57503
56257
|
// src/event-bus/event-bus.ts
|
|
57504
56258
|
var event_bus_exports = {};
|
|
57505
56259
|
__export(event_bus_exports, {
|
|
@@ -57545,12 +56299,12 @@ var ndjson_sink_exports = {};
|
|
|
57545
56299
|
__export(ndjson_sink_exports, {
|
|
57546
56300
|
NdjsonSink: () => NdjsonSink
|
|
57547
56301
|
});
|
|
57548
|
-
var import_fs9,
|
|
56302
|
+
var import_fs9, import_path14, NdjsonSink;
|
|
57549
56303
|
var init_ndjson_sink = __esm({
|
|
57550
56304
|
"src/frontends/ndjson-sink.ts"() {
|
|
57551
56305
|
"use strict";
|
|
57552
56306
|
import_fs9 = __toESM(require("fs"));
|
|
57553
|
-
|
|
56307
|
+
import_path14 = __toESM(require("path"));
|
|
57554
56308
|
NdjsonSink = class {
|
|
57555
56309
|
name = "ndjson-sink";
|
|
57556
56310
|
cfg;
|
|
@@ -57582,8 +56336,8 @@ var init_ndjson_sink = __esm({
|
|
|
57582
56336
|
this.unsub = void 0;
|
|
57583
56337
|
}
|
|
57584
56338
|
resolveFile(p) {
|
|
57585
|
-
if (
|
|
57586
|
-
return
|
|
56339
|
+
if (import_path14.default.isAbsolute(p)) return p;
|
|
56340
|
+
return import_path14.default.join(process.cwd(), p);
|
|
57587
56341
|
}
|
|
57588
56342
|
};
|
|
57589
56343
|
}
|
|
@@ -58406,8 +57160,8 @@ ${content}
|
|
|
58406
57160
|
* Sleep utility
|
|
58407
57161
|
*/
|
|
58408
57162
|
sleep(ms) {
|
|
58409
|
-
return new Promise((
|
|
58410
|
-
const t = setTimeout(
|
|
57163
|
+
return new Promise((resolve15) => {
|
|
57164
|
+
const t = setTimeout(resolve15, ms);
|
|
58411
57165
|
if (typeof t.unref === "function") {
|
|
58412
57166
|
try {
|
|
58413
57167
|
t.unref();
|
|
@@ -58692,8 +57446,8 @@ ${end}`);
|
|
|
58692
57446
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
58693
57447
|
const existingLock = this.updateLocks.get(group);
|
|
58694
57448
|
let resolveLock;
|
|
58695
|
-
const ourLock = new Promise((
|
|
58696
|
-
resolveLock =
|
|
57449
|
+
const ourLock = new Promise((resolve15) => {
|
|
57450
|
+
resolveLock = resolve15;
|
|
58697
57451
|
});
|
|
58698
57452
|
this.updateLocks.set(group, ourLock);
|
|
58699
57453
|
try {
|
|
@@ -59024,7 +57778,7 @@ ${blocks}
|
|
|
59024
57778
|
* Sleep utility for enforcing delays
|
|
59025
57779
|
*/
|
|
59026
57780
|
sleep(ms) {
|
|
59027
|
-
return new Promise((
|
|
57781
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
59028
57782
|
}
|
|
59029
57783
|
};
|
|
59030
57784
|
}
|
|
@@ -60193,7 +58947,7 @@ var init_tui_frontend = __esm({
|
|
|
60193
58947
|
});
|
|
60194
58948
|
|
|
60195
58949
|
// src/agent-protocol/task-store.ts
|
|
60196
|
-
function
|
|
58950
|
+
function safeJsonParse2(value) {
|
|
60197
58951
|
if (!value) return void 0;
|
|
60198
58952
|
try {
|
|
60199
58953
|
return JSON.parse(value);
|
|
@@ -60210,22 +58964,22 @@ function taskRowToAgentTask(row) {
|
|
|
60210
58964
|
context_id: row.context_id,
|
|
60211
58965
|
status: {
|
|
60212
58966
|
state: row.state,
|
|
60213
|
-
message:
|
|
58967
|
+
message: safeJsonParse2(row.status_message),
|
|
60214
58968
|
timestamp: row.updated_at
|
|
60215
58969
|
},
|
|
60216
|
-
artifacts:
|
|
60217
|
-
history:
|
|
60218
|
-
metadata:
|
|
58970
|
+
artifacts: safeJsonParse2(row.artifacts) ?? [],
|
|
58971
|
+
history: safeJsonParse2(row.history) ?? [],
|
|
58972
|
+
metadata: safeJsonParse2(row.request_metadata),
|
|
60219
58973
|
workflow_id: row.workflow_id ?? void 0
|
|
60220
58974
|
};
|
|
60221
58975
|
}
|
|
60222
|
-
var
|
|
58976
|
+
var import_path15, import_fs10, import_crypto6, SqliteTaskStore;
|
|
60223
58977
|
var init_task_store = __esm({
|
|
60224
58978
|
"src/agent-protocol/task-store.ts"() {
|
|
60225
58979
|
"use strict";
|
|
60226
|
-
|
|
58980
|
+
import_path15 = __toESM(require("path"));
|
|
60227
58981
|
import_fs10 = __toESM(require("fs"));
|
|
60228
|
-
|
|
58982
|
+
import_crypto6 = __toESM(require("crypto"));
|
|
60229
58983
|
init_logger();
|
|
60230
58984
|
init_types();
|
|
60231
58985
|
init_state_transitions();
|
|
@@ -60236,8 +58990,8 @@ var init_task_store = __esm({
|
|
|
60236
58990
|
this.dbPath = filename || ".visor/agent-tasks.db";
|
|
60237
58991
|
}
|
|
60238
58992
|
async initialize() {
|
|
60239
|
-
const resolvedPath =
|
|
60240
|
-
const dir =
|
|
58993
|
+
const resolvedPath = import_path15.default.resolve(process.cwd(), this.dbPath);
|
|
58994
|
+
const dir = import_path15.default.dirname(resolvedPath);
|
|
60241
58995
|
import_fs10.default.mkdirSync(dir, { recursive: true });
|
|
60242
58996
|
const { createRequire } = require("module");
|
|
60243
58997
|
const runtimeRequire = createRequire(__filename);
|
|
@@ -60306,7 +59060,7 @@ var init_task_store = __esm({
|
|
|
60306
59060
|
// -------------------------------------------------------------------------
|
|
60307
59061
|
createTask(params) {
|
|
60308
59062
|
const db = this.getDb();
|
|
60309
|
-
const id =
|
|
59063
|
+
const id = import_crypto6.default.randomUUID();
|
|
60310
59064
|
const now = nowISO();
|
|
60311
59065
|
const contextId = this.resolveContextId(params.requestMessage, params.contextId);
|
|
60312
59066
|
const expiresAt = params.expiresAt ?? null;
|
|
@@ -60393,6 +59147,13 @@ var init_task_store = __esm({
|
|
|
60393
59147
|
messageText = textPart?.text ?? "";
|
|
60394
59148
|
} catch {
|
|
60395
59149
|
}
|
|
59150
|
+
let source = "-";
|
|
59151
|
+
let metadata = {};
|
|
59152
|
+
try {
|
|
59153
|
+
metadata = JSON.parse(r.request_metadata || "{}");
|
|
59154
|
+
source = metadata.source || "-";
|
|
59155
|
+
} catch {
|
|
59156
|
+
}
|
|
60396
59157
|
return {
|
|
60397
59158
|
id: r.id,
|
|
60398
59159
|
context_id: r.context_id,
|
|
@@ -60403,7 +59164,9 @@ var init_task_store = __esm({
|
|
|
60403
59164
|
claimed_at: r.claimed_at,
|
|
60404
59165
|
workflow_id: r.workflow_id,
|
|
60405
59166
|
run_id: r.run_id,
|
|
60406
|
-
request_message: messageText
|
|
59167
|
+
request_message: messageText,
|
|
59168
|
+
source,
|
|
59169
|
+
metadata
|
|
60407
59170
|
};
|
|
60408
59171
|
});
|
|
60409
59172
|
return { rows, total };
|
|
@@ -60423,11 +59186,18 @@ var init_task_store = __esm({
|
|
|
60423
59186
|
WHERE id = ?`
|
|
60424
59187
|
).run(newState, now, statusMessage ? JSON.stringify(statusMessage) : null, taskId);
|
|
60425
59188
|
}
|
|
59189
|
+
claimTask(taskId, workerId) {
|
|
59190
|
+
const db = this.getDb();
|
|
59191
|
+
const now = nowISO();
|
|
59192
|
+
db.prepare(
|
|
59193
|
+
`UPDATE agent_tasks SET claimed_by = ?, claimed_at = ?, updated_at = ? WHERE id = ?`
|
|
59194
|
+
).run(workerId, now, now, taskId);
|
|
59195
|
+
}
|
|
60426
59196
|
addArtifact(taskId, artifact) {
|
|
60427
59197
|
const db = this.getDb();
|
|
60428
59198
|
const row = db.prepare("SELECT artifacts FROM agent_tasks WHERE id = ?").get(taskId);
|
|
60429
59199
|
if (!row) throw new TaskNotFoundError(taskId);
|
|
60430
|
-
const artifacts =
|
|
59200
|
+
const artifacts = safeJsonParse2(row.artifacts) ?? [];
|
|
60431
59201
|
artifacts.push(artifact);
|
|
60432
59202
|
db.prepare("UPDATE agent_tasks SET artifacts = ?, updated_at = ? WHERE id = ?").run(
|
|
60433
59203
|
JSON.stringify(artifacts),
|
|
@@ -60439,7 +59209,7 @@ var init_task_store = __esm({
|
|
|
60439
59209
|
const db = this.getDb();
|
|
60440
59210
|
const row = db.prepare("SELECT history FROM agent_tasks WHERE id = ?").get(taskId);
|
|
60441
59211
|
if (!row) throw new TaskNotFoundError(taskId);
|
|
60442
|
-
const history =
|
|
59212
|
+
const history = safeJsonParse2(row.history) ?? [];
|
|
60443
59213
|
history.push(message);
|
|
60444
59214
|
db.prepare("UPDATE agent_tasks SET history = ?, updated_at = ? WHERE id = ?").run(
|
|
60445
59215
|
JSON.stringify(history),
|
|
@@ -60644,11 +59414,11 @@ var init_task_stream_manager = __esm({
|
|
|
60644
59414
|
});
|
|
60645
59415
|
|
|
60646
59416
|
// src/agent-protocol/push-notification-manager.ts
|
|
60647
|
-
var
|
|
59417
|
+
var import_crypto7, PushNotificationManager;
|
|
60648
59418
|
var init_push_notification_manager = __esm({
|
|
60649
59419
|
"src/agent-protocol/push-notification-manager.ts"() {
|
|
60650
59420
|
"use strict";
|
|
60651
|
-
|
|
59421
|
+
import_crypto7 = __toESM(require("crypto"));
|
|
60652
59422
|
init_logger();
|
|
60653
59423
|
PushNotificationManager = class {
|
|
60654
59424
|
db = null;
|
|
@@ -60693,7 +59463,7 @@ var init_push_notification_manager = __esm({
|
|
|
60693
59463
|
// -------------------------------------------------------------------------
|
|
60694
59464
|
create(config) {
|
|
60695
59465
|
const db = this.getDb();
|
|
60696
|
-
const id = config.id ??
|
|
59466
|
+
const id = config.id ?? import_crypto7.default.randomUUID();
|
|
60697
59467
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
60698
59468
|
db.prepare(
|
|
60699
59469
|
`INSERT INTO agent_push_configs (id, task_id, url, token, auth_scheme, auth_credentials, created_at)
|
|
@@ -60791,11 +59561,11 @@ var init_push_notification_manager = __esm({
|
|
|
60791
59561
|
});
|
|
60792
59562
|
|
|
60793
59563
|
// src/agent-protocol/task-queue.ts
|
|
60794
|
-
var
|
|
59564
|
+
var import_crypto8, DEFAULT_CONFIG, TaskQueue;
|
|
60795
59565
|
var init_task_queue = __esm({
|
|
60796
59566
|
"src/agent-protocol/task-queue.ts"() {
|
|
60797
59567
|
"use strict";
|
|
60798
|
-
|
|
59568
|
+
import_crypto8 = __toESM(require("crypto"));
|
|
60799
59569
|
init_logger();
|
|
60800
59570
|
init_trace_helpers();
|
|
60801
59571
|
DEFAULT_CONFIG = {
|
|
@@ -60808,7 +59578,7 @@ var init_task_queue = __esm({
|
|
|
60808
59578
|
this.taskStore = taskStore;
|
|
60809
59579
|
this.executor = executor;
|
|
60810
59580
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
60811
|
-
this.workerId = workerId ??
|
|
59581
|
+
this.workerId = workerId ?? import_crypto8.default.randomUUID();
|
|
60812
59582
|
}
|
|
60813
59583
|
running = false;
|
|
60814
59584
|
timer = null;
|
|
@@ -60882,7 +59652,7 @@ var init_task_queue = __esm({
|
|
|
60882
59652
|
}
|
|
60883
59653
|
if (result.success) {
|
|
60884
59654
|
const completedMsg = {
|
|
60885
|
-
message_id:
|
|
59655
|
+
message_id: import_crypto8.default.randomUUID(),
|
|
60886
59656
|
role: "agent",
|
|
60887
59657
|
parts: [
|
|
60888
59658
|
{
|
|
@@ -60894,7 +59664,7 @@ var init_task_queue = __esm({
|
|
|
60894
59664
|
this.taskStore.updateTaskState(task.id, "completed", completedMsg);
|
|
60895
59665
|
} else {
|
|
60896
59666
|
this.taskStore.updateTaskState(task.id, "failed", {
|
|
60897
|
-
message_id:
|
|
59667
|
+
message_id: import_crypto8.default.randomUUID(),
|
|
60898
59668
|
role: "agent",
|
|
60899
59669
|
parts: [{ text: result.error ?? "Task execution failed" }]
|
|
60900
59670
|
});
|
|
@@ -60905,7 +59675,7 @@ var init_task_queue = __esm({
|
|
|
60905
59675
|
);
|
|
60906
59676
|
try {
|
|
60907
59677
|
this.taskStore.updateTaskState(task.id, "failed", {
|
|
60908
|
-
message_id:
|
|
59678
|
+
message_id: import_crypto8.default.randomUUID(),
|
|
60909
59679
|
role: "agent",
|
|
60910
59680
|
parts: [{ text: err instanceof Error ? err.message : "Unknown error" }]
|
|
60911
59681
|
});
|
|
@@ -60925,13 +59695,13 @@ __export(a2a_frontend_exports, {
|
|
|
60925
59695
|
resultToArtifacts: () => resultToArtifacts
|
|
60926
59696
|
});
|
|
60927
59697
|
function readJsonBody(req) {
|
|
60928
|
-
return new Promise((
|
|
59698
|
+
return new Promise((resolve15, reject) => {
|
|
60929
59699
|
const chunks = [];
|
|
60930
59700
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
60931
59701
|
req.on("end", () => {
|
|
60932
59702
|
try {
|
|
60933
59703
|
const body = Buffer.concat(chunks).toString("utf8");
|
|
60934
|
-
|
|
59704
|
+
resolve15(body ? JSON.parse(body) : {});
|
|
60935
59705
|
} catch {
|
|
60936
59706
|
reject(new ParseError("Malformed JSON body"));
|
|
60937
59707
|
}
|
|
@@ -60959,7 +59729,7 @@ function timingSafeEqual(a, b) {
|
|
|
60959
59729
|
if (!a || !b) return false;
|
|
60960
59730
|
if (a.length !== b.length) return false;
|
|
60961
59731
|
try {
|
|
60962
|
-
return
|
|
59732
|
+
return import_crypto9.default.timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
60963
59733
|
} catch {
|
|
60964
59734
|
return false;
|
|
60965
59735
|
}
|
|
@@ -61033,7 +59803,7 @@ function resultToArtifacts(checkResults) {
|
|
|
61033
59803
|
}
|
|
61034
59804
|
if (parts.length > 0) {
|
|
61035
59805
|
artifacts.push({
|
|
61036
|
-
artifact_id:
|
|
59806
|
+
artifact_id: import_crypto9.default.randomUUID(),
|
|
61037
59807
|
name: checkId,
|
|
61038
59808
|
description: `Output from check: ${checkId}`,
|
|
61039
59809
|
parts
|
|
@@ -61042,14 +59812,14 @@ function resultToArtifacts(checkResults) {
|
|
|
61042
59812
|
}
|
|
61043
59813
|
return artifacts;
|
|
61044
59814
|
}
|
|
61045
|
-
var import_http2, import_https, import_fs11,
|
|
59815
|
+
var import_http2, import_https, import_fs11, import_crypto9, A2AFrontend;
|
|
61046
59816
|
var init_a2a_frontend = __esm({
|
|
61047
59817
|
"src/agent-protocol/a2a-frontend.ts"() {
|
|
61048
59818
|
"use strict";
|
|
61049
59819
|
import_http2 = __toESM(require("http"));
|
|
61050
59820
|
import_https = __toESM(require("https"));
|
|
61051
59821
|
import_fs11 = __toESM(require("fs"));
|
|
61052
|
-
|
|
59822
|
+
import_crypto9 = __toESM(require("crypto"));
|
|
61053
59823
|
init_logger();
|
|
61054
59824
|
init_task_store();
|
|
61055
59825
|
init_types();
|
|
@@ -61143,7 +59913,7 @@ var init_a2a_frontend = __esm({
|
|
|
61143
59913
|
if (!taskId) return;
|
|
61144
59914
|
try {
|
|
61145
59915
|
const statusMessage = {
|
|
61146
|
-
message_id:
|
|
59916
|
+
message_id: import_crypto9.default.randomUUID(),
|
|
61147
59917
|
role: "agent",
|
|
61148
59918
|
parts: [{ text: envelope.payload?.prompt ?? "Agent requires input" }]
|
|
61149
59919
|
};
|
|
@@ -61174,12 +59944,12 @@ var init_a2a_frontend = __esm({
|
|
|
61174
59944
|
}
|
|
61175
59945
|
const port = this.config.port ?? 9e3;
|
|
61176
59946
|
const host = this.config.host ?? "0.0.0.0";
|
|
61177
|
-
await new Promise((
|
|
59947
|
+
await new Promise((resolve15) => {
|
|
61178
59948
|
this.server.listen(port, host, () => {
|
|
61179
59949
|
const addr = this.server.address();
|
|
61180
59950
|
this._boundPort = typeof addr === "object" && addr ? addr.port : port;
|
|
61181
59951
|
logger.info(`A2A server listening on ${host}:${this._boundPort}`);
|
|
61182
|
-
|
|
59952
|
+
resolve15();
|
|
61183
59953
|
});
|
|
61184
59954
|
});
|
|
61185
59955
|
if (this.agentCard) {
|
|
@@ -61203,8 +59973,8 @@ var init_a2a_frontend = __esm({
|
|
|
61203
59973
|
}
|
|
61204
59974
|
this.streamManager.shutdown();
|
|
61205
59975
|
if (this.server) {
|
|
61206
|
-
await new Promise((
|
|
61207
|
-
this.server.close((err) => err ? reject(err) :
|
|
59976
|
+
await new Promise((resolve15, reject) => {
|
|
59977
|
+
this.server.close((err) => err ? reject(err) : resolve15());
|
|
61208
59978
|
});
|
|
61209
59979
|
this.server = null;
|
|
61210
59980
|
}
|
|
@@ -61315,7 +60085,7 @@ var init_a2a_frontend = __esm({
|
|
|
61315
60085
|
const response = await this.handleFollowUpMessage(existingTaskId, body);
|
|
61316
60086
|
return sendJson(res, 200, response);
|
|
61317
60087
|
}
|
|
61318
|
-
const contextId = body.message.context_id ??
|
|
60088
|
+
const contextId = body.message.context_id ?? import_crypto9.default.randomUUID();
|
|
61319
60089
|
const workflowId = resolveWorkflow(body, this.config);
|
|
61320
60090
|
const blocking = body.configuration?.blocking ?? false;
|
|
61321
60091
|
await withActiveSpan(
|
|
@@ -61428,7 +60198,7 @@ var init_a2a_frontend = __esm({
|
|
|
61428
60198
|
if (!body.message?.parts?.length) {
|
|
61429
60199
|
throw new InvalidRequestError("Message must contain at least one part");
|
|
61430
60200
|
}
|
|
61431
|
-
const contextId = body.message.context_id ??
|
|
60201
|
+
const contextId = body.message.context_id ?? import_crypto9.default.randomUUID();
|
|
61432
60202
|
const workflowId = resolveWorkflow(body, this.config);
|
|
61433
60203
|
const task = this.taskStore.createTask({
|
|
61434
60204
|
contextId,
|
|
@@ -61562,7 +60332,7 @@ var init_a2a_frontend = __esm({
|
|
|
61562
60332
|
await this.executeTaskViaEngine(task, message);
|
|
61563
60333
|
} else {
|
|
61564
60334
|
const agentResponse = {
|
|
61565
|
-
message_id:
|
|
60335
|
+
message_id: import_crypto9.default.randomUUID(),
|
|
61566
60336
|
role: "agent",
|
|
61567
60337
|
parts: [{ text: `Task ${task.id} received and processed.`, media_type: "text/markdown" }]
|
|
61568
60338
|
};
|
|
@@ -61574,7 +60344,7 @@ var init_a2a_frontend = __esm({
|
|
|
61574
60344
|
logger.error(`[A2A] Task ${task.id} execution failed: ${errorMsg}`);
|
|
61575
60345
|
try {
|
|
61576
60346
|
const failMessage = {
|
|
61577
|
-
message_id:
|
|
60347
|
+
message_id: import_crypto9.default.randomUUID(),
|
|
61578
60348
|
role: "agent",
|
|
61579
60349
|
parts: [{ text: errorMsg }]
|
|
61580
60350
|
};
|
|
@@ -61617,7 +60387,7 @@ ${issueText}`, media_type: "text/markdown" });
|
|
|
61617
60387
|
}
|
|
61618
60388
|
if (summaryParts.length > 0) {
|
|
61619
60389
|
artifacts.push({
|
|
61620
|
-
artifact_id:
|
|
60390
|
+
artifact_id: import_crypto9.default.randomUUID(),
|
|
61621
60391
|
name: "review-summary",
|
|
61622
60392
|
description: "Review summary with issues found",
|
|
61623
60393
|
parts: summaryParts
|
|
@@ -61637,7 +60407,7 @@ ${issueText}`, media_type: "text/markdown" });
|
|
|
61637
60407
|
}
|
|
61638
60408
|
if (parts.length > 0) {
|
|
61639
60409
|
artifacts.push({
|
|
61640
|
-
artifact_id:
|
|
60410
|
+
artifact_id: import_crypto9.default.randomUUID(),
|
|
61641
60411
|
name: cr.checkName ?? groupName,
|
|
61642
60412
|
description: `Output from check: ${cr.checkName ?? groupName}`,
|
|
61643
60413
|
parts
|
|
@@ -61648,7 +60418,7 @@ ${issueText}`, media_type: "text/markdown" });
|
|
|
61648
60418
|
}
|
|
61649
60419
|
if (artifacts.length === 0) {
|
|
61650
60420
|
artifacts.push({
|
|
61651
|
-
artifact_id:
|
|
60421
|
+
artifact_id: import_crypto9.default.randomUUID(),
|
|
61652
60422
|
name: "result",
|
|
61653
60423
|
description: "Execution result",
|
|
61654
60424
|
parts: [
|
|
@@ -61670,7 +60440,7 @@ ${issueText}`, media_type: "text/markdown" });
|
|
|
61670
60440
|
);
|
|
61671
60441
|
}
|
|
61672
60442
|
const agentResponse = {
|
|
61673
|
-
message_id:
|
|
60443
|
+
message_id: import_crypto9.default.randomUUID(),
|
|
61674
60444
|
role: "agent",
|
|
61675
60445
|
parts: [
|
|
61676
60446
|
{
|
|
@@ -61723,7 +60493,7 @@ ${issueText}`, media_type: "text/markdown" });
|
|
|
61723
60493
|
}
|
|
61724
60494
|
if (parts.length === 0) return null;
|
|
61725
60495
|
return {
|
|
61726
|
-
artifact_id:
|
|
60496
|
+
artifact_id: import_crypto9.default.randomUUID(),
|
|
61727
60497
|
name: p.checkId ?? "check-result",
|
|
61728
60498
|
parts
|
|
61729
60499
|
};
|
|
@@ -61909,15 +60679,15 @@ function serializeRunState(state) {
|
|
|
61909
60679
|
])
|
|
61910
60680
|
};
|
|
61911
60681
|
}
|
|
61912
|
-
var
|
|
60682
|
+
var path28, fs24, StateMachineExecutionEngine;
|
|
61913
60683
|
var init_state_machine_execution_engine = __esm({
|
|
61914
60684
|
"src/state-machine-execution-engine.ts"() {
|
|
61915
60685
|
"use strict";
|
|
61916
60686
|
init_runner();
|
|
61917
60687
|
init_logger();
|
|
61918
60688
|
init_sandbox_manager();
|
|
61919
|
-
|
|
61920
|
-
|
|
60689
|
+
path28 = __toESM(require("path"));
|
|
60690
|
+
fs24 = __toESM(require("fs"));
|
|
61921
60691
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
61922
60692
|
workingDirectory;
|
|
61923
60693
|
executionContext;
|
|
@@ -62149,8 +60919,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
62149
60919
|
logger.debug(
|
|
62150
60920
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
62151
60921
|
);
|
|
62152
|
-
const { loadEnterprisePolicyEngine
|
|
62153
|
-
context2.policyEngine = await
|
|
60922
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
60923
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
62154
60924
|
logger.debug(
|
|
62155
60925
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
62156
60926
|
);
|
|
@@ -62304,9 +61074,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
62304
61074
|
}
|
|
62305
61075
|
const checkId = String(ev?.checkId || "unknown");
|
|
62306
61076
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
62307
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
62308
|
-
|
|
62309
|
-
const filePath =
|
|
61077
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path28.resolve(process.cwd(), ".visor", "snapshots");
|
|
61078
|
+
fs24.mkdirSync(baseDir, { recursive: true });
|
|
61079
|
+
const filePath = path28.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
62310
61080
|
await this.saveSnapshotToFile(filePath);
|
|
62311
61081
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
62312
61082
|
try {
|
|
@@ -62447,7 +61217,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
62447
61217
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
62448
61218
|
*/
|
|
62449
61219
|
async saveSnapshotToFile(filePath) {
|
|
62450
|
-
const
|
|
61220
|
+
const fs25 = await import("fs/promises");
|
|
62451
61221
|
const ctx = this._lastContext;
|
|
62452
61222
|
const runner = this._lastRunner;
|
|
62453
61223
|
if (!ctx || !runner) {
|
|
@@ -62467,14 +61237,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
62467
61237
|
journal: entries,
|
|
62468
61238
|
requestedChecks: ctx.requestedChecks || []
|
|
62469
61239
|
};
|
|
62470
|
-
await
|
|
61240
|
+
await fs25.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
62471
61241
|
}
|
|
62472
61242
|
/**
|
|
62473
61243
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
62474
61244
|
*/
|
|
62475
61245
|
async loadSnapshotFromFile(filePath) {
|
|
62476
|
-
const
|
|
62477
|
-
const raw = await
|
|
61246
|
+
const fs25 = await import("fs/promises");
|
|
61247
|
+
const raw = await fs25.readFile(filePath, "utf8");
|
|
62478
61248
|
return JSON.parse(raw);
|
|
62479
61249
|
}
|
|
62480
61250
|
/**
|