@probelabs/visor 0.1.129 → 0.1.130
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/README.md +23 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/docs/author-permissions.md +20 -0
- package/dist/docs/enterprise-policy.md +1325 -0
- package/dist/docs/index.md +10 -0
- package/dist/docs/scheduler-storage.md +433 -0
- package/dist/docs/scheduler.md +12 -2
- package/dist/enterprise/license/validator.d.ts +39 -0
- package/dist/enterprise/license/validator.d.ts.map +1 -0
- package/dist/enterprise/loader.d.ts +25 -0
- package/dist/enterprise/loader.d.ts.map +1 -0
- package/dist/enterprise/policy/opa-compiler.d.ts +37 -0
- package/dist/enterprise/policy/opa-compiler.d.ts.map +1 -0
- package/dist/enterprise/policy/opa-http-evaluator.d.ts +36 -0
- package/dist/enterprise/policy/opa-http-evaluator.d.ts.map +1 -0
- package/dist/enterprise/policy/opa-policy-engine.d.ts +48 -0
- package/dist/enterprise/policy/opa-policy-engine.d.ts.map +1 -0
- package/dist/enterprise/policy/opa-wasm-evaluator.d.ts +34 -0
- package/dist/enterprise/policy/opa-wasm-evaluator.d.ts.map +1 -0
- package/dist/enterprise/policy/policy-input-builder.d.ts +120 -0
- package/dist/enterprise/policy/policy-input-builder.d.ts.map +1 -0
- package/dist/enterprise/scheduler/knex-store.d.ts +41 -0
- package/dist/enterprise/scheduler/knex-store.d.ts.map +1 -0
- package/dist/examples/README.md +23 -0
- package/dist/examples/enterprise-policy/README.md +344 -0
- package/dist/examples/enterprise-policy/policies/capability_resolve.rego +29 -0
- package/dist/examples/enterprise-policy/policies/capability_resolve_test.rego +230 -0
- package/dist/examples/enterprise-policy/policies/check_execute.rego +71 -0
- package/dist/examples/enterprise-policy/policies/check_execute_test.rego +321 -0
- package/dist/examples/enterprise-policy/policies/deploy_production.rego +33 -0
- package/dist/examples/enterprise-policy/policies/deploy_production_test.rego +29 -0
- package/dist/examples/enterprise-policy/policies/slack_channel_gate.rego +17 -0
- package/dist/examples/enterprise-policy/policies/slack_tool_restrict.rego +16 -0
- package/dist/examples/enterprise-policy/policies/tool_invoke.rego +24 -0
- package/dist/examples/enterprise-policy/policies/tool_invoke_test.rego +227 -0
- package/dist/examples/enterprise-policy/visor.yaml +64 -0
- package/dist/failure-condition-evaluator.d.ts +18 -0
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/frontends/slack-frontend.d.ts +1 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +139 -0
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/index.js +12121 -7169
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/output/traces/{run-2026-02-08T18-16-04-160Z.ndjson → run-2026-02-11T16-20-59-999Z.ndjson} +84 -84
- package/dist/{traces/run-2026-02-08T18-16-51-253Z.ndjson → output/traces/run-2026-02-11T16-21-47-711Z.ndjson} +1032 -1032
- package/dist/policy/default-engine.d.ts +17 -0
- package/dist/policy/default-engine.d.ts.map +1 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/policy-check-command.d.ts +65 -0
- package/dist/policy/policy-check-command.d.ts.map +1 -0
- package/dist/policy/types.d.ts +81 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +2 -0
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +2 -0
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/schedule-store.d.ts +33 -59
- package/dist/scheduler/schedule-store.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/scheduler/scheduler.d.ts +24 -3
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/scheduler/store/index.d.ts +7 -0
- package/dist/scheduler/store/index.d.ts.map +1 -0
- package/dist/scheduler/store/json-migrator.d.ts +10 -0
- package/dist/scheduler/store/json-migrator.d.ts.map +1 -0
- package/dist/scheduler/store/sqlite-store.d.ts +32 -0
- package/dist/scheduler/store/sqlite-store.d.ts.map +1 -0
- package/dist/scheduler/store/types.d.ts +127 -0
- package/dist/scheduler/store/types.d.ts.map +1 -0
- package/dist/sdk/check-provider-registry-M3Y6JMTW.mjs +28 -0
- package/dist/sdk/check-provider-registry-PANIXYRB.mjs +28 -0
- package/dist/sdk/{chunk-D5KI4YQ4.mjs → chunk-DIND4ZCV.mjs} +2 -2
- package/dist/sdk/{chunk-DGZPPGJJ.mjs → chunk-EUUAQBTW.mjs} +1463 -568
- package/dist/sdk/chunk-EUUAQBTW.mjs.map +1 -0
- package/dist/sdk/{chunk-XDLQ3UNF.mjs → chunk-GEW6LS32.mjs} +2 -2
- package/dist/sdk/{chunk-N7HO6KKC.mjs → chunk-HOKQOO3G.mjs} +11 -6
- package/dist/sdk/chunk-HOKQOO3G.mjs.map +1 -0
- package/dist/sdk/{chunk-XR7XXGL7.mjs → chunk-JL7JXCET.mjs} +2 -2
- package/dist/sdk/{chunk-6W75IMDC.mjs → chunk-LG4AUKHB.mjs} +2 -2
- package/dist/sdk/{chunk-BDGUM6BA.mjs → chunk-S6CD7GFM.mjs} +1463 -568
- package/dist/sdk/chunk-S6CD7GFM.mjs.map +1 -0
- package/dist/sdk/{chunk-PO7X5XI7.mjs → chunk-SZXICFQ3.mjs} +2 -2
- package/dist/sdk/{chunk-HEX3RL32.mjs → chunk-UCMJJ3IM.mjs} +5 -2
- package/dist/sdk/{chunk-HEX3RL32.mjs.map → chunk-UCMJJ3IM.mjs.map} +1 -1
- package/dist/sdk/{chunk-7YSOINAQ.mjs → chunk-UCNT3PDT.mjs} +342 -5
- package/dist/sdk/chunk-UCNT3PDT.mjs.map +1 -0
- package/dist/sdk/{chunk-R5Z7YWPB.mjs → chunk-V2IV3ILA.mjs} +7 -5
- package/dist/sdk/chunk-V2IV3ILA.mjs.map +1 -0
- package/dist/sdk/{chunk-SGS2VMEL.mjs → chunk-VMLORODQ.mjs} +107 -20
- package/dist/sdk/chunk-VMLORODQ.mjs.map +1 -0
- package/dist/sdk/{chunk-2KB35MB7.mjs → chunk-VPC3QSPW.mjs} +2 -2
- package/dist/sdk/{chunk-J5RGJQ53.mjs → chunk-YJRBN3XS.mjs} +2 -2
- package/dist/sdk/{command-executor-DVVXERLR.mjs → command-executor-TOYBBE7S.mjs} +4 -4
- package/dist/sdk/{config-7VTT64SQ.mjs → config-OGOS4ZU4.mjs} +4 -4
- package/dist/sdk/failure-condition-evaluator-HC3M5377.mjs +17 -0
- package/dist/sdk/{github-frontend-3N2NLO66.mjs → github-frontend-E2KJSC3Y.mjs} +7 -7
- package/dist/sdk/{host-ONVMEHAA.mjs → host-EE6EJ2FM.mjs} +4 -4
- package/dist/sdk/lazy-otel-5NH4ZJJM.mjs +24 -0
- package/dist/sdk/{liquid-extensions-5IZLTFSZ.mjs → liquid-extensions-E4EUOCES.mjs} +5 -5
- package/dist/sdk/memory-store-AAPL2MTE.mjs +12 -0
- package/dist/sdk/{metrics-GXQ2EDXA.mjs → metrics-I6A7IHG4.mjs} +3 -3
- package/dist/sdk/{prompt-state-YHGXB2OA.mjs → prompt-state-VAKKC773.mjs} +4 -4
- package/dist/sdk/{renderer-schema-CMXOLNIG.mjs → renderer-schema-HXEW6BRJ.mjs} +3 -3
- package/dist/sdk/{routing-S3Y7T2X3.mjs → routing-OZQWAGAI.mjs} +9 -8
- package/dist/sdk/schedule-tool-handler-B7TMSG6A.mjs +38 -0
- package/dist/sdk/schedule-tool-handler-IEB2VS7O.mjs +38 -0
- package/dist/sdk/sdk.d.mts +134 -4
- package/dist/sdk/sdk.d.ts +134 -4
- package/dist/sdk/sdk.js +2509 -1085
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +14 -14
- package/dist/sdk/{slack-frontend-R3M2CACB.mjs → slack-frontend-LAY45IBR.mjs} +119 -29
- package/dist/sdk/slack-frontend-LAY45IBR.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-YHNPC7MR.mjs → trace-helpers-PP3YHTAM.mjs} +3 -3
- package/dist/sdk/{tui-frontend-S546M7A7.mjs → tui-frontend-T56PZB67.mjs} +25 -16
- package/dist/sdk/tui-frontend-T56PZB67.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-2ET3SFZH.mjs +28 -0
- package/dist/sdk/workflow-check-provider-2ET3SFZH.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-HB4XTD4Z.mjs +28 -0
- package/dist/sdk/workflow-check-provider-HB4XTD4Z.mjs.map +1 -0
- package/dist/sdk/workflow-registry-AAD37XKZ.mjs +12 -0
- package/dist/sdk/workflow-registry-AAD37XKZ.mjs.map +1 -0
- package/dist/slack/client.d.ts +12 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/slack-output-adapter.d.ts.map +1 -1
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/policy-gate.d.ts +28 -0
- package/dist/state-machine/dispatch/policy-gate.d.ts.map +1 -0
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/state-machine/states/routing.d.ts.map +1 -1
- package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
- package/dist/state-machine-execution-engine.d.ts.map +1 -1
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/traces/{run-2026-02-08T18-16-04-160Z.ndjson → run-2026-02-11T16-20-59-999Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-02-08T18-16-51-253Z.ndjson → traces/run-2026-02-11T16-21-47-711Z.ndjson} +1032 -1032
- package/dist/tui/chat-runner.d.ts.map +1 -1
- package/dist/tui/chat-state.d.ts +1 -0
- package/dist/tui/chat-state.d.ts.map +1 -1
- package/dist/tui/chat-tui.d.ts +3 -2
- package/dist/tui/chat-tui.d.ts.map +1 -1
- package/dist/tui/components/chat-box.d.ts +9 -0
- package/dist/tui/components/chat-box.d.ts.map +1 -1
- package/dist/tui/components/input-bar.d.ts +18 -1
- package/dist/tui/components/input-bar.d.ts.map +1 -1
- package/dist/tui/components/status-bar.d.ts +5 -2
- package/dist/tui/components/status-bar.d.ts.map +1 -1
- package/dist/tui/components/trace-viewer.d.ts +1 -0
- package/dist/tui/components/trace-viewer.d.ts.map +1 -1
- package/dist/tui/tui-frontend.d.ts.map +1 -1
- package/dist/types/config.d.ts +107 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +5 -0
- package/dist/types/engine.d.ts.map +1 -1
- package/dist/types/execution.d.ts +1 -1
- package/dist/types/execution.d.ts.map +1 -1
- package/package.json +14 -4
- package/dist/sdk/check-provider-registry-ACRGIYOB.mjs +0 -28
- package/dist/sdk/check-provider-registry-VYHKFHK2.mjs +0 -28
- package/dist/sdk/chunk-7YSOINAQ.mjs.map +0 -1
- package/dist/sdk/chunk-BDGUM6BA.mjs.map +0 -1
- package/dist/sdk/chunk-DGZPPGJJ.mjs.map +0 -1
- package/dist/sdk/chunk-N7HO6KKC.mjs.map +0 -1
- package/dist/sdk/chunk-R5Z7YWPB.mjs.map +0 -1
- package/dist/sdk/chunk-SGS2VMEL.mjs.map +0 -1
- package/dist/sdk/failure-condition-evaluator-4WMDF4Q3.mjs +0 -17
- package/dist/sdk/memory-store-3N4AZCYB.mjs +0 -12
- package/dist/sdk/slack-frontend-R3M2CACB.mjs.map +0 -1
- package/dist/sdk/tui-frontend-S546M7A7.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-4F3432ZP.mjs +0 -28
- package/dist/sdk/workflow-check-provider-A44PBPG2.mjs +0 -28
- package/dist/sdk/workflow-registry-ZAYYXLEP.mjs +0 -12
- /package/dist/sdk/{check-provider-registry-ACRGIYOB.mjs.map → check-provider-registry-M3Y6JMTW.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-VYHKFHK2.mjs.map → check-provider-registry-PANIXYRB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-D5KI4YQ4.mjs.map → chunk-DIND4ZCV.mjs.map} +0 -0
- /package/dist/sdk/{chunk-XDLQ3UNF.mjs.map → chunk-GEW6LS32.mjs.map} +0 -0
- /package/dist/sdk/{chunk-XR7XXGL7.mjs.map → chunk-JL7JXCET.mjs.map} +0 -0
- /package/dist/sdk/{chunk-6W75IMDC.mjs.map → chunk-LG4AUKHB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-PO7X5XI7.mjs.map → chunk-SZXICFQ3.mjs.map} +0 -0
- /package/dist/sdk/{chunk-2KB35MB7.mjs.map → chunk-VPC3QSPW.mjs.map} +0 -0
- /package/dist/sdk/{chunk-J5RGJQ53.mjs.map → chunk-YJRBN3XS.mjs.map} +0 -0
- /package/dist/sdk/{command-executor-DVVXERLR.mjs.map → command-executor-TOYBBE7S.mjs.map} +0 -0
- /package/dist/sdk/{config-7VTT64SQ.mjs.map → config-OGOS4ZU4.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-4WMDF4Q3.mjs.map → failure-condition-evaluator-HC3M5377.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-3N2NLO66.mjs.map → github-frontend-E2KJSC3Y.mjs.map} +0 -0
- /package/dist/sdk/{host-ONVMEHAA.mjs.map → host-EE6EJ2FM.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-5IZLTFSZ.mjs.map → lazy-otel-5NH4ZJJM.mjs.map} +0 -0
- /package/dist/sdk/{memory-store-3N4AZCYB.mjs.map → liquid-extensions-E4EUOCES.mjs.map} +0 -0
- /package/dist/sdk/{metrics-GXQ2EDXA.mjs.map → memory-store-AAPL2MTE.mjs.map} +0 -0
- /package/dist/sdk/{prompt-state-YHGXB2OA.mjs.map → metrics-I6A7IHG4.mjs.map} +0 -0
- /package/dist/sdk/{routing-S3Y7T2X3.mjs.map → prompt-state-VAKKC773.mjs.map} +0 -0
- /package/dist/sdk/{renderer-schema-CMXOLNIG.mjs.map → renderer-schema-HXEW6BRJ.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-YHNPC7MR.mjs.map → routing-OZQWAGAI.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-4F3432ZP.mjs.map → schedule-tool-handler-B7TMSG6A.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-A44PBPG2.mjs.map → schedule-tool-handler-IEB2VS7O.mjs.map} +0 -0
- /package/dist/sdk/{workflow-registry-ZAYYXLEP.mjs.map → trace-helpers-PP3YHTAM.mjs.map} +0 -0
package/dist/sdk/sdk.mjs
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StateMachineExecutionEngine,
|
|
3
3
|
init_state_machine_execution_engine
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EUUAQBTW.mjs";
|
|
5
|
+
import "./chunk-LG4AUKHB.mjs";
|
|
5
6
|
import "./chunk-KFKHU6CM.mjs";
|
|
7
|
+
import "./chunk-B7BVQM5K.mjs";
|
|
6
8
|
import "./chunk-XXAEN5KU.mjs";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-GEW6LS32.mjs";
|
|
10
|
+
import "./chunk-DIND4ZCV.mjs";
|
|
9
11
|
import {
|
|
10
12
|
ConfigManager,
|
|
11
13
|
init_config
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UCNT3PDT.mjs";
|
|
13
15
|
import "./chunk-NCWIZVOT.mjs";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-R5Z7YWPB.mjs";
|
|
16
|
+
import "./chunk-VMLORODQ.mjs";
|
|
17
|
+
import "./chunk-HOKQOO3G.mjs";
|
|
18
|
+
import "./chunk-YJRBN3XS.mjs";
|
|
19
|
+
import "./chunk-JL7JXCET.mjs";
|
|
20
|
+
import "./chunk-V2IV3ILA.mjs";
|
|
20
21
|
import "./chunk-25IC7KXZ.mjs";
|
|
21
22
|
import "./chunk-VF6XIUE4.mjs";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-B7BVQM5K.mjs";
|
|
23
|
+
import "./chunk-VPC3QSPW.mjs";
|
|
24
|
+
import "./chunk-SZXICFQ3.mjs";
|
|
25
|
+
import "./chunk-UCMJJ3IM.mjs";
|
|
26
26
|
import "./chunk-J7LXIPZS.mjs";
|
|
27
27
|
|
|
28
28
|
// src/sdk.ts
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
context,
|
|
3
3
|
init_lazy_otel,
|
|
4
4
|
trace
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UCMJJ3IM.mjs";
|
|
6
6
|
import {
|
|
7
7
|
__esm
|
|
8
8
|
} from "./chunk-J7LXIPZS.mjs";
|
|
@@ -54,30 +54,65 @@ var init_client = __esm({
|
|
|
54
54
|
text,
|
|
55
55
|
thread_ts
|
|
56
56
|
}) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
try {
|
|
58
|
+
const resp = await this.api("chat.postMessage", { channel, text, thread_ts });
|
|
59
|
+
if (!resp || resp.ok !== true) {
|
|
60
|
+
const err = resp && resp.error || "unknown_error";
|
|
61
|
+
const warnings = Array.isArray(resp?.response_metadata?.warnings) ? resp.response_metadata.warnings.join(",") : "";
|
|
62
|
+
console.warn(
|
|
63
|
+
`Slack chat.postMessage failed (non-fatal): error=${err} channel=${channel} thread_ts=${thread_ts || "-"} text_len=${text.length}${warnings ? ` warnings=${warnings}` : ""}`
|
|
64
|
+
);
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
ts: void 0,
|
|
68
|
+
message: void 0,
|
|
69
|
+
data: resp,
|
|
70
|
+
error: err
|
|
71
|
+
};
|
|
72
|
+
}
|
|
61
73
|
return {
|
|
74
|
+
ok: true,
|
|
75
|
+
ts: resp.ts || resp.message && resp.message.ts || void 0,
|
|
76
|
+
message: resp.message,
|
|
77
|
+
data: resp,
|
|
78
|
+
error: void 0
|
|
79
|
+
};
|
|
80
|
+
} catch (e) {
|
|
81
|
+
console.warn(
|
|
82
|
+
`Slack chat.postMessage threw (non-fatal): channel=${channel} thread_ts=${thread_ts || "-"} text_len=${text.length} error=${e instanceof Error ? e.message : String(e)}`
|
|
83
|
+
);
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
62
86
|
ts: void 0,
|
|
63
87
|
message: void 0,
|
|
64
|
-
data:
|
|
88
|
+
data: void 0,
|
|
89
|
+
error: e instanceof Error ? e.message : String(e)
|
|
65
90
|
};
|
|
66
91
|
}
|
|
67
|
-
return {
|
|
68
|
-
ts: resp.ts || resp.message && resp.message.ts || void 0,
|
|
69
|
-
message: resp.message,
|
|
70
|
-
data: resp
|
|
71
|
-
};
|
|
72
92
|
},
|
|
73
93
|
update: async ({ channel, ts, text }) => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
try {
|
|
95
|
+
const resp = await this.api("chat.update", { channel, ts, text });
|
|
96
|
+
if (!resp || resp.ok !== true) {
|
|
97
|
+
const err = resp && resp.error || "unknown_error";
|
|
98
|
+
const warnings = Array.isArray(resp?.response_metadata?.warnings) ? resp.response_metadata.warnings.join(",") : "";
|
|
99
|
+
console.warn(
|
|
100
|
+
`Slack chat.update failed (non-fatal): error=${err} channel=${channel} ts=${ts} text_len=${text.length}${warnings ? ` warnings=${warnings}` : ""}`
|
|
101
|
+
);
|
|
102
|
+
return { ok: false, ts, error: err, data: resp };
|
|
103
|
+
}
|
|
104
|
+
return { ok: true, ts: resp.ts || ts, error: void 0, data: resp };
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.warn(
|
|
107
|
+
`Slack chat.update threw (non-fatal): channel=${channel} ts=${ts} text_len=${text.length} error=${e instanceof Error ? e.message : String(e)}`
|
|
108
|
+
);
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
ts,
|
|
112
|
+
error: e instanceof Error ? e.message : String(e),
|
|
113
|
+
data: void 0
|
|
114
|
+
};
|
|
79
115
|
}
|
|
80
|
-
return { ok: true, ts: resp.ts || ts };
|
|
81
116
|
}
|
|
82
117
|
};
|
|
83
118
|
async getBotUserId() {
|
|
@@ -441,11 +476,21 @@ var init_slack_frontend = __esm({
|
|
|
441
476
|
ackName = "eyes";
|
|
442
477
|
doneName = "thumbsup";
|
|
443
478
|
errorNotified = false;
|
|
479
|
+
cachedTraceInfo = null;
|
|
444
480
|
constructor(config) {
|
|
445
481
|
this.cfg = config || {};
|
|
446
482
|
}
|
|
447
483
|
start(ctx) {
|
|
448
484
|
const bus = ctx.eventBus;
|
|
485
|
+
if (!this.cachedTraceInfo) {
|
|
486
|
+
this.cachedTraceInfo = this.getTraceInfo();
|
|
487
|
+
}
|
|
488
|
+
if (!this.cachedTraceInfo) {
|
|
489
|
+
const runTraceId = ctx?.run?.traceId;
|
|
490
|
+
if (typeof runTraceId === "string" && runTraceId) {
|
|
491
|
+
this.cachedTraceInfo = { traceId: runTraceId, spanId: "" };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
449
494
|
try {
|
|
450
495
|
const hasClient = !!(ctx.slack || ctx.slackClient || this.cfg?.botToken || process.env.SLACK_BOT_TOKEN);
|
|
451
496
|
ctx.logger.info(`[slack-frontend] started; hasClient=${hasClient} defaultChannel=unset`);
|
|
@@ -524,7 +569,7 @@ var init_slack_frontend = __esm({
|
|
|
524
569
|
}
|
|
525
570
|
}
|
|
526
571
|
if (!channel || !threadTs) return;
|
|
527
|
-
const { getPromptStateManager } = await import("./prompt-state-
|
|
572
|
+
const { getPromptStateManager } = await import("./prompt-state-VAKKC773.mjs");
|
|
528
573
|
const mgr = getPromptStateManager();
|
|
529
574
|
const prev = mgr.getWaiting(channel, threadTs);
|
|
530
575
|
const text = String(ev.prompt);
|
|
@@ -558,7 +603,7 @@ var init_slack_frontend = __esm({
|
|
|
558
603
|
const threadTs = String(ev?.threadTs || "");
|
|
559
604
|
const filePath = String(ev?.filePath || "");
|
|
560
605
|
if (!channel || !threadTs || !filePath) return;
|
|
561
|
-
const { getPromptStateManager } = await import("./prompt-state-
|
|
606
|
+
const { getPromptStateManager } = await import("./prompt-state-VAKKC773.mjs");
|
|
562
607
|
const mgr = getPromptStateManager();
|
|
563
608
|
mgr.update(channel, threadTs, { snapshotPath: filePath });
|
|
564
609
|
try {
|
|
@@ -628,14 +673,22 @@ var init_slack_frontend = __esm({
|
|
|
628
673
|
const ev = payload?.event;
|
|
629
674
|
const channel = String(ev?.channel || "");
|
|
630
675
|
const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || "");
|
|
631
|
-
if (!channel || !threadTs)
|
|
676
|
+
if (!channel || !threadTs) {
|
|
677
|
+
try {
|
|
678
|
+
ctx.logger.warn(
|
|
679
|
+
`[slack-frontend] skip posting error notice: missing channel/thread (channel=${channel || "-"} thread=${threadTs || "-"})`
|
|
680
|
+
);
|
|
681
|
+
} catch {
|
|
682
|
+
}
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
632
685
|
let text = `\u274C ${title}`;
|
|
633
686
|
if (checkId) text += `
|
|
634
687
|
Check: ${checkId}`;
|
|
635
688
|
if (message) text += `
|
|
636
689
|
${message}`;
|
|
637
690
|
if (this.isTelemetryEnabled(ctx)) {
|
|
638
|
-
const traceInfo = this.getTraceInfo();
|
|
691
|
+
const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;
|
|
639
692
|
if (traceInfo?.traceId) {
|
|
640
693
|
text += `
|
|
641
694
|
|
|
@@ -643,7 +696,20 @@ ${message}`;
|
|
|
643
696
|
}
|
|
644
697
|
}
|
|
645
698
|
const formattedText = formatSlackText(text);
|
|
646
|
-
await slack.chat.postMessage({
|
|
699
|
+
const postResult = await slack.chat.postMessage({
|
|
700
|
+
channel,
|
|
701
|
+
text: formattedText,
|
|
702
|
+
thread_ts: threadTs
|
|
703
|
+
});
|
|
704
|
+
if (!postResult?.ok) {
|
|
705
|
+
try {
|
|
706
|
+
ctx.logger.warn(
|
|
707
|
+
`[slack-frontend] failed to post error notice to ${channel} thread=${threadTs} check=${checkId || "run"} error=${postResult?.error || "unknown_error"}`
|
|
708
|
+
);
|
|
709
|
+
} catch {
|
|
710
|
+
}
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
647
713
|
try {
|
|
648
714
|
ctx.logger.info(
|
|
649
715
|
`[slack-frontend] posted error notice to ${channel} thread=${threadTs} check=${checkId || "run"}`
|
|
@@ -711,6 +777,9 @@ ${message}`;
|
|
|
711
777
|
}
|
|
712
778
|
this.acked = true;
|
|
713
779
|
this.ackRef = ref;
|
|
780
|
+
if (!this.cachedTraceInfo) {
|
|
781
|
+
this.cachedTraceInfo = this.getTraceInfo();
|
|
782
|
+
}
|
|
714
783
|
}
|
|
715
784
|
async finalizeReactions(ctx) {
|
|
716
785
|
if (!this.acked || !this.ackRef) return;
|
|
@@ -757,7 +826,8 @@ ${message}`;
|
|
|
757
826
|
const providerType = checkCfg.type || "";
|
|
758
827
|
const isAi = providerType === "ai";
|
|
759
828
|
const isLogChat = providerType === "log" && checkCfg.group === "chat";
|
|
760
|
-
|
|
829
|
+
const isWorkflow = providerType === "workflow";
|
|
830
|
+
if (!isAi && !isLogChat && !isWorkflow) return;
|
|
761
831
|
if (checkCfg.criticality === "internal") return;
|
|
762
832
|
if (isAi) {
|
|
763
833
|
const schema = checkCfg.schema;
|
|
@@ -772,7 +842,12 @@ ${message}`;
|
|
|
772
842
|
const ev = payload?.event;
|
|
773
843
|
const channel = String(ev?.channel || "");
|
|
774
844
|
const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || "");
|
|
775
|
-
if (!channel || !threadTs)
|
|
845
|
+
if (!channel || !threadTs) {
|
|
846
|
+
ctx.logger.warn(
|
|
847
|
+
`[slack-frontend] skip posting AI reply for ${checkId}: missing channel/thread (channel=${channel || "-"} thread=${threadTs || "-"})`
|
|
848
|
+
);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
776
851
|
const out = result?.output;
|
|
777
852
|
let text;
|
|
778
853
|
if (out && typeof out.text === "string" && out.text.trim().length > 0) {
|
|
@@ -793,7 +868,12 @@ ${message}`;
|
|
|
793
868
|
text = String(out);
|
|
794
869
|
}
|
|
795
870
|
}
|
|
796
|
-
if (!text)
|
|
871
|
+
if (!text) {
|
|
872
|
+
ctx.logger.info(
|
|
873
|
+
`[slack-frontend] skip posting AI reply for ${checkId}: no renderable text in check output`
|
|
874
|
+
);
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
797
877
|
const diagrams = extractMermaidDiagrams(text);
|
|
798
878
|
let processedText = text;
|
|
799
879
|
if (diagrams.length > 0) {
|
|
@@ -849,7 +929,7 @@ ${message}`;
|
|
|
849
929
|
let decoratedText = processedText;
|
|
850
930
|
const telemetryEnabled = telemetryCfg === true || telemetryCfg && typeof telemetryCfg === "object" && telemetryCfg.enabled === true;
|
|
851
931
|
if (telemetryEnabled) {
|
|
852
|
-
const traceInfo = this.getTraceInfo();
|
|
932
|
+
const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;
|
|
853
933
|
if (traceInfo?.traceId) {
|
|
854
934
|
const suffix = `\`trace_id: ${traceInfo.traceId}\``;
|
|
855
935
|
decoratedText = `${decoratedText}
|
|
@@ -858,9 +938,19 @@ ${suffix}`;
|
|
|
858
938
|
}
|
|
859
939
|
}
|
|
860
940
|
const formattedText = formatSlackText(decoratedText);
|
|
861
|
-
await slack.chat.postMessage({
|
|
941
|
+
const postResult = await slack.chat.postMessage({
|
|
942
|
+
channel,
|
|
943
|
+
text: formattedText,
|
|
944
|
+
thread_ts: threadTs
|
|
945
|
+
});
|
|
946
|
+
if (!postResult?.ok) {
|
|
947
|
+
ctx.logger.warn(
|
|
948
|
+
`[slack-frontend] failed to post AI reply for ${checkId} to ${channel} thread=${threadTs} error=${postResult?.error || "unknown_error"}`
|
|
949
|
+
);
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
862
952
|
ctx.logger.info(
|
|
863
|
-
`[slack-frontend] posted AI reply for ${checkId} to ${channel} thread=${threadTs}`
|
|
953
|
+
`[slack-frontend] posted AI reply for ${checkId} to ${channel} thread=${threadTs} ts=${postResult.ts || "-"}`
|
|
864
954
|
);
|
|
865
955
|
const responseCapture = ctx.responseCapture;
|
|
866
956
|
if (responseCapture && typeof responseCapture === "function") {
|
|
@@ -896,4 +986,4 @@ init_slack_frontend();
|
|
|
896
986
|
export {
|
|
897
987
|
SlackFrontend
|
|
898
988
|
};
|
|
899
|
-
//# sourceMappingURL=slack-frontend-
|
|
989
|
+
//# sourceMappingURL=slack-frontend-LAY45IBR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/slack/client.ts","../../src/slack/markdown.ts","../../src/frontends/slack-frontend.ts"],"sourcesContent":["// Lightweight Slack Web API wrapper implemented with fetch (no external deps).\n// Only methods needed by SlackFrontend are implemented.\n\nexport class SlackClient {\n private token: string;\n\n constructor(botToken: string) {\n if (!botToken || typeof botToken !== 'string') {\n throw new Error('SlackClient: botToken is required');\n }\n this.token = botToken;\n }\n\n public readonly reactions = {\n add: async ({\n channel,\n timestamp,\n name,\n }: {\n channel: string;\n timestamp: string;\n name: string;\n }) => {\n const resp: any = await this.api('reactions.add', { channel, timestamp, name });\n if (!resp || resp.ok !== true) {\n // Non-fatal in CLI/test runs – log and continue\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(`Slack reactions.add failed (non-fatal): ${err}`);\n return { ok: false as const };\n }\n return { ok: true } as const;\n },\n remove: async ({\n channel,\n timestamp,\n name,\n }: {\n channel: string;\n timestamp: string;\n name: string;\n }) => {\n const resp: any = await this.api('reactions.remove', { channel, timestamp, name });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(`Slack reactions.remove failed (non-fatal): ${err}`);\n return { ok: false as const };\n }\n return { ok: true } as const;\n },\n };\n\n public readonly chat = {\n postMessage: async ({\n channel,\n text,\n thread_ts,\n }: {\n channel: string;\n text: string;\n thread_ts?: string;\n }) => {\n try {\n const resp: any = await this.api('chat.postMessage', { channel, text, thread_ts });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n const warnings = Array.isArray(resp?.response_metadata?.warnings)\n ? resp.response_metadata.warnings.join(',')\n : '';\n console.warn(\n `Slack chat.postMessage failed (non-fatal): error=${err} channel=${channel} thread_ts=${\n thread_ts || '-'\n } text_len=${text.length}${warnings ? ` warnings=${warnings}` : ''}`\n );\n return {\n ok: false as const,\n ts: undefined,\n message: undefined,\n data: resp,\n error: err,\n };\n }\n // Normalize common fields for tests/frontend\n return {\n ok: true as const,\n ts: resp.ts || (resp.message && resp.message.ts) || undefined,\n message: resp.message,\n data: resp,\n error: undefined,\n };\n } catch (e) {\n console.warn(\n `Slack chat.postMessage threw (non-fatal): channel=${channel} thread_ts=${thread_ts || '-'} text_len=${\n text.length\n } error=${e instanceof Error ? e.message : String(e)}`\n );\n return {\n ok: false as const,\n ts: undefined,\n message: undefined,\n data: undefined,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n },\n update: async ({ channel, ts, text }: { channel: string; ts: string; text: string }) => {\n try {\n const resp: any = await this.api('chat.update', { channel, ts, text });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n const warnings = Array.isArray(resp?.response_metadata?.warnings)\n ? resp.response_metadata.warnings.join(',')\n : '';\n console.warn(\n `Slack chat.update failed (non-fatal): error=${err} channel=${channel} ts=${ts} text_len=${\n text.length\n }${warnings ? ` warnings=${warnings}` : ''}`\n );\n return { ok: false as const, ts, error: err, data: resp };\n }\n return { ok: true as const, ts: resp.ts || ts, error: undefined, data: resp };\n } catch (e) {\n console.warn(\n `Slack chat.update threw (non-fatal): channel=${channel} ts=${ts} text_len=${text.length} error=${\n e instanceof Error ? e.message : String(e)\n }`\n );\n return {\n ok: false as const,\n ts,\n error: e instanceof Error ? e.message : String(e),\n data: undefined,\n };\n }\n },\n };\n\n async getBotUserId(): Promise<string> {\n const resp: any = await this.api('auth.test', {});\n if (!resp || resp.ok !== true || !resp.user_id) {\n console.warn('Slack auth.test failed (non-fatal); bot user id unavailable');\n return 'UNKNOWN_BOT';\n }\n return String(resp.user_id);\n }\n\n /**\n * Fetch user info from Slack API.\n * Returns user profile including guest status flags, email, display name, and timezone.\n */\n async getUserInfo(userId: string): Promise<{\n ok: boolean;\n user?: {\n id: string;\n name?: string; // username\n real_name?: string; // full name\n email?: string; // requires users:read.email scope\n is_restricted?: boolean; // Multi-channel guest\n is_ultra_restricted?: boolean; // Single-channel guest\n is_bot?: boolean;\n is_app_user?: boolean;\n deleted?: boolean;\n tz?: string; // IANA timezone (e.g., \"America/New_York\")\n tz_offset?: number; // Timezone offset in seconds from UTC\n };\n }> {\n try {\n const resp: any = await this.api('users.info', { user: userId });\n if (!resp || resp.ok !== true || !resp.user) {\n return { ok: false };\n }\n return {\n ok: true,\n user: {\n id: resp.user.id,\n name: resp.user.name,\n real_name: resp.user.real_name || resp.user.profile?.real_name,\n email: resp.user.profile?.email,\n is_restricted: resp.user.is_restricted,\n is_ultra_restricted: resp.user.is_ultra_restricted,\n is_bot: resp.user.is_bot,\n is_app_user: resp.user.is_app_user,\n deleted: resp.user.deleted,\n tz: resp.user.tz,\n tz_offset: resp.user.tz_offset,\n },\n };\n } catch (e) {\n console.warn(`Slack users.info failed: ${e instanceof Error ? e.message : String(e)}`);\n return { ok: false };\n }\n }\n\n /**\n * Open a DM channel with a user.\n * Returns the DM channel ID.\n */\n async openDM(userId: string): Promise<{ ok: boolean; channel?: string }> {\n try {\n const resp: any = await this.api('conversations.open', { users: userId });\n if (!resp || resp.ok !== true || !resp.channel?.id) {\n console.warn(`Slack conversations.open failed: ${resp?.error || 'unknown_error'}`);\n return { ok: false };\n }\n return { ok: true, channel: resp.channel.id };\n } catch (e) {\n console.warn(\n `Slack conversations.open failed: ${e instanceof Error ? e.message : String(e)}`\n );\n return { ok: false };\n }\n }\n\n async fetchThreadReplies(\n channel: string,\n thread_ts: string,\n limit: number = 40\n ): Promise<\n Array<{ ts: string; user?: string; text?: string; bot_id?: string; thread_ts?: string }>\n > {\n try {\n // Use query-string GET semantics similar to Slack WebClient to avoid\n // subtle JSON/form encoding issues that can cause invalid_arguments\n const params = new URLSearchParams({\n channel,\n ts: thread_ts,\n limit: String(limit),\n });\n const res = await fetch(`https://slack.com/api/conversations.replies?${params.toString()}`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.token}`,\n },\n });\n const resp: any = await res.json();\n if (!resp || resp.ok !== true || !Array.isArray(resp.messages)) {\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(\n `Slack conversations.replies failed (non-fatal): ${err} (channel=${channel}, ts=${thread_ts}, limit=${limit})`\n );\n return [];\n }\n return resp.messages.map((m: any) => ({\n ts: String(m.ts || ''),\n user: m.user,\n text: m.text,\n bot_id: m.bot_id,\n thread_ts: m.thread_ts,\n }));\n } catch (e) {\n console.warn(\n `Slack conversations.replies failed (non-fatal): ${\n e instanceof Error ? e.message : String(e)\n } (channel=${channel}, ts=${thread_ts}, limit=${limit})`\n );\n return [];\n }\n }\n\n public readonly files = {\n /**\n * Upload a file to Slack using files.uploadV2 API\n * @param options Upload options including file content, filename, channel, and thread_ts\n */\n uploadV2: async ({\n content,\n filename,\n channel,\n thread_ts,\n title,\n initial_comment,\n }: {\n content: Buffer;\n filename: string;\n channel: string;\n thread_ts?: string;\n title?: string;\n initial_comment?: string;\n }): Promise<{ ok: boolean; file?: { id: string; permalink?: string } }> => {\n try {\n // Step 1: Get upload URL\n const getUrlResp: any = await this.api('files.getUploadURLExternal', {\n filename,\n length: content.length,\n });\n if (!getUrlResp || getUrlResp.ok !== true || !getUrlResp.upload_url) {\n console.warn(\n `Slack files.getUploadURLExternal failed: ${getUrlResp?.error || 'unknown'}`\n );\n return { ok: false };\n }\n\n // Step 2: Upload file content to the URL\n const uploadResp = await fetch(getUrlResp.upload_url, {\n method: 'POST',\n body: content,\n });\n if (!uploadResp.ok) {\n console.warn(`Slack file upload to URL failed: ${uploadResp.status}`);\n return { ok: false };\n }\n\n // Step 3: Complete the upload and share to channel\n const completeResp: any = await this.api('files.completeUploadExternal', {\n files: [{ id: getUrlResp.file_id, title: title || filename }],\n channel_id: channel,\n thread_ts,\n initial_comment,\n });\n if (!completeResp || completeResp.ok !== true) {\n console.warn(\n `Slack files.completeUploadExternal failed: ${completeResp?.error || 'unknown'}`\n );\n return { ok: false };\n }\n\n return {\n ok: true,\n file: completeResp.files?.[0] || { id: getUrlResp.file_id },\n };\n } catch (e) {\n console.warn(`Slack file upload failed: ${e instanceof Error ? e.message : String(e)}`);\n return { ok: false };\n }\n },\n };\n\n getWebClient(): any {\n return {\n conversations: {\n history: async ({ channel, limit }: { channel: string; limit?: number }) =>\n (await this.api('conversations.history', { channel, limit })) as any,\n open: async ({ users }: { users: string }) =>\n (await this.api('conversations.open', { users })) as any,\n replies: async ({ channel, ts, limit }: { channel: string; ts: string; limit?: number }) =>\n (await this.api('conversations.replies', { channel, ts, limit })) as any,\n },\n };\n }\n\n private async api(method: string, body: Record<string, unknown>): Promise<unknown> {\n // Node 18+ global fetch\n const res = await fetch(`https://slack.com/api/${method}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=utf-8',\n Authorization: `Bearer ${this.token}`,\n },\n body: JSON.stringify(body),\n });\n return (await res.json()) as unknown;\n }\n}\n","// Lightweight Markdown → Slack mrkdwn formatter.\n// The goal is to make common Markdown output from AI steps look natural in Slack\n// without pulling in a full Markdown parser.\n//\n// Supported conversions:\n// - # Header / ## Header → *Header* (bold with visual separation)\n// - **bold** / __bold__ → *bold*\n// - [label](url) → <url|label>\n// -  → <url|alt>\n// - *italic* (inline) → _italic_\n// - ```mermaid blocks → rendered to PNG and uploaded to Slack\n//\n// Everything else is passed through unchanged; Slack will still render many\n// Markdown-like constructs (lists, code fences, etc.) natively.\n\nimport { spawn } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\n/**\n * Represents an extracted mermaid diagram\n */\nexport interface MermaidDiagram {\n /** The full match including ```mermaid and ``` */\n fullMatch: string;\n /** The mermaid code content */\n code: string;\n /** Start index in the original text */\n startIndex: number;\n /** End index in the original text */\n endIndex: number;\n}\n\n/**\n * Extract all mermaid code blocks from text\n */\nexport function extractMermaidDiagrams(text: string): MermaidDiagram[] {\n const diagrams: MermaidDiagram[] = [];\n // Match ```mermaid followed by newline, content, and closing ```\n const regex = /```mermaid\\s*\\n([\\s\\S]*?)```/g;\n let match;\n while ((match = regex.exec(text)) !== null) {\n diagrams.push({\n fullMatch: match[0],\n code: match[1].trim(),\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n return diagrams;\n}\n\n/**\n * Render a mermaid diagram to PNG using mmdc CLI (@mermaid-js/mermaid-cli).\n *\n * Requirements:\n * - Node.js and npx must be available in PATH\n * - Network access on first run (npx downloads the package)\n * - Puppeteer/Chromium dependencies (mermaid-cli uses headless browser)\n *\n * On Linux, you may need to install chromium dependencies:\n * apt-get install -y chromium-browser libatk-bridge2.0-0 libgtk-3-0\n *\n * On Docker/CI, consider using a base image with puppeteer support or\n * pre-installing @mermaid-js/mermaid-cli globally.\n *\n * @param mermaidCode The mermaid diagram code\n * @returns Buffer containing PNG data, or null if rendering failed\n */\nexport async function renderMermaidToPng(mermaidCode: string): Promise<Buffer | null> {\n // Create temp files for input and output\n const tmpDir = os.tmpdir();\n const inputFile = path.join(\n tmpDir,\n `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.mmd`\n );\n const outputFile = path.join(\n tmpDir,\n `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.png`\n );\n\n try {\n // Write mermaid code to temp file\n fs.writeFileSync(inputFile, mermaidCode, 'utf-8');\n\n // Detect system chromium for puppeteer (mermaid-cli dependency)\n // Without this, puppeteer may hang trying to download its own chromium\n const chromiumPaths = [\n '/usr/bin/chromium',\n '/usr/bin/chromium-browser',\n '/usr/bin/google-chrome',\n '/usr/bin/chrome',\n ];\n let chromiumPath: string | undefined;\n for (const p of chromiumPaths) {\n if (fs.existsSync(p)) {\n chromiumPath = p;\n break;\n }\n }\n\n // Build environment with chromium path if found\n const env = { ...process.env };\n if (chromiumPath) {\n env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;\n }\n\n // Run mmdc to render PNG\n const result = await new Promise<{ success: boolean; error?: string }>(resolve => {\n const proc = spawn(\n 'npx',\n [\n '--yes',\n '@mermaid-js/mermaid-cli',\n '-i',\n inputFile,\n '-o',\n outputFile,\n '-e',\n 'png',\n '-b',\n 'white',\n '-w',\n '1200',\n ],\n {\n timeout: 60000, // 60 second timeout (first run may download packages)\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n }\n );\n\n let stderr = '';\n proc.stderr?.on('data', data => {\n stderr += data.toString();\n });\n\n proc.on('close', code => {\n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({ success: false, error: stderr || `Exit code ${code}` });\n }\n });\n\n proc.on('error', err => {\n resolve({ success: false, error: err.message });\n });\n });\n\n if (!result.success) {\n console.warn(`Mermaid rendering failed: ${result.error}`);\n return null;\n }\n\n // Read the output PNG\n if (!fs.existsSync(outputFile)) {\n console.warn('Mermaid output file not created');\n return null;\n }\n\n const pngBuffer = fs.readFileSync(outputFile);\n return pngBuffer;\n } catch (e) {\n console.warn(`Mermaid rendering error: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n } finally {\n // Cleanup temp files\n try {\n if (fs.existsSync(inputFile)) fs.unlinkSync(inputFile);\n if (fs.existsSync(outputFile)) fs.unlinkSync(outputFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Replace mermaid blocks in text with a placeholder message\n * @param text Original text\n * @param diagrams Extracted diagrams\n * @param replacement Text to replace each diagram with (or a function that returns replacement for each index)\n */\nexport function replaceMermaidBlocks(\n text: string,\n diagrams: MermaidDiagram[],\n replacement: string | ((index: number) => string) = '_(See diagram above)_'\n): string {\n if (diagrams.length === 0) return text;\n\n // Sort by start index descending to replace from end to start (preserves indices)\n const sorted = [...diagrams].sort((a, b) => b.startIndex - a.startIndex);\n\n let result = text;\n sorted.forEach((diagram, sortedIndex) => {\n // Calculate original index (since we sorted in reverse)\n const originalIndex = diagrams.length - 1 - sortedIndex;\n const rep = typeof replacement === 'function' ? replacement(originalIndex) : replacement;\n result = result.slice(0, diagram.startIndex) + rep + result.slice(diagram.endIndex);\n });\n\n return result;\n}\n\nexport function markdownToSlack(text: string): string {\n if (!text || typeof text !== 'string') return '';\n\n let out = text;\n\n // Images:  → <url|alt>\n // We intentionally keep only the URL + alt text; Slack will usually unfurl.\n out = out.replace(\n /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, alt: string, url: string) => `<${url}|${alt || 'image'}>`\n );\n\n // Links: [label](url) → <url|label>\n out = out.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, label: string, url: string) => `<${url}|${label}>`\n );\n\n // Bold: **text** or __text__ → *text*\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, (_m, inner: string) => `*${inner}*`);\n out = out.replace(/__([^_]+)__/g, (_m, inner: string) => `*${inner}*`);\n\n // Process lines for headers and bullet lists.\n // Slack's mrkdwn handles \"•\" bullets more naturally than raw \"-\" Markdown.\n const lines = out.split(/\\r?\\n/);\n let inCodeBlock = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trimStart();\n // Track fenced code blocks and avoid rewriting inside them\n if (/^```/.test(trimmed)) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n // Headers: # Header → *Header* (Slack doesn't have native headers)\n // Match 1-6 # at start of line, followed by space and text\n const headerMatch = /^(#{1,6})\\s+(.+)$/.exec(trimmed);\n if (headerMatch) {\n const [, hashes, headerText] = headerMatch;\n // For h1/h2, add extra emphasis with newline before (if not first line\n // and previous line is not empty/header/code-fence)\n const prevLine = i > 0 ? lines[i - 1].trim() : '';\n const prevIsHeaderOrFence =\n /^#{1,6}\\s+/.test(prevLine) || /^\\*[^*]+\\*$/.test(prevLine) || /^```/.test(prevLine);\n if (hashes.length <= 2 && i > 0 && prevLine !== '' && !prevIsHeaderOrFence) {\n lines[i] = `\\n*${headerText.trim()}*`;\n } else {\n lines[i] = `*${headerText.trim()}*`;\n }\n continue;\n }\n\n // Bullet lists: \"- item\" or \"* item\" → \"• item\" (preserve indentation)\n const bulletMatch = /^(\\s*)([-*])\\s+(.+)$/.exec(line);\n if (bulletMatch) {\n const [, indent, , rest] = bulletMatch;\n lines[i] = `${indent}• ${rest}`;\n }\n }\n out = lines.join('\\n');\n\n return out;\n}\n\nexport function formatSlackText(text: string): string {\n return markdownToSlack(text);\n}\n","/**\n * Slack Frontend for Visor workflows.\n *\n * Features:\n * - Posts AI replies to Slack threads\n * - Converts Markdown to Slack mrkdwn format\n * - Renders mermaid diagrams to PNG and uploads as images\n * - Manages 👀/👍 reactions for acknowledgement\n * - Handles human input prompts via prompt-state\n *\n * Mermaid Diagram Rendering:\n * - Detects ```mermaid code blocks in AI responses\n * - Renders to PNG using @mermaid-js/mermaid-cli (mmdc)\n * - Uploads rendered images to Slack thread\n * - Replaces mermaid blocks with \"_(See diagram above)_\" placeholder\n *\n * Requirements for mermaid rendering:\n * - Node.js and npx in PATH\n * - Puppeteer/Chromium dependencies (mermaid-cli uses headless browser)\n * - On Linux: apt-get install chromium-browser libatk-bridge2.0-0 libgtk-3-0\n */\nimport type { Frontend, FrontendContext } from './host';\nimport { SlackClient } from '../slack/client';\nimport {\n formatSlackText,\n extractMermaidDiagrams,\n renderMermaidToPng,\n replaceMermaidBlocks,\n} from '../slack/markdown';\nimport { context as otContext, trace } from '../telemetry/lazy-otel';\n\ntype SlackFrontendConfig = {\n defaultChannel?: string;\n groupChannels?: Record<string, string>;\n debounceMs?: number;\n maxWaitMs?: number;\n showRawOutput?: boolean;\n telemetry?: {\n enabled?: boolean;\n };\n};\n\nexport class SlackFrontend implements Frontend {\n public readonly name = 'slack';\n private subs: Array<{ unsubscribe(): void }> = [];\n private cfg: SlackFrontendConfig;\n // Reactions ack/done per run (inbound Slack events only)\n private acked: boolean = false;\n private ackRef: { channel: string; ts: string } | null = null;\n private ackName: string = 'eyes';\n private doneName: string = 'thumbsup';\n private errorNotified: boolean = false;\n private cachedTraceInfo: { traceId: string; spanId: string } | null = null;\n\n constructor(config?: SlackFrontendConfig) {\n this.cfg = config || {};\n }\n\n start(ctx: FrontendContext): void {\n const bus = ctx.eventBus;\n\n // Capture trace info now while the OTel span may still be active.\n // EventBus handlers run in a different async context where the span is lost.\n if (!this.cachedTraceInfo) {\n this.cachedTraceInfo = this.getTraceInfo();\n }\n // Also check ctx.run.traceId which is injected by the execution engine\n if (!this.cachedTraceInfo) {\n const runTraceId = (ctx as any)?.run?.traceId;\n if (typeof runTraceId === 'string' && runTraceId) {\n this.cachedTraceInfo = { traceId: runTraceId, spanId: '' };\n }\n }\n\n // Info-level boot log\n try {\n const hasClient = !!(\n (ctx as any).slack ||\n (ctx as any).slackClient ||\n (this.cfg as any)?.botToken ||\n process.env.SLACK_BOT_TOKEN\n );\n ctx.logger.info(`[slack-frontend] started; hasClient=${hasClient} defaultChannel=unset`);\n } catch {}\n\n // If this run was triggered by a Slack event, log key attributes\n try {\n const payload = this.getInboundSlackPayload(ctx);\n if (payload) {\n const ev: any = payload.event || {};\n const ch = String(ev.channel || '-');\n const ts = String(ev.ts || ev.event_ts || '-');\n const user = String(ev.user || ev.bot_id || '-');\n const type = String(ev.type || '-');\n const thread = String(ev.thread_ts || '');\n ctx.logger.info(\n `[slack-frontend] inbound event received: type=${type} channel=${ch} ts=${ts}` +\n (thread ? ` thread_ts=${thread}` : '') +\n ` user=${user}`\n );\n }\n } catch {}\n\n // Listen to check lifecycle; we only post on completion/error (no queued placeholders)\n this.subs.push(\n bus.on('CheckCompleted', async (env: any) => {\n const ev = (env && env.payload) || env;\n // For chat-style AI checks, post direct replies into the Slack thread\n await this.maybePostDirectReply(ctx, ev.checkId, ev.result).catch(() => {});\n // Post execution failure notices when a check completes with fatal issues\n await this.maybePostExecutionFailure(ctx, ev.checkId, ev.result).catch(() => {});\n })\n );\n this.subs.push(\n bus.on('CheckErrored', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Execution error';\n await this.maybePostError(ctx, 'Check failed', message, ev?.checkId).catch(() => {});\n })\n );\n\n // On terminal state, replace 👀 with 👍 if we acked an inbound Slack message\n this.subs.push(\n bus.on('StateTransition', async (env: any) => {\n const ev = (env && env.payload) || env;\n if (ev && (ev.to === 'Completed' || ev.to === 'Error')) {\n await this.finalizeReactions(ctx).catch(() => {});\n }\n })\n );\n this.subs.push(\n bus.on('Shutdown', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Fatal error';\n await this.maybePostError(ctx, 'Run failed', message).catch(() => {});\n })\n );\n // Add 👀 acknowledgement as soon as first check is scheduled for Slack-driven runs\n this.subs.push(\n bus.on('CheckScheduled', async () => {\n await this.ensureAcknowledgement(ctx).catch(() => {});\n })\n );\n\n // Human-input requests: post prompt to Slack and mark waiting using prompt-state\n this.subs.push(\n bus.on('HumanInputRequested', async (env: any) => {\n try {\n const ev = (env && env.payload) || env;\n if (!ev || typeof ev.prompt !== 'string' || !ev.checkId) return;\n // Determine channel/thread (Slack SocketMode); if we can't, just ignore.\n let channel = ev.channel as string | undefined;\n let threadTs = ev.threadTs as string | undefined;\n if (!channel || !threadTs) {\n const payload = this.getInboundSlackPayload(ctx);\n const e: any = payload?.event;\n const derivedTs = String(e?.thread_ts || e?.ts || e?.event_ts || '');\n const derivedCh = String(e?.channel || '');\n if (derivedCh && derivedTs) {\n channel = channel || derivedCh;\n threadTs = threadTs || derivedTs;\n }\n }\n if (!channel || !threadTs) return;\n\n // Mark waiting in prompt-state without posting the prompt text to Slack.\n const { getPromptStateManager } = await import('../slack/prompt-state');\n const mgr = getPromptStateManager();\n const prev = mgr.getWaiting(channel, threadTs);\n const text = String(ev.prompt);\n mgr.setWaiting(channel, threadTs, {\n checkName: String(ev.checkId),\n prompt: text,\n promptMessageTs: prev?.promptMessageTs,\n promptsPosted: ((prev?.promptsPosted || 0) + 1) as any,\n });\n try {\n ctx.logger.info(\n `[slack-frontend] registered human-input waiting state for ${channel} thread=${threadTs}`\n );\n } catch {}\n } catch (e) {\n try {\n ctx.logger.warn(\n `[slack-frontend] HumanInputRequested handling failed: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n } catch {}\n }\n })\n );\n\n // SnapshotSaved: attach snapshot path to waiting entry for this thread\n this.subs.push(\n bus.on('SnapshotSaved', async (env: any) => {\n try {\n const ev = (env && env.payload) || env;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.threadTs || '');\n const filePath = String(ev?.filePath || '');\n if (!channel || !threadTs || !filePath) return;\n const { getPromptStateManager } = await import('../slack/prompt-state');\n const mgr = getPromptStateManager();\n mgr.update(channel, threadTs, { snapshotPath: filePath });\n try {\n ctx.logger.info(\n `[slack-frontend] snapshot path attached to waiting prompt: ${filePath}`\n );\n } catch {}\n } catch {}\n })\n );\n }\n\n stop(): void {\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\n }\n\n private getSlack(ctx: FrontendContext): any | undefined {\n // Prefer injected fake client in tests: ctx.slack or ctx.slackClient\n const injected = (ctx as any).slack || (ctx as any).slackClient;\n if (injected) return injected;\n // Else try to lazy-create from env or frontend config\n try {\n const token = (this.cfg as any)?.botToken || process.env.SLACK_BOT_TOKEN;\n if (typeof token === 'string' && token.trim()) {\n return new SlackClient(token.trim());\n }\n } catch {}\n return undefined;\n }\n\n private getInboundSlackPayload(ctx: FrontendContext): any | null {\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n const endpoint: string = slackCfg.endpoint || '/bots/slack/support';\n const payload: any = (ctx as any).webhookContext?.webhookData?.get(endpoint);\n return payload || null;\n } catch {\n return null;\n }\n }\n\n private getInboundSlackEvent(ctx: FrontendContext): { channel: string; ts: string } | null {\n try {\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const ts = String(ev?.ts || ev?.event_ts || '');\n if (channel && ts) return { channel, ts };\n } catch {}\n return null;\n }\n\n private isTelemetryEnabled(ctx: FrontendContext): boolean {\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n const telemetryCfg = slackCfg.telemetry ?? (this.cfg as any)?.telemetry;\n return (\n telemetryCfg === true ||\n (telemetryCfg && typeof telemetryCfg === 'object' && telemetryCfg.enabled === true)\n );\n } catch {\n return false;\n }\n }\n\n private async maybePostError(\n ctx: FrontendContext,\n title: string,\n message: string,\n checkId?: string\n ): Promise<void> {\n if (this.errorNotified) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || '');\n if (!channel || !threadTs) {\n try {\n ctx.logger.warn(\n `[slack-frontend] skip posting error notice: missing channel/thread (channel=${\n channel || '-'\n } thread=${threadTs || '-'})`\n );\n } catch {}\n return;\n }\n\n let text = `❌ ${title}`;\n if (checkId) text += `\\nCheck: ${checkId}`;\n if (message) text += `\\n${message}`;\n\n if (this.isTelemetryEnabled(ctx)) {\n const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;\n if (traceInfo?.traceId) {\n text += `\\n\\n\\`trace_id: ${traceInfo.traceId}\\``;\n }\n }\n\n const formattedText = formatSlackText(text);\n const postResult = await slack.chat.postMessage({\n channel,\n text: formattedText,\n thread_ts: threadTs,\n });\n if (!postResult?.ok) {\n try {\n ctx.logger.warn(\n `[slack-frontend] failed to post error notice to ${channel} thread=${threadTs} check=${\n checkId || 'run'\n } error=${postResult?.error || 'unknown_error'}`\n );\n } catch {}\n return;\n }\n try {\n ctx.logger.info(\n `[slack-frontend] posted error notice to ${channel} thread=${threadTs} check=${checkId || 'run'}`\n );\n } catch {}\n this.errorNotified = true;\n }\n\n private isExecutionFailureIssue(issue: any): boolean {\n const ruleId = String(issue?.ruleId || '');\n const msg = String(issue?.message || '');\n const msgLower = msg.toLowerCase();\n return (\n ruleId.endsWith('/error') ||\n ruleId.includes('/execution_error') ||\n ruleId.includes('timeout') ||\n ruleId.includes('sandbox_runner_error') ||\n msgLower.includes('timed out') ||\n msg.includes('Command execution failed')\n );\n }\n\n private async maybePostExecutionFailure(\n ctx: FrontendContext,\n checkId: string,\n result: { issues?: any[] }\n ): Promise<void> {\n try {\n if (this.errorNotified) return;\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n if (checkCfg.type === 'human-input') return;\n if (checkCfg.criticality === 'internal') return;\n const issues = (result as any)?.issues;\n if (!Array.isArray(issues) || issues.length === 0) return;\n\n const failureIssue = issues.find(issue => this.isExecutionFailureIssue(issue));\n if (!failureIssue) return;\n if (\n typeof failureIssue.message === 'string' &&\n failureIssue.message.toLowerCase().includes('awaiting human input')\n ) {\n return;\n }\n\n const msg =\n typeof failureIssue.message === 'string' && failureIssue.message.trim().length > 0\n ? failureIssue.message.trim()\n : `Execution failed (${String(failureIssue.ruleId || 'unknown')})`;\n await this.maybePostError(ctx, 'Check failed', msg, checkId);\n } catch {}\n }\n\n private async ensureAcknowledgement(ctx: FrontendContext): Promise<void> {\n if (this.acked) return;\n const ref = this.getInboundSlackEvent(ctx);\n if (!ref) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n // Skip ack for our own bot messages to avoid loops (allow other bots)\n try {\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n // If we can resolve bot user id, skip if the sender is the bot\n try {\n const botId = await slack.getBotUserId?.();\n if (botId && ev?.user && String(ev.user) === String(botId)) return;\n } catch {}\n } catch {}\n // Allow overrides via config\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n if (slackCfg?.reactions?.enabled === false) return;\n this.ackName = slackCfg?.reactions?.ack || this.ackName;\n this.doneName = slackCfg?.reactions?.done || this.doneName;\n } catch {}\n await slack.reactions.add({ channel: ref.channel, timestamp: ref.ts, name: this.ackName });\n try {\n ctx.logger.info(\n `[slack-frontend] added acknowledgement reaction :${this.ackName}: channel=${ref.channel} ts=${ref.ts}`\n );\n } catch {}\n this.acked = true;\n this.ackRef = ref;\n // Capture trace info while span is active (event handlers lose OTel context)\n if (!this.cachedTraceInfo) {\n this.cachedTraceInfo = this.getTraceInfo();\n }\n }\n\n private async finalizeReactions(ctx: FrontendContext): Promise<void> {\n if (!this.acked || !this.ackRef) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n try {\n try {\n await slack.reactions.remove({\n channel: this.ackRef.channel,\n timestamp: this.ackRef.ts,\n name: this.ackName,\n });\n } catch {}\n await slack.reactions.add({\n channel: this.ackRef.channel,\n timestamp: this.ackRef.ts,\n name: this.doneName,\n });\n try {\n ctx.logger.info(\n `[slack-frontend] replaced acknowledgement with completion reaction :${this.doneName}: channel=${this.ackRef.channel} ts=${this.ackRef.ts}`\n );\n } catch {}\n } finally {\n // Reset for safety\n this.acked = false;\n this.ackRef = null;\n }\n }\n\n /**\n * Post direct replies into the originating Slack thread when appropriate.\n * This is independent of summary messages and is intended for chat-style flows\n * (e.g., AI answers and explicit chat/notify steps).\n */\n private async maybePostDirectReply(\n ctx: FrontendContext,\n checkId: string,\n result: { output?: any; content?: string }\n ): Promise<void> {\n try {\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n\n // Per-workflow / per-frontend flag to allow posting raw JSON\n // outputs for AI steps (useful for debugging router outputs).\n const slackRoot: any = (cfg as any).slack || {};\n const showRawOutput =\n slackRoot.show_raw_output === true || (this.cfg as any)?.showRawOutput === true;\n const telemetryCfg = slackRoot.telemetry ?? (this.cfg as any)?.telemetry;\n\n const providerType = (checkCfg.type as string) || '';\n const isAi = providerType === 'ai';\n const isLogChat = providerType === 'log' && checkCfg.group === 'chat';\n const isWorkflow = providerType === 'workflow';\n\n // Allow ai, log-chat, and workflow types; skip everything else\n if (!isAi && !isLogChat && !isWorkflow) return;\n\n // Skip internal steps - they're intermediate processing and shouldn't post to Slack\n if (checkCfg.criticality === 'internal') return;\n\n // For AI checks, only post when using simple/unstructured schemas (or none).\n if (isAi) {\n const schema = checkCfg.schema;\n // String schemas: allow only simple/plain ones\n if (typeof schema === 'string') {\n const simpleSchemas = ['code-review', 'markdown', 'text', 'plain'];\n if (!simpleSchemas.includes(schema)) return;\n }\n // Object schemas (custom JSON): treat as structured; require output.text\n }\n\n const slack = this.getSlack(ctx);\n if (!slack) return;\n\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || '');\n if (!channel || !threadTs) {\n ctx.logger.warn(\n `[slack-frontend] skip posting AI reply for ${checkId}: missing channel/thread (channel=${\n channel || '-'\n } thread=${threadTs || '-'})`\n );\n return;\n }\n\n // Prefer output.text; fall back to content ONLY for string/simple schemas.\n const out: any = (result as any)?.output;\n let text: string | undefined;\n if (out && typeof out.text === 'string' && out.text.trim().length > 0) {\n text = out.text.trim();\n } else if (isAi && typeof checkCfg.schema === 'string') {\n if (\n typeof (result as any)?.content === 'string' &&\n (result as any).content.trim().length > 0\n ) {\n text = (result as any).content.trim();\n }\n } else if (isLogChat && typeof (result as any)?.logOutput === 'string') {\n // For log-based chat checks, render the formatted log output as the\n // Slack message when no structured text field is present.\n const raw = (result as any).logOutput;\n if (raw.trim().length > 0) {\n text = raw.trim();\n }\n } else if (isAi && showRawOutput && out !== undefined) {\n try {\n text = JSON.stringify(out, null, 2);\n } catch {\n text = String(out);\n }\n }\n if (!text) {\n ctx.logger.info(\n `[slack-frontend] skip posting AI reply for ${checkId}: no renderable text in check output`\n );\n return;\n }\n\n // Extract and render mermaid diagrams before posting\n const diagrams = extractMermaidDiagrams(text);\n let processedText = text;\n\n if (diagrams.length > 0) {\n try {\n ctx.logger.info(\n `[slack-frontend] found ${diagrams.length} mermaid diagram(s) to render for ${checkId}`\n );\n } catch {}\n\n // Render and upload each diagram\n const uploadedCount: number[] = [];\n for (let i = 0; i < diagrams.length; i++) {\n const diagram = diagrams[i];\n try {\n ctx.logger.info(`[slack-frontend] rendering mermaid diagram ${i + 1}...`);\n const pngBuffer = await renderMermaidToPng(diagram.code);\n if (pngBuffer) {\n ctx.logger.info(\n `[slack-frontend] rendered diagram ${i + 1}, size=${pngBuffer.length} bytes, uploading...`\n );\n const filename = `diagram-${i + 1}.png`;\n const uploadResult = await slack.files.uploadV2({\n content: pngBuffer,\n filename,\n channel,\n thread_ts: threadTs,\n title: `Diagram ${i + 1}`,\n });\n if (uploadResult.ok) {\n uploadedCount.push(i);\n ctx.logger.info(`[slack-frontend] uploaded mermaid diagram ${i + 1} to ${channel}`);\n } else {\n ctx.logger.warn(`[slack-frontend] upload failed for diagram ${i + 1}`);\n }\n } else {\n ctx.logger.warn(\n `[slack-frontend] mermaid rendering returned null for diagram ${i + 1} (mmdc failed or not installed)`\n );\n }\n } catch (e) {\n ctx.logger.warn(\n `[slack-frontend] failed to render/upload mermaid diagram ${i + 1}: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n }\n\n // Replace mermaid blocks with placeholder text\n if (uploadedCount.length > 0) {\n processedText = replaceMermaidBlocks(text, diagrams, idx =>\n uploadedCount.includes(idx) ? '_(See diagram above)_' : '_(Diagram rendering failed)_'\n );\n }\n }\n\n let decoratedText = processedText;\n const telemetryEnabled =\n telemetryCfg === true ||\n (telemetryCfg && typeof telemetryCfg === 'object' && telemetryCfg.enabled === true);\n if (telemetryEnabled) {\n const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;\n if (traceInfo?.traceId) {\n const suffix = `\\`trace_id: ${traceInfo.traceId}\\``;\n decoratedText = `${decoratedText}\\n\\n${suffix}`;\n }\n }\n\n const formattedText = formatSlackText(decoratedText);\n const postResult = await slack.chat.postMessage({\n channel,\n text: formattedText,\n thread_ts: threadTs,\n });\n if (!postResult?.ok) {\n ctx.logger.warn(\n `[slack-frontend] failed to post AI reply for ${checkId} to ${channel} thread=${threadTs} error=${\n postResult?.error || 'unknown_error'\n }`\n );\n return;\n }\n ctx.logger.info(\n `[slack-frontend] posted AI reply for ${checkId} to ${channel} thread=${threadTs} ts=${\n postResult.ts || '-'\n }`\n );\n\n // Capture response for scheduled reminders (allows storing previousResponse)\n const responseCapture = (ctx as any).responseCapture as ((text: string) => void) | undefined;\n if (responseCapture && typeof responseCapture === 'function') {\n try {\n // Store the original text (before mrkdwn formatting) for continuity\n responseCapture(processedText);\n } catch {}\n }\n } catch (outerErr) {\n // Log errors instead of silently swallowing them\n try {\n ctx.logger.warn(\n `[slack-frontend] maybePostDirectReply failed for ${checkId}: ${\n outerErr instanceof Error ? outerErr.message : String(outerErr)\n }`\n );\n } catch {}\n }\n }\n\n private getTraceInfo(): { traceId: string; spanId: string } | null {\n try {\n const span = trace.getSpan(otContext.active());\n if (!span) return null;\n const ctx = span.spanContext();\n if (!ctx || !ctx.traceId) return null;\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
setSpanAttributes,
|
|
8
8
|
setSpanError,
|
|
9
9
|
withActiveSpan
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-YJRBN3XS.mjs";
|
|
11
|
+
import "./chunk-UCMJJ3IM.mjs";
|
|
12
12
|
import "./chunk-J7LXIPZS.mjs";
|
|
13
13
|
init_trace_helpers();
|
|
14
14
|
export {
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
setSpanError,
|
|
21
21
|
withActiveSpan
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=trace-helpers-
|
|
23
|
+
//# sourceMappingURL=trace-helpers-PP3YHTAM.mjs.map
|
|
@@ -107,13 +107,28 @@ var init_chat_state = __esm({
|
|
|
107
107
|
minute: "2-digit",
|
|
108
108
|
second: "2-digit"
|
|
109
109
|
});
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
${
|
|
110
|
+
const content = this.escapeTags(message.content);
|
|
111
|
+
if (message.role === "user") {
|
|
112
|
+
const header2 = `{black-bg}{bold} > You {/bold}[${time}]{/black-bg}`;
|
|
113
|
+
const body = content.split("\n").map((l) => `{black-bg} ${l} {/black-bg}`).join("\n");
|
|
114
|
+
return `${header2}
|
|
115
|
+
${body}`;
|
|
116
|
+
}
|
|
117
|
+
if (message.role === "assistant") {
|
|
118
|
+
const header2 = `{bold}{green-fg}\u25CF{/green-fg} Assistant{/bold} {gray-fg}[${time}]{/gray-fg}`;
|
|
119
|
+
return `${header2}
|
|
120
|
+
${content}`;
|
|
121
|
+
}
|
|
122
|
+
const header = `{gray-fg}\u2298 Visor [${time}]`;
|
|
123
|
+
return `${header}
|
|
124
|
+
${content}{/gray-fg}`;
|
|
125
|
+
}
|
|
126
|
+
escapeTags(text) {
|
|
127
|
+
return text.replace(/\{/g, "\\{");
|
|
113
128
|
}
|
|
114
129
|
formatHistoryForDisplay() {
|
|
115
130
|
if (this._history.length === 0) {
|
|
116
|
-
return "No messages yet. Type a message to start...";
|
|
131
|
+
return "{gray-fg}No messages yet. Type a message to start...{/gray-fg}";
|
|
117
132
|
}
|
|
118
133
|
const separator = "\n\n";
|
|
119
134
|
return this._history.map((msg) => this.formatMessageForDisplay(msg)).join(separator);
|
|
@@ -191,11 +206,7 @@ var init_tui_frontend = __esm({
|
|
|
191
206
|
const cfg = ctx.config || {};
|
|
192
207
|
const checkCfg = cfg.checks?.[checkId];
|
|
193
208
|
if (!checkCfg) return;
|
|
194
|
-
const providerType = checkCfg.type || "";
|
|
195
|
-
const isAi = providerType === "ai";
|
|
196
|
-
const isLogChat = providerType === "log" && checkCfg.group === "chat";
|
|
197
209
|
if (checkCfg.criticality === "internal") return;
|
|
198
|
-
if (!isAi && !isLogChat) return;
|
|
199
210
|
let text;
|
|
200
211
|
const out = result?.output;
|
|
201
212
|
if (out) {
|
|
@@ -204,16 +215,14 @@ var init_tui_frontend = __esm({
|
|
|
204
215
|
text = extracted.trim();
|
|
205
216
|
} else if (typeof out.text === "string" && out.text.trim()) {
|
|
206
217
|
text = out.text.trim();
|
|
218
|
+
} else if (typeof out === "string" && out.trim()) {
|
|
219
|
+
text = out.trim();
|
|
207
220
|
}
|
|
208
221
|
}
|
|
209
|
-
if (!text &&
|
|
210
|
-
|
|
211
|
-
const isSimpleSchema = typeof schema === "string" ? ["plain", "text", "markdown", "code-review"].includes(schema) : schema === void 0 || schema === null;
|
|
212
|
-
if (isSimpleSchema) {
|
|
213
|
-
text = result.content.trim();
|
|
214
|
-
}
|
|
222
|
+
if (!text && typeof result?.content === "string" && result.content.trim()) {
|
|
223
|
+
text = result.content.trim();
|
|
215
224
|
}
|
|
216
|
-
if (!text
|
|
225
|
+
if (!text) {
|
|
217
226
|
const logResult = result;
|
|
218
227
|
if (typeof logResult?.logOutput === "string" && logResult.logOutput.trim()) {
|
|
219
228
|
text = logResult.logOutput.trim();
|
|
@@ -278,4 +287,4 @@ init_tui_frontend();
|
|
|
278
287
|
export {
|
|
279
288
|
TuiFrontend
|
|
280
289
|
};
|
|
281
|
-
//# sourceMappingURL=tui-frontend-
|
|
290
|
+
//# sourceMappingURL=tui-frontend-T56PZB67.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/tui/chat-state.ts","../../src/tui/tui-frontend.ts"],"sourcesContent":["/**\n * Chat State Manager for TUI\n *\n * Manages chat message history, processing state, and human-input waiting state.\n */\n\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: Date;\n checkId?: string;\n}\n\nexport interface WaitingState {\n checkId: string;\n prompt: string;\n placeholder?: string;\n multiline?: boolean;\n timeout?: number;\n defaultValue?: string;\n allowEmpty?: boolean;\n}\n\nexport interface ChatStateManagerOptions {\n maxMessages?: number;\n}\n\nexport class ChatStateManager {\n private _history: ChatMessage[] = [];\n private _isProcessing = false;\n private _waitingState?: WaitingState;\n private _inputQueue: string[] = [];\n private _maxMessages: number;\n private _messageCounter = 0;\n private _statusText = 'Ready';\n\n constructor(options: ChatStateManagerOptions = {}) {\n this._maxMessages = options.maxMessages ?? 1000;\n }\n\n get history(): ChatMessage[] {\n return [...this._history];\n }\n\n get isProcessing(): boolean {\n return this._isProcessing;\n }\n\n get isWaiting(): boolean {\n return this._waitingState !== undefined;\n }\n\n get waitingState(): WaitingState | undefined {\n return this._waitingState;\n }\n\n get hasQueuedInput(): boolean {\n return this._inputQueue.length > 0;\n }\n\n get statusText(): string {\n return this._statusText;\n }\n\n setStatus(text: string): void {\n this._statusText = text;\n }\n\n addMessage(\n role: 'user' | 'assistant' | 'system',\n content: string,\n checkId?: string\n ): ChatMessage {\n const message: ChatMessage = {\n id: `msg-${++this._messageCounter}`,\n role,\n content,\n timestamp: new Date(),\n checkId,\n };\n\n this._history.push(message);\n\n // Trim history if it exceeds max\n while (this._history.length > this._maxMessages) {\n this._history.shift();\n }\n\n return message;\n }\n\n setProcessing(processing: boolean): void {\n this._isProcessing = processing;\n if (processing) {\n this._statusText = 'Processing...';\n } else if (!this._waitingState) {\n this._statusText = 'Ready';\n }\n }\n\n setWaiting(state: WaitingState | undefined): void {\n this._waitingState = state;\n if (state) {\n this._statusText = 'Awaiting input...';\n } else if (!this._isProcessing) {\n this._statusText = 'Ready';\n }\n }\n\n clearWaiting(): void {\n this._waitingState = undefined;\n if (!this._isProcessing) {\n this._statusText = 'Ready';\n }\n }\n\n queueInput(input: string): void {\n this._inputQueue.push(input);\n }\n\n dequeueInput(): string | undefined {\n return this._inputQueue.shift();\n }\n\n clearQueue(): void {\n this._inputQueue = [];\n }\n\n clearHistory(): void {\n this._history = [];\n }\n\n getRecentMessages(count: number): ChatMessage[] {\n return this._history.slice(-count);\n }\n\n formatMessageForDisplay(message: ChatMessage): string {\n const time = message.timestamp.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n\n const content = this.escapeTags(message.content);\n\n if (message.role === 'user') {\n const header = `{black-bg}{bold} > You {/bold}[${time}]{/black-bg}`;\n const body = content\n .split('\\n')\n .map((l: string) => `{black-bg} ${l} {/black-bg}`)\n .join('\\n');\n return `${header}\\n${body}`;\n }\n\n if (message.role === 'assistant') {\n const header = `{bold}{green-fg}●{/green-fg} Assistant{/bold} {gray-fg}[${time}]{/gray-fg}`;\n return `${header}\\n${content}`;\n }\n\n // System/Visor messages: gray and subdued\n const header = `{gray-fg}⊘ Visor [${time}]`;\n return `${header}\\n${content}{/gray-fg}`;\n }\n\n private escapeTags(text: string): string {\n return text.replace(/\\{/g, '\\\\{');\n }\n\n formatHistoryForDisplay(): string {\n if (this._history.length === 0) {\n return '{gray-fg}No messages yet. Type a message to start...{/gray-fg}';\n }\n\n const separator = '\\n\\n';\n return this._history.map(msg => this.formatMessageForDisplay(msg)).join(separator);\n }\n}\n\n// Singleton instance for global access\nlet globalStateManager: ChatStateManager | undefined;\n\nexport function getChatStateManager(): ChatStateManager {\n if (!globalStateManager) {\n globalStateManager = new ChatStateManager();\n }\n return globalStateManager;\n}\n\nexport function setChatStateManager(manager: ChatStateManager): void {\n globalStateManager = manager;\n}\n\nexport function resetChatStateManager(): void {\n globalStateManager = undefined;\n}\n","/**\n * TUI Frontend for Visor workflows.\n *\n * Subscribes to EventBus events and updates the ChatTUI accordingly:\n * - CheckCompleted → Display AI response in chat\n * - HumanInputRequested → Set waiting state, update placeholder\n * - StateTransition → Update status bar\n * - CheckErrored → Display error message\n */\nimport type { Frontend, FrontendContext } from '../frontends/host';\nimport { ChatTUI } from './chat-tui';\nimport { getChatStateManager } from './chat-state';\nimport { extractTextFromJson } from '../utils/json-text-extractor';\n\nexport interface TuiFrontendConfig {\n chatTui?: ChatTUI;\n}\n\nexport class TuiFrontend implements Frontend {\n public readonly name = 'tui';\n private subs: Array<{ unsubscribe(): void }> = [];\n private chatTui?: ChatTUI;\n\n constructor(config?: TuiFrontendConfig) {\n this.chatTui = config?.chatTui;\n }\n\n setChatTUI(tui: ChatTUI): void {\n this.chatTui = tui;\n }\n\n start(ctx: FrontendContext): void {\n const bus = ctx.eventBus;\n\n // Info-level boot log\n try {\n ctx.logger.info(`[tui-frontend] started; hasChatTui=${!!this.chatTui}`);\n } catch {}\n\n // Listen to check lifecycle\n this.subs.push(\n bus.on('CheckCompleted', async (env: any) => {\n try {\n const ev = (env && env.payload) || env;\n this.handleCheckCompleted(ctx, ev.checkId, ev.result);\n } catch {}\n })\n );\n\n this.subs.push(\n bus.on('CheckErrored', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Execution error';\n this.handleError(ctx, ev?.checkId, message);\n })\n );\n\n // Human input requests\n this.subs.push(\n bus.on('HumanInputRequested', async (env: any) => {\n const ev = (env && env.payload) || env;\n if (!ev || typeof ev.prompt !== 'string' || !ev.checkId) return;\n this.handleHumanInputRequested(ctx, ev);\n })\n );\n\n // State transitions\n this.subs.push(\n bus.on('StateTransition', async (env: any) => {\n const ev = (env && env.payload) || env;\n this.handleStateTransition(ctx, ev);\n })\n );\n\n // Shutdown events\n this.subs.push(\n bus.on('Shutdown', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Workflow completed';\n this.handleShutdown(ctx, message);\n })\n );\n }\n\n stop(): void {\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\n }\n\n private handleCheckCompleted(\n ctx: FrontendContext,\n checkId: string,\n result: { output?: unknown; content?: string }\n ): void {\n try {\n if (!this.chatTui) return;\n\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n\n // Skip internal steps\n if (checkCfg.criticality === 'internal') return;\n\n // Extract text from result\n let text: string | undefined;\n\n // Try extracting from output\n const out: any = result?.output;\n if (out) {\n // First try extractTextFromJson for structured outputs\n const extracted = extractTextFromJson(out);\n if (extracted) {\n text = extracted.trim();\n } else if (typeof out.text === 'string' && out.text.trim()) {\n text = out.text.trim();\n } else if (typeof out === 'string' && out.trim()) {\n text = out.trim();\n }\n }\n\n // Fall back to content\n if (!text && typeof result?.content === 'string' && result.content.trim()) {\n text = result.content.trim();\n }\n\n // Fall back to logOutput for log checks\n if (!text) {\n const logResult = result as any;\n if (typeof logResult?.logOutput === 'string' && logResult.logOutput.trim()) {\n text = logResult.logOutput.trim();\n }\n }\n\n if (!text) return;\n\n // Add message to chat\n this.chatTui.addAssistantMessage(text, checkId);\n\n try {\n ctx.logger.info(`[tui-frontend] displayed AI response for ${checkId}`);\n } catch {}\n } catch (err) {\n try {\n ctx.logger.warn(\n `[tui-frontend] handleCheckCompleted failed: ${err instanceof Error ? err.message : String(err)}`\n );\n } catch {}\n }\n }\n\n private handleError(_ctx: FrontendContext, checkId: string | undefined, message: string): void {\n if (!this.chatTui) return;\n\n const errorText = checkId ? `[Error in ${checkId}] ${message}` : `[Error] ${message}`;\n\n this.chatTui.addSystemMessage(errorText);\n this.chatTui.setStatus('Error occurred');\n }\n\n private handleHumanInputRequested(_ctx: FrontendContext, ev: any): void {\n if (!this.chatTui) return;\n\n const stateManager = getChatStateManager();\n stateManager.setWaiting({\n checkId: String(ev.checkId),\n prompt: String(ev.prompt),\n placeholder: ev.placeholder,\n multiline: ev.multiline,\n timeout: ev.timeout,\n defaultValue: ev.default,\n allowEmpty: ev.allowEmpty,\n });\n\n this.chatTui.setWaiting(true, ev.prompt);\n }\n\n private handleStateTransition(_ctx: FrontendContext, ev: any): void {\n if (!this.chatTui) return;\n\n const to = ev?.to as string;\n\n if (to === 'Completed' || to === 'Error') {\n this.chatTui.setProcessing(false);\n this.chatTui.setStatus(to === 'Completed' ? 'Workflow completed' : 'Workflow failed');\n } else if (to === 'Running' || to === 'Executing') {\n this.chatTui.setProcessing(true);\n this.chatTui.setStatus('Processing...');\n } else if (to === 'Waiting') {\n // Handled by HumanInputRequested\n }\n }\n\n private handleShutdown(_ctx: FrontendContext, message: string): void {\n if (!this.chatTui) return;\n this.chatTui.setProcessing(false);\n this.chatTui.setStatus(message);\n }\n}\n"],"mappings":"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","names":["header"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WorkflowCheckProvider,
|
|
3
|
+
init_workflow_check_provider
|
|
4
|
+
} from "./chunk-EUUAQBTW.mjs";
|
|
5
|
+
import "./chunk-LG4AUKHB.mjs";
|
|
6
|
+
import "./chunk-KFKHU6CM.mjs";
|
|
7
|
+
import "./chunk-B7BVQM5K.mjs";
|
|
8
|
+
import "./chunk-XXAEN5KU.mjs";
|
|
9
|
+
import "./chunk-GEW6LS32.mjs";
|
|
10
|
+
import "./chunk-DIND4ZCV.mjs";
|
|
11
|
+
import "./chunk-UCNT3PDT.mjs";
|
|
12
|
+
import "./chunk-NCWIZVOT.mjs";
|
|
13
|
+
import "./chunk-VMLORODQ.mjs";
|
|
14
|
+
import "./chunk-HOKQOO3G.mjs";
|
|
15
|
+
import "./chunk-YJRBN3XS.mjs";
|
|
16
|
+
import "./chunk-JL7JXCET.mjs";
|
|
17
|
+
import "./chunk-V2IV3ILA.mjs";
|
|
18
|
+
import "./chunk-25IC7KXZ.mjs";
|
|
19
|
+
import "./chunk-VF6XIUE4.mjs";
|
|
20
|
+
import "./chunk-VPC3QSPW.mjs";
|
|
21
|
+
import "./chunk-SZXICFQ3.mjs";
|
|
22
|
+
import "./chunk-UCMJJ3IM.mjs";
|
|
23
|
+
import "./chunk-J7LXIPZS.mjs";
|
|
24
|
+
init_workflow_check_provider();
|
|
25
|
+
export {
|
|
26
|
+
WorkflowCheckProvider
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=workflow-check-provider-2ET3SFZH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|