@probelabs/visor 0.1.154 → 0.1.155
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/index.js +365 -109
- package/dist/output/traces/{run-2026-03-04T15-57-32-312Z.ndjson → run-2026-03-04T18-12-39-729Z.ndjson} +84 -84
- package/dist/output/traces/{run-2026-03-04T15-58-17-868Z.ndjson → run-2026-03-04T18-13-23-673Z.ndjson} +1761 -1761
- package/dist/sdk/{check-provider-registry-2HT3USLQ.mjs → check-provider-registry-7ZHNM7YO.mjs} +5 -5
- package/dist/sdk/{check-provider-registry-CQTR5OVS.mjs → check-provider-registry-GJ4EZAIO.mjs} +2 -2
- package/dist/sdk/{chunk-PW3RK2IS.mjs → chunk-D7STLGAD.mjs} +8 -8
- package/dist/sdk/{chunk-RH7C77KY.mjs → chunk-E7QWTDTC.mjs} +15 -15
- package/dist/sdk/{chunk-ZPRIWRM2.mjs → chunk-JBLYMLQJ.mjs} +3 -3
- package/dist/sdk/{chunk-AU6RDTY4.mjs → chunk-MLMI3N35.mjs} +2 -2
- package/dist/sdk/{chunk-S6MIZBKN.mjs → chunk-POPHHNHJ.mjs} +2 -2
- package/dist/sdk/{chunk-S6MIZBKN.mjs.map → chunk-POPHHNHJ.mjs.map} +1 -1
- package/dist/sdk/{failure-condition-evaluator-TCB66TZU.mjs → failure-condition-evaluator-NZGTI5SZ.mjs} +3 -3
- package/dist/sdk/{github-frontend-6C7WVBEL.mjs → github-frontend-6U46M2ZI.mjs} +3 -3
- package/dist/sdk/{host-LKPQXXCY.mjs → host-4ONWAJ6Q.mjs} +3 -3
- package/dist/sdk/host-OXBUPRSC.mjs +63 -0
- package/dist/sdk/host-OXBUPRSC.mjs.map +1 -0
- package/dist/sdk/{routing-5U4Z5KI2.mjs → routing-PTYHW3IU.mjs} +4 -4
- package/dist/sdk/{schedule-tool-MVXQWDE2.mjs → schedule-tool-K5LTUYHP.mjs} +5 -5
- package/dist/sdk/{schedule-tool-7VHYOB5O.mjs → schedule-tool-SLR7ZHBZ.mjs} +2 -2
- package/dist/sdk/{schedule-tool-handler-VYXBBOB6.mjs → schedule-tool-handler-5HKGK5IL.mjs} +5 -5
- package/dist/sdk/{schedule-tool-handler-NY67TD3Y.mjs → schedule-tool-handler-XVHYK4KT.mjs} +2 -2
- package/dist/sdk/sdk.js +22 -1
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -4
- package/dist/sdk/slack-frontend-6KDUMDDI.mjs +896 -0
- package/dist/sdk/slack-frontend-6KDUMDDI.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-GI65SVE2.mjs → trace-helpers-NSPBKLBU.mjs} +2 -2
- package/dist/sdk/{workflow-check-provider-6QS4QI55.mjs → workflow-check-provider-KWXTBIV2.mjs} +5 -5
- package/dist/sdk/{workflow-check-provider-PJSFGBCM.mjs → workflow-check-provider-NYBQAYVH.mjs} +2 -2
- package/dist/slack/client.d.ts +9 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/socket-runner.d.ts +27 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/traces/{run-2026-03-04T15-57-32-312Z.ndjson → run-2026-03-04T18-12-39-729Z.ndjson} +84 -84
- package/dist/traces/{run-2026-03-04T15-58-17-868Z.ndjson → run-2026-03-04T18-13-23-673Z.ndjson} +1761 -1761
- package/package.json +1 -1
- /package/dist/sdk/{check-provider-registry-2HT3USLQ.mjs.map → check-provider-registry-7ZHNM7YO.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-CQTR5OVS.mjs.map → check-provider-registry-GJ4EZAIO.mjs.map} +0 -0
- /package/dist/sdk/{chunk-PW3RK2IS.mjs.map → chunk-D7STLGAD.mjs.map} +0 -0
- /package/dist/sdk/{chunk-RH7C77KY.mjs.map → chunk-E7QWTDTC.mjs.map} +0 -0
- /package/dist/sdk/{chunk-ZPRIWRM2.mjs.map → chunk-JBLYMLQJ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-AU6RDTY4.mjs.map → chunk-MLMI3N35.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-TCB66TZU.mjs.map → failure-condition-evaluator-NZGTI5SZ.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-6C7WVBEL.mjs.map → github-frontend-6U46M2ZI.mjs.map} +0 -0
- /package/dist/sdk/{host-LKPQXXCY.mjs.map → host-4ONWAJ6Q.mjs.map} +0 -0
- /package/dist/sdk/{routing-5U4Z5KI2.mjs.map → routing-PTYHW3IU.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-7VHYOB5O.mjs.map → schedule-tool-K5LTUYHP.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-MVXQWDE2.mjs.map → schedule-tool-SLR7ZHBZ.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-NY67TD3Y.mjs.map → schedule-tool-handler-5HKGK5IL.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-VYXBBOB6.mjs.map → schedule-tool-handler-XVHYK4KT.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-GI65SVE2.mjs.map → trace-helpers-NSPBKLBU.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-6QS4QI55.mjs.map → workflow-check-provider-KWXTBIV2.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-PJSFGBCM.mjs.map → workflow-check-provider-NYBQAYVH.mjs.map} +0 -0
package/dist/cli-main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli-main.ts"],"names":[],"mappings":"AA6zBA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli-main.ts"],"names":[],"mappings":"AA6zBA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA08C1C"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.env.VISOR_VERSION = '0.1.
|
|
2
|
+
process.env.VISOR_VERSION = '0.1.155';
|
|
3
3
|
process.env.PROBE_VERSION = '0.6.0-rc271';
|
|
4
|
-
process.env.VISOR_COMMIT_SHA = '
|
|
5
|
-
process.env.VISOR_COMMIT_SHORT = '
|
|
4
|
+
process.env.VISOR_COMMIT_SHA = '37220799c91e64df29a72348ad88a26bd94f6214';
|
|
5
|
+
process.env.VISOR_COMMIT_SHORT = '37220799';
|
|
6
6
|
/******/ (() => { // webpackBootstrap
|
|
7
7
|
/******/ var __webpack_modules__ = ({
|
|
8
8
|
|
|
@@ -162275,6 +162275,8 @@ async function main() {
|
|
|
162275
162275
|
await runner.start();
|
|
162276
162276
|
console.log('✅ Slack Socket Mode is running. Press Ctrl+C to exit.');
|
|
162277
162277
|
// Start config file watcher if --watch is enabled
|
|
162278
|
+
let configWatcher;
|
|
162279
|
+
let configWatchStore;
|
|
162278
162280
|
if (options.watch) {
|
|
162279
162281
|
if (!options.configPath) {
|
|
162280
162282
|
console.error('❌ --watch requires --config <path>');
|
|
@@ -162298,23 +162300,34 @@ async function main() {
|
|
|
162298
162300
|
});
|
|
162299
162301
|
const watcher = new ConfigWatcher(options.configPath, reloader);
|
|
162300
162302
|
watcher.start();
|
|
162303
|
+
configWatcher = watcher;
|
|
162304
|
+
configWatchStore = watchStore;
|
|
162301
162305
|
logger_1.logger.info('Config watching enabled');
|
|
162302
|
-
// Clean up watcher resources on process shutdown, then re-raise
|
|
162303
|
-
// the signal so the default handler (or other listeners) can terminate.
|
|
162304
|
-
const onSignal = (sig) => {
|
|
162305
|
-
watcher.stop();
|
|
162306
|
-
watchStore.shutdown().catch(() => { });
|
|
162307
|
-
process.removeListener('SIGINT', onSignal);
|
|
162308
|
-
process.removeListener('SIGTERM', onSignal);
|
|
162309
|
-
process.kill(process.pid, sig);
|
|
162310
|
-
};
|
|
162311
|
-
process.on('SIGINT', onSignal);
|
|
162312
|
-
process.on('SIGTERM', onSignal);
|
|
162313
162306
|
}
|
|
162314
162307
|
catch (watchErr) {
|
|
162315
162308
|
logger_1.logger.warn(`Config watch setup failed (Slack mode continues without it): ${watchErr}`);
|
|
162316
162309
|
}
|
|
162317
162310
|
}
|
|
162311
|
+
// Graceful shutdown: notify active threads before exiting
|
|
162312
|
+
let shuttingDown = false;
|
|
162313
|
+
const onShutdown = async (sig) => {
|
|
162314
|
+
if (shuttingDown)
|
|
162315
|
+
return;
|
|
162316
|
+
shuttingDown = true;
|
|
162317
|
+
logger_1.logger.info(`[Slack] Received ${sig}, shutting down gracefully…`);
|
|
162318
|
+
if (configWatcher)
|
|
162319
|
+
configWatcher.stop();
|
|
162320
|
+
if (configWatchStore)
|
|
162321
|
+
configWatchStore.shutdown().catch(() => { });
|
|
162322
|
+
await runner.stop();
|
|
162323
|
+
process.exit(0);
|
|
162324
|
+
};
|
|
162325
|
+
process.on('SIGINT', sig => {
|
|
162326
|
+
onShutdown(sig);
|
|
162327
|
+
});
|
|
162328
|
+
process.on('SIGTERM', sig => {
|
|
162329
|
+
onShutdown(sig);
|
|
162330
|
+
});
|
|
162318
162331
|
process.stdin.resume();
|
|
162319
162332
|
return;
|
|
162320
162333
|
}
|
|
@@ -197254,6 +197267,23 @@ class SlackClient {
|
|
|
197254
197267
|
}
|
|
197255
197268
|
},
|
|
197256
197269
|
};
|
|
197270
|
+
views = {
|
|
197271
|
+
publish: async ({ user_id, view, }) => {
|
|
197272
|
+
try {
|
|
197273
|
+
const resp = await this.api('views.publish', { user_id, view });
|
|
197274
|
+
if (!resp || resp.ok !== true) {
|
|
197275
|
+
const err = (resp && resp.error) || 'unknown_error';
|
|
197276
|
+
console.warn(`Slack views.publish failed (non-fatal): ${err}`);
|
|
197277
|
+
return { ok: false, error: err };
|
|
197278
|
+
}
|
|
197279
|
+
return { ok: true };
|
|
197280
|
+
}
|
|
197281
|
+
catch (e) {
|
|
197282
|
+
console.warn(`Slack views.publish threw (non-fatal): ${e instanceof Error ? e.message : String(e)}`);
|
|
197283
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
197284
|
+
}
|
|
197285
|
+
},
|
|
197286
|
+
};
|
|
197257
197287
|
getWebClient() {
|
|
197258
197288
|
return {
|
|
197259
197289
|
conversations: {
|
|
@@ -198381,6 +198411,7 @@ class SlackSocketRunner {
|
|
|
198381
198411
|
retryCount = 0;
|
|
198382
198412
|
genericScheduler;
|
|
198383
198413
|
messageTriggerEvaluator;
|
|
198414
|
+
activeThreads = new Set();
|
|
198384
198415
|
constructor(engine, cfg, opts) {
|
|
198385
198416
|
const app = opts.appToken || process.env.SLACK_APP_TOKEN || '';
|
|
198386
198417
|
if (!app)
|
|
@@ -198688,6 +198719,11 @@ class SlackSocketRunner {
|
|
|
198688
198719
|
await this.ensureClient();
|
|
198689
198720
|
}
|
|
198690
198721
|
catch { }
|
|
198722
|
+
// Handle app_home_opened — publish Home tab view and return early
|
|
198723
|
+
if (type === 'app_home_opened') {
|
|
198724
|
+
await this.publishAppHome(String(ev.user || ''));
|
|
198725
|
+
return;
|
|
198726
|
+
}
|
|
198691
198727
|
// Ignore edited/changed events to prevent loops (allow file_share — users can share attachments)
|
|
198692
198728
|
if (subtype &&
|
|
198693
198729
|
subtype !== 'thread_broadcast' &&
|
|
@@ -198918,6 +198954,9 @@ class SlackSocketRunner {
|
|
|
198918
198954
|
}
|
|
198919
198955
|
catch { }
|
|
198920
198956
|
logger_1.logger.info('[SlackSocket] Dispatching engine run for Slack event');
|
|
198957
|
+
const trackChannel = String(ev.channel || '');
|
|
198958
|
+
const trackThreadTs = String(ev.thread_ts || ev.ts || ev.event_ts || '');
|
|
198959
|
+
const threadKey = trackChannel && trackThreadTs ? this.trackThread(trackChannel, trackThreadTs) : '';
|
|
198921
198960
|
try {
|
|
198922
198961
|
// Rate limiting (optional)
|
|
198923
198962
|
const userId = String(ev.user || 'unknown');
|
|
@@ -199004,6 +199043,10 @@ class SlackSocketRunner {
|
|
|
199004
199043
|
catch (e) {
|
|
199005
199044
|
logger_1.logger.error(`[SlackSocket] Engine execution failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
199006
199045
|
}
|
|
199046
|
+
finally {
|
|
199047
|
+
if (threadKey)
|
|
199048
|
+
this.untrackThread(threadKey);
|
|
199049
|
+
}
|
|
199007
199050
|
}
|
|
199008
199051
|
/**
|
|
199009
199052
|
* Dispatch a matched message trigger as an asynchronous workflow execution.
|
|
@@ -199015,121 +199058,334 @@ class SlackSocketRunner {
|
|
|
199015
199058
|
const ts = String(ev.ts || ev.event_ts || '');
|
|
199016
199059
|
const threadTs = ev.thread_ts ? String(ev.thread_ts) : undefined;
|
|
199017
199060
|
const user = String(ev.user || 'unknown');
|
|
199061
|
+
const replyTs = threadTs || ts;
|
|
199062
|
+
const threadKey = channel && replyTs ? this.trackThread(channel, replyTs) : '';
|
|
199018
199063
|
logger_1.logger.info(`[SlackSocket] Message trigger '${id}' matched → workflow="${trigger.workflow}" channel=${channel} ts=${ts}`);
|
|
199019
|
-
// Verify workflow exists
|
|
199020
|
-
const allChecks = Object.keys(this.cfg.checks || {});
|
|
199021
|
-
if (!allChecks.includes(trigger.workflow)) {
|
|
199022
|
-
logger_1.logger.error(`[SlackSocket] Message trigger '${id}': workflow "${trigger.workflow}" not found in configuration`);
|
|
199023
|
-
return;
|
|
199024
|
-
}
|
|
199025
|
-
// Build conversation context (for thread replies, fetch full thread)
|
|
199026
|
-
let conversationContext = undefined;
|
|
199027
199064
|
try {
|
|
199028
|
-
|
|
199029
|
-
|
|
199030
|
-
|
|
199031
|
-
|
|
199032
|
-
|
|
199033
|
-
|
|
199034
|
-
|
|
199035
|
-
|
|
199036
|
-
|
|
199037
|
-
|
|
199038
|
-
|
|
199039
|
-
|
|
199040
|
-
|
|
199041
|
-
|
|
199065
|
+
// Verify workflow exists
|
|
199066
|
+
const allChecks = Object.keys(this.cfg.checks || {});
|
|
199067
|
+
if (!allChecks.includes(trigger.workflow)) {
|
|
199068
|
+
logger_1.logger.error(`[SlackSocket] Message trigger '${id}': workflow "${trigger.workflow}" not found in configuration`);
|
|
199069
|
+
return;
|
|
199070
|
+
}
|
|
199071
|
+
// Build conversation context (for thread replies, fetch full thread)
|
|
199072
|
+
let conversationContext = undefined;
|
|
199073
|
+
try {
|
|
199074
|
+
const isThreadReply = !!threadTs && threadTs !== ts;
|
|
199075
|
+
if (isThreadReply) {
|
|
199076
|
+
const adapter = this.getSlackAdapter();
|
|
199077
|
+
if (adapter && channel && threadTs) {
|
|
199078
|
+
const cleanedText = String(ev.text || '')
|
|
199079
|
+
.replace(/<@[A-Z0-9]+>/g, '')
|
|
199080
|
+
.trim();
|
|
199081
|
+
conversationContext = await adapter.fetchConversation(channel, threadTs, {
|
|
199082
|
+
ts,
|
|
199083
|
+
user,
|
|
199084
|
+
text: cleanedText || String(ev.text || ''),
|
|
199085
|
+
timestamp: Date.now(),
|
|
199086
|
+
files: Array.isArray(ev.files) ? ev.files : undefined,
|
|
199087
|
+
});
|
|
199088
|
+
}
|
|
199042
199089
|
}
|
|
199043
199090
|
}
|
|
199091
|
+
catch (err) {
|
|
199092
|
+
logger_1.logger.warn(`[SlackSocket] Message trigger '${id}': conversation context fetch failed: ${err instanceof Error ? err.message : err}`);
|
|
199093
|
+
}
|
|
199094
|
+
// Build synthetic webhook payload
|
|
199095
|
+
const triggerPayload = {
|
|
199096
|
+
...payload,
|
|
199097
|
+
trigger: {
|
|
199098
|
+
id,
|
|
199099
|
+
type: 'on_message',
|
|
199100
|
+
workflow: trigger.workflow,
|
|
199101
|
+
},
|
|
199102
|
+
...(conversationContext ? { slack_conversation: conversationContext } : {}),
|
|
199103
|
+
};
|
|
199104
|
+
const webhookData = new Map();
|
|
199105
|
+
webhookData.set(this.endpoint, triggerPayload);
|
|
199106
|
+
// Clone config for this run with Slack frontend
|
|
199107
|
+
const cfgForRun = (() => {
|
|
199108
|
+
try {
|
|
199109
|
+
const cfg = JSON.parse(JSON.stringify(this.cfg));
|
|
199110
|
+
const fronts = Array.isArray(cfg.frontends) ? cfg.frontends : [];
|
|
199111
|
+
if (!fronts.some((f) => f && f.name === 'slack'))
|
|
199112
|
+
fronts.push({ name: 'slack' });
|
|
199113
|
+
cfg.frontends = fronts;
|
|
199114
|
+
return cfg;
|
|
199115
|
+
}
|
|
199116
|
+
catch {
|
|
199117
|
+
return this.cfg;
|
|
199118
|
+
}
|
|
199119
|
+
})();
|
|
199120
|
+
// Derive stable workspace name from thread identity
|
|
199121
|
+
const wsThreadTs = threadTs || ts;
|
|
199122
|
+
if (channel && wsThreadTs) {
|
|
199123
|
+
const hash = (0, crypto_1.createHash)('sha256')
|
|
199124
|
+
.update(`${channel}:${wsThreadTs}`)
|
|
199125
|
+
.digest('hex')
|
|
199126
|
+
.slice(0, 8);
|
|
199127
|
+
const workspaceName = `slack-trigger-${hash}`;
|
|
199128
|
+
if (!cfgForRun.workspace) {
|
|
199129
|
+
cfgForRun.workspace = {};
|
|
199130
|
+
}
|
|
199131
|
+
cfgForRun.workspace.name = workspaceName;
|
|
199132
|
+
cfgForRun.workspace.cleanup_on_exit = false;
|
|
199133
|
+
}
|
|
199134
|
+
// Create a dedicated engine instance for this trigger
|
|
199135
|
+
const runEngine = new state_machine_execution_engine_1.StateMachineExecutionEngine();
|
|
199136
|
+
await this.ensureClient();
|
|
199137
|
+
try {
|
|
199138
|
+
const parentCtx = this.engine.getExecutionContext?.() || {};
|
|
199139
|
+
const prevCtx = runEngine.getExecutionContext?.() || {};
|
|
199140
|
+
runEngine.setExecutionContext?.({
|
|
199141
|
+
...parentCtx,
|
|
199142
|
+
...prevCtx,
|
|
199143
|
+
slack: this.client || parentCtx.slack,
|
|
199144
|
+
slackClient: this.client || parentCtx.slackClient,
|
|
199145
|
+
});
|
|
199146
|
+
}
|
|
199147
|
+
catch { }
|
|
199148
|
+
// Refresh GitHub credentials
|
|
199149
|
+
try {
|
|
199150
|
+
const { refreshGitHubCredentials } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(11347)));
|
|
199151
|
+
await refreshGitHubCredentials();
|
|
199152
|
+
}
|
|
199153
|
+
catch { }
|
|
199154
|
+
await (0, trace_helpers_1.withActiveSpan)('visor.run', {
|
|
199155
|
+
...(0, trace_helpers_1.getVisorRunAttributes)(),
|
|
199156
|
+
'visor.run.source': 'slack_message_trigger',
|
|
199157
|
+
'visor.trigger.id': id,
|
|
199158
|
+
'visor.trigger.workflow': trigger.workflow,
|
|
199159
|
+
'slack.channel_id': channel,
|
|
199160
|
+
'slack.thread_ts': threadTs || ts,
|
|
199161
|
+
'slack.user_id': user,
|
|
199162
|
+
}, async () => {
|
|
199163
|
+
await runEngine.executeChecks({
|
|
199164
|
+
checks: [trigger.workflow],
|
|
199165
|
+
showDetails: true,
|
|
199166
|
+
outputFormat: 'json',
|
|
199167
|
+
config: cfgForRun,
|
|
199168
|
+
webhookContext: { webhookData, eventType: 'slack_message' },
|
|
199169
|
+
debug: process.env.VISOR_DEBUG === 'true',
|
|
199170
|
+
inputs: trigger.inputs,
|
|
199171
|
+
});
|
|
199172
|
+
});
|
|
199173
|
+
logger_1.logger.info(`[SlackSocket] Message trigger '${id}' workflow completed`);
|
|
199044
199174
|
}
|
|
199045
|
-
|
|
199046
|
-
|
|
199175
|
+
finally {
|
|
199176
|
+
if (threadKey)
|
|
199177
|
+
this.untrackThread(threadKey);
|
|
199047
199178
|
}
|
|
199048
|
-
|
|
199049
|
-
|
|
199050
|
-
|
|
199051
|
-
|
|
199052
|
-
|
|
199053
|
-
|
|
199054
|
-
|
|
199055
|
-
|
|
199056
|
-
|
|
199057
|
-
|
|
199058
|
-
|
|
199059
|
-
|
|
199060
|
-
|
|
199061
|
-
|
|
199179
|
+
}
|
|
199180
|
+
trackThread(channel, threadTs) {
|
|
199181
|
+
const key = `${channel}:${threadTs}`;
|
|
199182
|
+
this.activeThreads.add(key);
|
|
199183
|
+
return key;
|
|
199184
|
+
}
|
|
199185
|
+
untrackThread(key) {
|
|
199186
|
+
this.activeThreads.delete(key);
|
|
199187
|
+
}
|
|
199188
|
+
/**
|
|
199189
|
+
* Send a best-effort shutdown notice to all active Slack threads.
|
|
199190
|
+
* Bounded by timeoutMs so we never block process exit indefinitely.
|
|
199191
|
+
*/
|
|
199192
|
+
async notifyActiveThreadsOfShutdown(timeoutMs = 5000) {
|
|
199193
|
+
if (this.activeThreads.size === 0 || !this.client)
|
|
199194
|
+
return;
|
|
199195
|
+
const msg = ':warning: The bot was restarted. Your request was interrupted and could not be completed. Please retry by sending your message again.';
|
|
199196
|
+
const promises = [...this.activeThreads].map(key => {
|
|
199197
|
+
const [channel, threadTs] = key.split(':');
|
|
199198
|
+
return this.client.chat.postMessage({ channel, thread_ts: threadTs, text: msg }).catch(err => {
|
|
199199
|
+
logger_1.logger.warn(`[SlackSocket] Failed to notify thread ${key} of shutdown: ${err instanceof Error ? err.message : err}`);
|
|
199200
|
+
});
|
|
199201
|
+
});
|
|
199202
|
+
try {
|
|
199203
|
+
let timer;
|
|
199204
|
+
await Promise.race([
|
|
199205
|
+
Promise.allSettled(promises),
|
|
199206
|
+
new Promise(resolve => {
|
|
199207
|
+
timer = setTimeout(resolve, timeoutMs);
|
|
199208
|
+
}),
|
|
199209
|
+
]);
|
|
199210
|
+
if (timer)
|
|
199211
|
+
clearTimeout(timer);
|
|
199212
|
+
}
|
|
199213
|
+
catch {
|
|
199214
|
+
// best effort
|
|
199215
|
+
}
|
|
199216
|
+
}
|
|
199217
|
+
/**
|
|
199218
|
+
* Publish the App Home tab for the given user.
|
|
199219
|
+
* Shows the user's schedules, message triggers, and available workflows.
|
|
199220
|
+
*/
|
|
199221
|
+
async publishAppHome(userId) {
|
|
199222
|
+
if (!userId || !this.client)
|
|
199223
|
+
return;
|
|
199224
|
+
try {
|
|
199225
|
+
const userInfo = await this.fetchUserInfo(userId);
|
|
199226
|
+
// Fetch user's schedules and triggers from the store (best-effort)
|
|
199227
|
+
let schedules = [];
|
|
199228
|
+
let triggers = [];
|
|
199062
199229
|
try {
|
|
199063
|
-
const
|
|
199064
|
-
|
|
199065
|
-
|
|
199066
|
-
|
|
199067
|
-
|
|
199068
|
-
return cfg;
|
|
199230
|
+
const store = schedule_store_1.ScheduleStore.getInstance();
|
|
199231
|
+
if (store.isInitialized()) {
|
|
199232
|
+
schedules = await store.getByCreatorAsync(userId);
|
|
199233
|
+
triggers = await store.getTriggersByCreatorAsync(userId);
|
|
199234
|
+
}
|
|
199069
199235
|
}
|
|
199070
|
-
catch {
|
|
199071
|
-
|
|
199236
|
+
catch (err) {
|
|
199237
|
+
logger_1.logger.warn(`[SlackSocket] Failed to fetch schedules/triggers for Home tab: ${err instanceof Error ? err.message : err}`);
|
|
199072
199238
|
}
|
|
199073
|
-
|
|
199074
|
-
|
|
199075
|
-
|
|
199076
|
-
|
|
199077
|
-
|
|
199078
|
-
|
|
199079
|
-
|
|
199080
|
-
|
|
199081
|
-
const workspaceName = `slack-trigger-${hash}`;
|
|
199082
|
-
if (!cfgForRun.workspace) {
|
|
199083
|
-
cfgForRun.workspace = {};
|
|
199239
|
+
// Get available workflows
|
|
199240
|
+
let workflows = [];
|
|
199241
|
+
try {
|
|
199242
|
+
const { WorkflowRegistry } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(82824)));
|
|
199243
|
+
const registry = WorkflowRegistry.getInstance();
|
|
199244
|
+
workflows = registry
|
|
199245
|
+
.list()
|
|
199246
|
+
.map(w => ({ id: w.id, name: w.name, description: w.description }));
|
|
199084
199247
|
}
|
|
199085
|
-
|
|
199086
|
-
|
|
199248
|
+
catch (err) {
|
|
199249
|
+
logger_1.logger.warn(`[SlackSocket] Failed to fetch workflows for Home tab: ${err instanceof Error ? err.message : err}`);
|
|
199250
|
+
}
|
|
199251
|
+
const blocks = this.buildHomeBlocks(userInfo, schedules, triggers, workflows);
|
|
199252
|
+
await this.client.views.publish({
|
|
199253
|
+
user_id: userId,
|
|
199254
|
+
view: { type: 'home', blocks },
|
|
199255
|
+
});
|
|
199087
199256
|
}
|
|
199088
|
-
|
|
199089
|
-
|
|
199090
|
-
|
|
199091
|
-
|
|
199092
|
-
|
|
199093
|
-
|
|
199094
|
-
|
|
199095
|
-
|
|
199096
|
-
|
|
199097
|
-
|
|
199098
|
-
|
|
199257
|
+
catch (err) {
|
|
199258
|
+
logger_1.logger.error(`[SlackSocket] app_home_opened failed: ${err instanceof Error ? err.message : err}`);
|
|
199259
|
+
}
|
|
199260
|
+
}
|
|
199261
|
+
/**
|
|
199262
|
+
* Build Slack Block Kit blocks for the App Home tab.
|
|
199263
|
+
* Exposed as a separate method for testability.
|
|
199264
|
+
*/
|
|
199265
|
+
buildHomeBlocks(userInfo, schedules, triggers, workflows) {
|
|
199266
|
+
const blocks = [];
|
|
199267
|
+
// Header
|
|
199268
|
+
const greeting = userInfo?.realName || userInfo?.name || 'there';
|
|
199269
|
+
blocks.push({
|
|
199270
|
+
type: 'header',
|
|
199271
|
+
text: { type: 'plain_text', text: `Hi, ${greeting}!` },
|
|
199272
|
+
});
|
|
199273
|
+
blocks.push({
|
|
199274
|
+
type: 'section',
|
|
199275
|
+
text: { type: 'mrkdwn', text: "Here's an overview of your Visor activity." },
|
|
199276
|
+
});
|
|
199277
|
+
blocks.push({ type: 'divider' });
|
|
199278
|
+
// --- Schedules section ---
|
|
199279
|
+
blocks.push({
|
|
199280
|
+
type: 'header',
|
|
199281
|
+
text: { type: 'plain_text', text: 'Your Schedules' },
|
|
199282
|
+
});
|
|
199283
|
+
const activeSchedules = schedules.filter(s => s.status === 'active' || s.status === 'paused');
|
|
199284
|
+
if (activeSchedules.length === 0) {
|
|
199285
|
+
blocks.push({
|
|
199286
|
+
type: 'section',
|
|
199287
|
+
text: { type: 'mrkdwn', text: '_No active schedules. Message the bot to create one._' },
|
|
199099
199288
|
});
|
|
199100
199289
|
}
|
|
199101
|
-
|
|
199102
|
-
|
|
199103
|
-
|
|
199104
|
-
|
|
199105
|
-
|
|
199290
|
+
else {
|
|
199291
|
+
for (const s of activeSchedules.slice(0, 15)) {
|
|
199292
|
+
const statusIcon = s.status === 'paused' ? ':double_vertical_bar:' : ':clock1:';
|
|
199293
|
+
const desc = s.originalExpression || s.workflow || s.id;
|
|
199294
|
+
const nextRun = s.nextRunAt
|
|
199295
|
+
? `<!date^${Math.floor(s.nextRunAt / 1000)}^{date_short_pretty} at {time}|${new Date(s.nextRunAt).toISOString()}>`
|
|
199296
|
+
: 'N/A';
|
|
199297
|
+
const recurring = s.isRecurring ? `\`${s.schedule}\`` : 'one-time';
|
|
199298
|
+
blocks.push({
|
|
199299
|
+
type: 'section',
|
|
199300
|
+
text: {
|
|
199301
|
+
type: 'mrkdwn',
|
|
199302
|
+
text: `${statusIcon} *${desc}*\n${recurring} · Next: ${nextRun} · Status: \`${s.status}\``,
|
|
199303
|
+
},
|
|
199304
|
+
});
|
|
199305
|
+
}
|
|
199306
|
+
if (activeSchedules.length > 15) {
|
|
199307
|
+
blocks.push({
|
|
199308
|
+
type: 'context',
|
|
199309
|
+
elements: [{ type: 'mrkdwn', text: `_…and ${activeSchedules.length - 15} more_` }],
|
|
199310
|
+
});
|
|
199311
|
+
}
|
|
199106
199312
|
}
|
|
199107
|
-
|
|
199108
|
-
|
|
199109
|
-
|
|
199110
|
-
|
|
199111
|
-
'
|
|
199112
|
-
|
|
199113
|
-
|
|
199114
|
-
|
|
199115
|
-
|
|
199116
|
-
|
|
199117
|
-
|
|
199118
|
-
checks: [trigger.workflow],
|
|
199119
|
-
showDetails: true,
|
|
199120
|
-
outputFormat: 'json',
|
|
199121
|
-
config: cfgForRun,
|
|
199122
|
-
webhookContext: { webhookData, eventType: 'slack_message' },
|
|
199123
|
-
debug: process.env.VISOR_DEBUG === 'true',
|
|
199124
|
-
inputs: trigger.inputs,
|
|
199313
|
+
blocks.push({ type: 'divider' });
|
|
199314
|
+
// --- Triggers section ---
|
|
199315
|
+
blocks.push({
|
|
199316
|
+
type: 'header',
|
|
199317
|
+
text: { type: 'plain_text', text: 'Your Message Triggers' },
|
|
199318
|
+
});
|
|
199319
|
+
const activeTriggers = triggers.filter(t => t.status === 'active');
|
|
199320
|
+
if (activeTriggers.length === 0) {
|
|
199321
|
+
blocks.push({
|
|
199322
|
+
type: 'section',
|
|
199323
|
+
text: { type: 'mrkdwn', text: '_No active message triggers._' },
|
|
199125
199324
|
});
|
|
199325
|
+
}
|
|
199326
|
+
else {
|
|
199327
|
+
for (const t of activeTriggers.slice(0, 10)) {
|
|
199328
|
+
const enabledIcon = t.enabled ? ':large_green_circle:' : ':white_circle:';
|
|
199329
|
+
const desc = t.description || t.workflow;
|
|
199330
|
+
const filters = [];
|
|
199331
|
+
if (t.channels?.length)
|
|
199332
|
+
filters.push(`channels: ${t.channels.join(', ')}`);
|
|
199333
|
+
if (t.contains?.length)
|
|
199334
|
+
filters.push(`contains: ${t.contains.join(', ')}`);
|
|
199335
|
+
if (t.matchPattern)
|
|
199336
|
+
filters.push(`pattern: \`${t.matchPattern}\``);
|
|
199337
|
+
blocks.push({
|
|
199338
|
+
type: 'section',
|
|
199339
|
+
text: {
|
|
199340
|
+
type: 'mrkdwn',
|
|
199341
|
+
text: `${enabledIcon} *${desc}*\n${filters.join(' · ') || 'no filters'} → \`${t.workflow}\``,
|
|
199342
|
+
},
|
|
199343
|
+
});
|
|
199344
|
+
}
|
|
199345
|
+
if (activeTriggers.length > 10) {
|
|
199346
|
+
blocks.push({
|
|
199347
|
+
type: 'context',
|
|
199348
|
+
elements: [{ type: 'mrkdwn', text: `_…and ${activeTriggers.length - 10} more_` }],
|
|
199349
|
+
});
|
|
199350
|
+
}
|
|
199351
|
+
}
|
|
199352
|
+
blocks.push({ type: 'divider' });
|
|
199353
|
+
// --- Workflows section ---
|
|
199354
|
+
blocks.push({
|
|
199355
|
+
type: 'header',
|
|
199356
|
+
text: { type: 'plain_text', text: 'Available Workflows' },
|
|
199126
199357
|
});
|
|
199127
|
-
|
|
199358
|
+
if (workflows.length === 0) {
|
|
199359
|
+
blocks.push({
|
|
199360
|
+
type: 'section',
|
|
199361
|
+
text: { type: 'mrkdwn', text: '_No workflows registered._' },
|
|
199362
|
+
});
|
|
199363
|
+
}
|
|
199364
|
+
else {
|
|
199365
|
+
for (const w of workflows.slice(0, 15)) {
|
|
199366
|
+
blocks.push({
|
|
199367
|
+
type: 'section',
|
|
199368
|
+
text: {
|
|
199369
|
+
type: 'mrkdwn',
|
|
199370
|
+
text: `*${w.name || w.id}*${w.description ? `\n${w.description}` : ''}`,
|
|
199371
|
+
},
|
|
199372
|
+
});
|
|
199373
|
+
}
|
|
199374
|
+
if (workflows.length > 15) {
|
|
199375
|
+
blocks.push({
|
|
199376
|
+
type: 'context',
|
|
199377
|
+
elements: [{ type: 'mrkdwn', text: `_…and ${workflows.length - 15} more_` }],
|
|
199378
|
+
});
|
|
199379
|
+
}
|
|
199380
|
+
}
|
|
199381
|
+
return blocks;
|
|
199128
199382
|
}
|
|
199129
199383
|
/**
|
|
199130
199384
|
* Stop the socket runner and clean up resources
|
|
199131
199385
|
*/
|
|
199132
199386
|
async stop() {
|
|
199387
|
+
// Notify active threads before tearing down
|
|
199388
|
+
await this.notifyActiveThreadsOfShutdown();
|
|
199133
199389
|
// Stop background GitHub App token refresh
|
|
199134
199390
|
try {
|
|
199135
199391
|
const { stopTokenRefreshTimer } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(11347)));
|
|
@@ -395353,7 +395609,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"100":"Continue","101":"Switching Pro
|
|
|
395353
395609
|
/***/ ((module) => {
|
|
395354
395610
|
|
|
395355
395611
|
"use strict";
|
|
395356
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.
|
|
395612
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.155","main":"dist/index.js","bin":{"visor":"./dist/index.js"},"exports":{".":{"require":"./dist/index.js","import":"./dist/index.js"},"./sdk":{"types":"./dist/sdk/sdk.d.ts","import":"./dist/sdk/sdk.mjs","require":"./dist/sdk/sdk.js"},"./cli":{"require":"./dist/index.js"}},"files":["dist/","defaults/","action.yml","README.md","LICENSE"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build:cli":"ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo \'#!/usr/bin/env node\' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js","build:sdk":"tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk","build":"./scripts/build-oss.sh","build:ee":"npm run build:cli && npm run build:sdk","test":"jest && npm run test:yaml","test:unit":"jest","prepublishOnly":"npm run build","test:watch":"jest --watch","test:coverage":"jest --coverage","test:ee":"jest --testPathPatterns=\'tests/ee\' --testPathIgnorePatterns=\'/node_modules/\' --no-coverage","test:manual:bash":"RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts","lint":"eslint src tests --ext .ts","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write src tests","format:check":"prettier --check src tests","clean":"","clean:traces":"node scripts/clean-traces.js","prebuild":"npm run clean && node scripts/generate-config-schema.js","pretest":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","pretest:unit":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","test:with-build":"npm run build:cli && jest","test:yaml":"node dist/index.js test --progress compact","test:yaml:parallel":"node dist/index.js test --progress compact --max-parallel 4","prepare":"husky","pre-commit":"lint-staged","deploy:site":"cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true","deploy:worker":"npx wrangler deploy","deploy":"npm run deploy:site && npm run deploy:worker","publish:ee":"./scripts/publish-ee.sh","release":"./scripts/release.sh","release:patch":"./scripts/release.sh patch","release:minor":"./scripts/release.sh minor","release:major":"./scripts/release.sh major","release:prerelease":"./scripts/release.sh prerelease","docs:validate":"node scripts/validate-readme-links.js","workshop:setup":"npm install -D reveal-md@6.1.2","workshop:serve":"cd workshop && reveal-md slides.md -w","workshop:export":"reveal-md workshop/slides.md --static workshop/build","workshop:pdf":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter","workshop:pdf:ci":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args=\\"--no-sandbox --disable-dev-shm-usage\\"","workshop:pdf:a4":"reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4","workshop:build":"npm run workshop:export && npm run workshop:pdf","simulate:issue":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug","simulate:comment":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"},"keywords":["code-review","ai","github-action","cli","pr-review","visor"],"author":"Probe Labs","license":"MIT","description":"AI workflow engine for code review, assistants, and automation — orchestrate checks, MCP tools, and AI providers with YAML-driven pipelines","repository":{"type":"git","url":"git+https://github.com/probelabs/visor.git"},"bugs":{"url":"https://github.com/probelabs/visor/issues"},"homepage":"https://github.com/probelabs/visor#readme","dependencies":{"@actions/core":"^1.11.1","@apidevtools/swagger-parser":"^12.1.0","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9","@octokit/action":"^8.0.2","@octokit/auth-app":"^8.1.0","@octokit/core":"^7.0.3","@octokit/rest":"^22.0.0","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^1.30.1","@opentelemetry/exporter-trace-otlp-grpc":"^0.203.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/instrumentation":"^0.203.0","@opentelemetry/resources":"^1.30.1","@opentelemetry/sdk-metrics":"^1.30.1","@opentelemetry/sdk-node":"^0.203.0","@opentelemetry/sdk-trace-base":"^1.30.1","@opentelemetry/semantic-conventions":"^1.30.1","@probelabs/probe":"^0.6.0-rc271","@types/commander":"^2.12.0","@types/uuid":"^10.0.0","acorn":"^8.16.0","acorn-walk":"^8.3.5","ajv":"^8.17.1","ajv-formats":"^3.0.1","better-sqlite3":"^11.0.0","blessed":"^0.1.81","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","ignore":"^7.0.5","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","minimatch":"^10.2.2","node-cron":"^3.0.3","open":"^9.1.0","simple-git":"^3.28.0","uuid":"^11.1.0","ws":"^8.18.3"},"optionalDependencies":{"@anthropic/claude-code-sdk":"npm:null@*","@open-policy-agent/opa-wasm":"^1.10.0","knex":"^3.1.0","mysql2":"^3.11.0","pg":"^8.13.0","tedious":"^19.0.0"},"devDependencies":{"@eslint/js":"^9.34.0","@kie/act-js":"^2.6.2","@kie/mock-github":"^2.0.1","@swc/core":"^1.13.2","@swc/jest":"^0.2.37","@types/better-sqlite3":"^7.6.0","@types/blessed":"^0.1.27","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/node":"^24.3.0","@types/node-cron":"^3.0.11","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^8.42.0","@typescript-eslint/parser":"^8.42.0","@vercel/ncc":"^0.38.4","eslint":"^9.34.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","jest":"^30.1.3","lint-staged":"^16.1.6","prettier":"^3.6.2","reveal-md":"^6.1.2","ts-json-schema-generator":"^1.5.1","ts-node":"^10.9.2","tsup":"^8.5.0","typescript":"^5.9.2","wrangler":"^3.0.0"},"peerDependenciesMeta":{"@anthropic/claude-code-sdk":{"optional":true}},"directories":{"test":"tests"},"lint-staged":{"src/**/*.{ts,js}":["eslint --fix","prettier --write"],"tests/**/*.{ts,js}":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]}}');
|
|
395357
395613
|
|
|
395358
395614
|
/***/ })
|
|
395359
395615
|
|