@sentry/junior 0.257.0 → 0.259.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actor-BTtLaeWy.js → actor-tlxzqaRe.js} +3 -6
- package/dist/adapter-Bn0gFVSF.js +270 -0
- package/dist/{admin-DgIkm6Vy.js → admin-C8xz2f10.js} +2 -3
- package/dist/{agent-hooks-BjtTzvru.js → agent-hooks-B00FaKdP.js} +70 -109
- package/dist/{agent-invocations-Bdu3ROfo.js → agent-invocations-Qfz7dWgU.js} +6 -12
- package/dist/{agent-runner-D7OboVb3.js → agent-runner-CPSd7rKm.js} +324 -742
- package/dist/api/schema.d.ts +442 -447
- package/dist/api/schema.js +6 -6
- package/dist/api.d.ts +2 -12
- package/dist/api.js +165 -158
- package/dist/{app-BsU5QNBd.d.ts → app-Bbxrehjf.d.ts} +25 -45
- package/dist/app.d.ts +3 -3
- package/dist/app.js +206 -321
- package/dist/{assistant-reply-CbTPebzL.js → assistant-reply-CqthTerd.js} +3 -5
- package/dist/{automation-CHdlHVZP.js → automation-DWBFBenG.js} +6 -11
- package/dist/{briefs-oLOldnDM.js → briefs-DNYbQ9cD.js} +8 -11
- package/dist/{cadence-D00SCzT1.js → cadence-R7Em4RjE.js} +1 -2
- package/dist/{catalog-runtime-CZzhGQ7F.js → catalog-runtime-B8SuFPGb.js} +3 -4
- package/dist/cli/chat.d.ts +2 -4
- package/dist/cli/chat.js +22 -24
- package/dist/cli/check.d.ts +1 -3
- package/dist/cli/check.js +4 -5
- package/dist/cli/env.d.ts +1 -3
- package/dist/cli/env.js +1 -2
- package/dist/cli/init.d.ts +1 -3
- package/dist/cli/init.js +3 -3
- package/dist/cli/main.d.ts +1 -3
- package/dist/cli/main.js +8 -5
- package/dist/cli/plugins.d.ts +2 -4
- package/dist/cli/plugins.js +7 -8
- package/dist/cli/run.d.ts +3 -3
- package/dist/cli/run.js +3 -3
- package/dist/cli/snapshot-create.d.ts +1 -3
- package/dist/cli/snapshot-create.js +5 -5
- package/dist/cli/upgrade.d.ts +3 -6
- package/dist/cli/upgrade.js +11 -17
- package/dist/{client-D8HnkOQX.js → client-BZdxgKyL.js} +64 -18
- package/dist/{config-CJRnWK9H.js → config-Deqpfpg9.js} +21 -15
- package/dist/{connections-ClYrKzpX.js → connections-9gJkfS85.js} +179 -20
- package/dist/{conversation-CKNLYBJt.js → conversation-DjN3mlog.js} +8 -15
- package/dist/{conversation-privacy-C8b1nphZ.js → conversation-privacy-CFhNKxp-.js} +2 -3
- package/dist/{conversation-work-C6y3T5Hx.js → conversation-work-BaT_T6EB.js} +1 -2
- package/dist/{credential-sync-BXfohNmJ.js → credential-sync-BABGymK3.js} +23 -190
- package/dist/{db-Ca9Nt5ci.d.ts → db-BnRqQ7G5.d.ts} +1 -1
- package/dist/{executor-Do0THDRR.js → executor-Bb3eQb8q.js} +30 -52
- package/dist/{experimental-CQIvMUO7.js → experimental-BNK1l1jv.js} +2 -4
- package/dist/{history-9pO1Zd4Y.js → history-AY8rs-FR.js} +5 -9
- package/dist/{history-DvqWZlYX.d.ts → history-BgI33Kie.d.ts} +12 -20
- package/dist/{images-BN_BiBXF.js → images-BbSdVHC6.js} +5 -6
- package/dist/instrumentation.d.ts +1 -3
- package/dist/instrumentation.js +6 -8
- package/dist/{job-queue-B6SV9uVa.js → job-queue-vdGU-5ge.js} +6 -12
- package/dist/{logging-CWxiIuCF.js → logging-BStXN56b.js} +7 -12
- package/dist/{message-TUOdbSBW.js → message-DRf6m4uO.js} +5 -6
- package/dist/{model-profile-BwU8mqwD.js → model-profile-Bg8EoCKD.js} +2 -4
- package/dist/nitro.d.ts +3 -5
- package/dist/nitro.js +12 -17
- package/dist/{oauth-authorization-BA4Dt6a7.js → oauth-authorization-djQn5Nhy.js} +2 -4
- package/dist/{oauth-callback-server-Dj5UJODo.js → oauth-callback-server-JmOgLcGl.js} +3 -4
- package/dist/{oauth-relay-CdCnu80W.js → oauth-relay-CTygMkNx.js} +2 -3
- package/dist/{package-discovery-BVvSnQBB.js → package-discovery-DJBompdd.js} +17 -21
- package/dist/{pending-auth-s_QFribU.js → pending-auth-rG5U_QS1.js} +92 -83
- package/dist/{plugin-module-CVvEUSMH.js → plugin-module-Cf5gVPWP.js} +1 -2
- package/dist/{plugins-CjfUP5gJ.d.ts → plugins-B_0Cr0MO.d.ts} +5 -5
- package/dist/{plugins-egKWjgue.js → plugins-DOm9Y6qI.js} +2 -3
- package/dist/{private-trace-result-BLvBjy_e.js → private-trace-result-CE7_lEdq.js} +1 -2
- package/dist/{profile-h-72wM78.js → profile-qBM6B_-V.js} +14 -295
- package/dist/{prompt-DyoEj9c2.js → prompt-xgpyMtg7.js} +5 -9
- package/dist/{queue-B5SnqRln.d.ts → queue-C37RbDVc.d.ts} +0 -2
- package/dist/{registry-sLTr-sV9.js → registry-B_M_x_iS.js} +56 -30
- package/dist/{resolve-ncQPZROQ.js → resolve-BzpuLh8c.js} +8 -12
- package/dist/{result-C883vngT.js → result-DEZH_AnZ.js} +13 -17
- package/dist/{rolldown-runtime-B4FMCO8f.js → rolldown-runtime-nwUcYXjP.js} +1 -2
- package/dist/{runner-CzYImdOF.js → runner-BqQlG10t.js} +12 -13
- package/dist/{sandbox-egress-signals-CZbMINHI.js → sandbox-egress-signals-DCq3WLs5.js} +2 -3
- package/dist/{schema-Dy69D4Ge.js → schema-CF9HqNRY.js} +30 -27
- package/dist/{sentry-CgWZM_kV.js → sentry-BBUlHih9.js} +2 -3
- package/dist/service-account-BqTBkyD7.js +120 -0
- package/dist/service-account-BzhW7kXu.js +661 -0
- package/dist/{session-stop-CQjKd4a2.js → session-stop-CV65ZlU3.js} +23 -33
- package/dist/{skills-C22SLruK.js → skills-CiWS5_Ub.js} +9 -9
- package/dist/{spawn-DY9CLXDL.js → spawn-BSAQ7UQZ.js} +4 -5
- package/dist/{store-DXFIQy-G.js → store-B1GES4gC.js} +13 -15
- package/dist/{store-DoewL5mG.d.ts → store-CG0VJyye.d.ts} +0 -14
- package/dist/{task-queue-B17vV0La.js → task-queue-BAeGEMjJ.js} +5 -7
- package/dist/{task-runner-DUjvzYXj.js → task-runner-BlGhcQPi.js} +22 -26
- package/dist/{tasks-D_WIJtvO.js → tasks-DieKX3d4.js} +63 -78
- package/dist/{thread-state-Ch4yuCqG.js → thread-state-DpSWS4Rr.js} +13 -19
- package/dist/{turn-failure-response-C5nBKC4S.js → turn-failure-response-DQljogGJ.js} +16 -22
- package/dist/{turn-lifecycle-CO-ylUmV.js → turn-lifecycle-BLgrkV_L.js} +2 -3
- package/dist/{turn-session-routing-B3LWooK5.js → turn-session-routing-BlajheOU.js} +2 -3
- package/dist/{validation-CXYxaNYx.js → validation-23d7K9tX.js} +3 -4
- package/dist/vercel.d.ts +1 -3
- package/dist/vercel.js +1 -2
- package/dist/{version-BcdZy2zg.js → version-B_XumRx-.js} +3 -5
- package/dist/{version-CnXZ614E.d.ts → version-Cc2OFd9G.d.ts} +0 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -2
- package/dist/{viewer-DSZXygMU.js → viewer-B2_ABsYi.js} +26 -57
- package/dist/{web-input-B9Bv0_lR.js → web-input-BZDyxpzR.js} +101 -158
- package/dist/{web-message-id-xPI_EFSC.js → web-message-id-CJSUiksE.js} +3 -6
- package/dist/{work-nAfDSUFP.js → work-D3QKiV0O.js} +14 -16
- package/dist/{worker-vGXZ6XFT.js → worker-C8mUjYf9.js} +7 -8
- package/package.json +10 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import "@sentry/junior-plugin-api";
|
|
3
|
-
|
|
3
|
+
// src/chat/slack/timestamp.ts
|
|
4
4
|
/** Native Slack message timestamp, safe to pass as Slack Web API `message_ts`. */
|
|
5
5
|
const slackMessageTsSchema = z.string().trim().regex(/^\d+(?:\.\d+)?$/).brand();
|
|
6
6
|
/** Parse a native Slack message timestamp from untrusted message metadata. */
|
|
@@ -8,8 +8,7 @@ function parseSlackMessageTs(value) {
|
|
|
8
8
|
const parsed = slackMessageTsSchema.safeParse(value);
|
|
9
9
|
return parsed.success ? parsed.data : void 0;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
//#region src/chat/slack/ids.ts
|
|
11
|
+
// src/chat/slack/ids.ts
|
|
13
12
|
const slackChannelIdSchema = z.string().regex(/^[CDG][A-Z0-9]+$/).brand();
|
|
14
13
|
const slackTeamIdSchema = z.string().regex(/^T[A-Z0-9]+$/).brand();
|
|
15
14
|
const slackUserIdSchema = z.string().regex(/^[UW][A-Z0-9]+$/).brand();
|
|
@@ -54,8 +53,7 @@ function parseSlackUserId(value) {
|
|
|
54
53
|
const parsed = slackUserIdSchema.safeParse(value.trim());
|
|
55
54
|
return parsed.success ? parsed.data : void 0;
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
//#region src/chat/actor.ts
|
|
56
|
+
// src/chat/actor.ts
|
|
59
57
|
/**
|
|
60
58
|
* Canonical actor identity.
|
|
61
59
|
*
|
|
@@ -199,5 +197,4 @@ function createSlackResumeActor(args) {
|
|
|
199
197
|
if (!actor || actor.platform !== "slack") throw new Error("Slack actor requires team and user ids");
|
|
200
198
|
return actor;
|
|
201
199
|
}
|
|
202
|
-
//#endregion
|
|
203
200
|
export { slackMessageTsSchema as _, isUserActor as a, toStoredSlackActor as c, parseSlackTeamId as d, parseSlackUserId as f, parseSlackMessageTs as g, slackUserIdSchema as h, isActorUserId as i, parseSlackChannelId as l, slackTeamIdSchema as m, createSlackActor as n, parseActorUserId as o, slackChannelIdSchema as p, createSlackResumeActor as r, parseStoredSlackActor as s, createActor as t, parseSlackChannelReferenceId as u };
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { i as getChatConfig } from "./config-Deqpfpg9.js";
|
|
2
|
+
import { createMemoryState } from "@chat-adapter/state-memory";
|
|
3
|
+
import { createRedisState } from "@chat-adapter/state-redis";
|
|
4
|
+
import { setTimeout } from "node:timers/promises";
|
|
5
|
+
// src/chat/state/locks.ts
|
|
6
|
+
const ACTIVE_LOCK_TTL_MS = 9e4;
|
|
7
|
+
const MUTATION_LOCK_TTL_MS = 1e4;
|
|
8
|
+
/**
|
|
9
|
+
* Acquire a lock for long-running work that the queued state adapter should
|
|
10
|
+
* keep alive while the owning invocation is still making progress.
|
|
11
|
+
*/
|
|
12
|
+
async function acquireActiveLock(state, threadId) {
|
|
13
|
+
return await state.acquireLock(threadId, ACTIVE_LOCK_TTL_MS);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run work under one lock, optionally waiting for the current owner.
|
|
17
|
+
* `keepAlive` is for multi-store mutations that must retain ownership until all
|
|
18
|
+
* side effects finish; callers should still fence each blind write.
|
|
19
|
+
*/
|
|
20
|
+
async function withLock(state, key, run, options = {}) {
|
|
21
|
+
const startedAtMs = Date.now();
|
|
22
|
+
let lock;
|
|
23
|
+
while (true) {
|
|
24
|
+
lock = await state.acquireLock(key, options.ttlMs ?? 9e4);
|
|
25
|
+
if (lock) break;
|
|
26
|
+
if (Date.now() - startedAtMs >= (options.waitMs ?? 0)) return { acquired: false };
|
|
27
|
+
await setTimeout(options.retryMs ?? 25, void 0, { ref: false });
|
|
28
|
+
}
|
|
29
|
+
const ttlMs = options.ttlMs ?? 9e4;
|
|
30
|
+
const heartbeat = options.keepAlive ? setInterval(() => {
|
|
31
|
+
state.extendLock(lock, ttlMs);
|
|
32
|
+
}, Math.max(1, Math.floor(ttlMs / 3))) : void 0;
|
|
33
|
+
heartbeat?.unref();
|
|
34
|
+
try {
|
|
35
|
+
return {
|
|
36
|
+
acquired: true,
|
|
37
|
+
value: await run(lock)
|
|
38
|
+
};
|
|
39
|
+
} finally {
|
|
40
|
+
if (heartbeat) clearInterval(heartbeat);
|
|
41
|
+
await state.releaseLock(lock);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Prove lock ownership immediately before a blind write.
|
|
46
|
+
*
|
|
47
|
+
* Whole-record mutations must stop if their lock expired rather than overwrite
|
|
48
|
+
* state committed by a newer owner.
|
|
49
|
+
*/
|
|
50
|
+
async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
|
|
51
|
+
if (!await state.extendLock(lock, ttlMs)) throw new Error(`Lock ownership was lost before write for ${lock.threadId}`);
|
|
52
|
+
}
|
|
53
|
+
// src/chat/state/adapter.ts
|
|
54
|
+
const ACTIVE_LOCK_HEARTBEAT_MS = 3e4;
|
|
55
|
+
let stateAdapter;
|
|
56
|
+
let redisStateAdapter;
|
|
57
|
+
/** Lazily connect state operations, including queued-adapter lock heartbeats. */
|
|
58
|
+
function createConnectingStateAdapter(base) {
|
|
59
|
+
const connected = async (operation) => {
|
|
60
|
+
await base.connect();
|
|
61
|
+
return await operation();
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
appendToList: (key, value, options) => connected(() => base.appendToList(key, value, options)),
|
|
65
|
+
connect: () => base.connect(),
|
|
66
|
+
disconnect: () => base.disconnect(),
|
|
67
|
+
subscribe: (threadId) => connected(() => base.subscribe(threadId)),
|
|
68
|
+
unsubscribe: (threadId) => connected(() => base.unsubscribe(threadId)),
|
|
69
|
+
isSubscribed: (threadId) => connected(() => base.isSubscribed(threadId)),
|
|
70
|
+
acquireLock: (threadId, ttlMs) => connected(() => base.acquireLock(threadId, ttlMs)),
|
|
71
|
+
releaseLock: (lock) => connected(() => base.releaseLock(lock)),
|
|
72
|
+
extendLock: (lock, ttlMs) => connected(() => base.extendLock(lock, ttlMs)),
|
|
73
|
+
forceReleaseLock: (threadId) => connected(() => base.forceReleaseLock(threadId)),
|
|
74
|
+
enqueue: (threadId, entry, maxSize) => connected(() => base.enqueue(threadId, entry, maxSize)),
|
|
75
|
+
dequeue: (threadId) => connected(() => base.dequeue(threadId)),
|
|
76
|
+
queueDepth: (threadId) => connected(() => base.queueDepth(threadId)),
|
|
77
|
+
get: (key) => connected(() => base.get(key)),
|
|
78
|
+
getList: (key) => connected(() => base.getList(key)),
|
|
79
|
+
set: (key, value, ttlMs) => connected(() => base.set(key, value, ttlMs)),
|
|
80
|
+
setIfNotExists: (key, value, ttlMs) => connected(() => base.setIfNotExists(key, value, ttlMs)),
|
|
81
|
+
delete: (key) => connected(() => base.delete(key))
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function createPrefixedStateAdapter(base, prefix) {
|
|
85
|
+
const prefixed = (value) => `${prefix}:${value}`;
|
|
86
|
+
const unprefixed = (value) => value.startsWith(`${prefix}:`) ? value.slice(prefix.length + 1) : value;
|
|
87
|
+
const prefixLock = (lock) => ({
|
|
88
|
+
...lock,
|
|
89
|
+
threadId: prefixed(lock.threadId)
|
|
90
|
+
});
|
|
91
|
+
const unprefixLock = (lock) => ({
|
|
92
|
+
...lock,
|
|
93
|
+
threadId: unprefixed(lock.threadId)
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
appendToList: (key, value, options) => base.appendToList(prefixed(key), value, options),
|
|
97
|
+
connect: () => base.connect(),
|
|
98
|
+
disconnect: () => base.disconnect(),
|
|
99
|
+
subscribe: (threadId) => base.subscribe(prefixed(threadId)),
|
|
100
|
+
unsubscribe: (threadId) => base.unsubscribe(prefixed(threadId)),
|
|
101
|
+
isSubscribed: (threadId) => base.isSubscribed(prefixed(threadId)),
|
|
102
|
+
acquireLock: async (threadId, ttlMs) => {
|
|
103
|
+
const lock = await base.acquireLock(prefixed(threadId), ttlMs);
|
|
104
|
+
return lock ? unprefixLock(lock) : null;
|
|
105
|
+
},
|
|
106
|
+
releaseLock: (lock) => base.releaseLock(prefixLock(lock)),
|
|
107
|
+
extendLock: async (lock, ttlMs) => {
|
|
108
|
+
const prefixedLock = prefixLock(lock);
|
|
109
|
+
const extended = await base.extendLock(prefixedLock, ttlMs);
|
|
110
|
+
if (extended) lock.expiresAt = prefixedLock.expiresAt;
|
|
111
|
+
return extended;
|
|
112
|
+
},
|
|
113
|
+
forceReleaseLock: (threadId) => base.forceReleaseLock(prefixed(threadId)),
|
|
114
|
+
enqueue: (threadId, entry, maxSize) => base.enqueue(prefixed(threadId), entry, maxSize),
|
|
115
|
+
dequeue: (threadId) => base.dequeue(prefixed(threadId)),
|
|
116
|
+
queueDepth: (threadId) => base.queueDepth(prefixed(threadId)),
|
|
117
|
+
get: (key) => base.get(prefixed(key)),
|
|
118
|
+
getList: (key) => base.getList(prefixed(key)),
|
|
119
|
+
set: (key, value, ttlMs) => base.set(prefixed(key), value, ttlMs),
|
|
120
|
+
setIfNotExists: (key, value, ttlMs) => base.setIfNotExists(prefixed(key), value, ttlMs),
|
|
121
|
+
delete: (key) => base.delete(prefixed(key))
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function createQueuedStateAdapter(base, options) {
|
|
125
|
+
const heartbeats = /* @__PURE__ */ new Map();
|
|
126
|
+
const shouldHeartbeatLock = (ttlMs) => ttlMs === ACTIVE_LOCK_TTL_MS;
|
|
127
|
+
const heartbeatKey = (lock) => `${lock.threadId}:${lock.token}`;
|
|
128
|
+
const stopHeartbeatByKey = (key) => {
|
|
129
|
+
const heartbeat = heartbeats.get(key);
|
|
130
|
+
if (!heartbeat) return;
|
|
131
|
+
clearInterval(heartbeat.timer);
|
|
132
|
+
heartbeats.delete(key);
|
|
133
|
+
};
|
|
134
|
+
const stopHeartbeat = (lock) => {
|
|
135
|
+
stopHeartbeatByKey(heartbeatKey(lock));
|
|
136
|
+
};
|
|
137
|
+
const stopHeartbeatsForThread = (threadId) => {
|
|
138
|
+
for (const [key, heartbeat] of heartbeats) if (heartbeat.lock.threadId === threadId) stopHeartbeatByKey(key);
|
|
139
|
+
};
|
|
140
|
+
const stopAllHeartbeats = () => {
|
|
141
|
+
for (const key of heartbeats.keys()) stopHeartbeatByKey(key);
|
|
142
|
+
};
|
|
143
|
+
const runHeartbeat = async (key) => {
|
|
144
|
+
const heartbeat = heartbeats.get(key);
|
|
145
|
+
if (!heartbeat || heartbeat.inFlight) return;
|
|
146
|
+
heartbeat.inFlight = true;
|
|
147
|
+
try {
|
|
148
|
+
if (Date.now() - heartbeat.startedAtMs >= options.activeLockMaxAgeMs) {
|
|
149
|
+
stopHeartbeatByKey(key);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!await base.extendLock(heartbeat.lock, heartbeat.ttlMs)) {
|
|
153
|
+
stopHeartbeatByKey(key);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
heartbeat.lock.expiresAt = Date.now() + heartbeat.ttlMs;
|
|
157
|
+
} catch {} finally {
|
|
158
|
+
const current = heartbeats.get(key);
|
|
159
|
+
if (current === heartbeat) current.inFlight = false;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const startOrUpdateHeartbeat = (lock, ttlMs) => {
|
|
163
|
+
const key = heartbeatKey(lock);
|
|
164
|
+
const existing = heartbeats.get(key);
|
|
165
|
+
if (existing) {
|
|
166
|
+
existing.ttlMs = ttlMs;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const timer = setInterval(() => {
|
|
170
|
+
runHeartbeat(key);
|
|
171
|
+
}, ACTIVE_LOCK_HEARTBEAT_MS);
|
|
172
|
+
timer.unref?.();
|
|
173
|
+
heartbeats.set(key, {
|
|
174
|
+
inFlight: false,
|
|
175
|
+
lock,
|
|
176
|
+
startedAtMs: Date.now(),
|
|
177
|
+
timer,
|
|
178
|
+
ttlMs
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
const acquireLock = async (threadId, ttlMs) => {
|
|
182
|
+
const lock = await base.acquireLock(threadId, ttlMs);
|
|
183
|
+
if (lock && shouldHeartbeatLock(ttlMs)) startOrUpdateHeartbeat(lock, ttlMs);
|
|
184
|
+
return lock;
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
appendToList: (key, value, options) => base.appendToList(key, value, options),
|
|
188
|
+
connect: () => base.connect(),
|
|
189
|
+
disconnect: async () => {
|
|
190
|
+
stopAllHeartbeats();
|
|
191
|
+
await base.disconnect();
|
|
192
|
+
},
|
|
193
|
+
subscribe: (threadId) => base.subscribe(threadId),
|
|
194
|
+
unsubscribe: (threadId) => base.unsubscribe(threadId),
|
|
195
|
+
isSubscribed: (threadId) => base.isSubscribed(threadId),
|
|
196
|
+
acquireLock,
|
|
197
|
+
releaseLock: async (lock) => {
|
|
198
|
+
stopHeartbeat(lock);
|
|
199
|
+
await base.releaseLock(lock);
|
|
200
|
+
},
|
|
201
|
+
extendLock: async (lock, ttlMs) => {
|
|
202
|
+
const extended = await base.extendLock(lock, ttlMs);
|
|
203
|
+
if (extended) {
|
|
204
|
+
lock.expiresAt = Date.now() + ttlMs;
|
|
205
|
+
if (shouldHeartbeatLock(ttlMs)) startOrUpdateHeartbeat(lock, ttlMs);
|
|
206
|
+
else stopHeartbeat(lock);
|
|
207
|
+
} else stopHeartbeat(lock);
|
|
208
|
+
return extended;
|
|
209
|
+
},
|
|
210
|
+
forceReleaseLock: async (threadId) => {
|
|
211
|
+
stopHeartbeatsForThread(threadId);
|
|
212
|
+
await base.forceReleaseLock(threadId);
|
|
213
|
+
},
|
|
214
|
+
enqueue: (threadId, entry, maxSize) => base.enqueue(threadId, entry, maxSize),
|
|
215
|
+
dequeue: (threadId) => base.dequeue(threadId),
|
|
216
|
+
queueDepth: (threadId) => base.queueDepth(threadId),
|
|
217
|
+
get: (key) => base.get(key),
|
|
218
|
+
getList: (key) => base.getList(key),
|
|
219
|
+
set: (key, value, ttlMs) => base.set(key, value, ttlMs),
|
|
220
|
+
setIfNotExists: (key, value, ttlMs) => base.setIfNotExists(key, value, ttlMs),
|
|
221
|
+
delete: (key) => base.delete(key)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function withOptionalPrefix(base, prefix) {
|
|
225
|
+
return prefix ? createPrefixedStateAdapter(base, prefix) : base;
|
|
226
|
+
}
|
|
227
|
+
function createStateAdapter() {
|
|
228
|
+
const config = getChatConfig();
|
|
229
|
+
const activeLockMaxAgeMs = config.bot.turnTimeoutMs + ACTIVE_LOCK_TTL_MS;
|
|
230
|
+
if (config.state.adapter === "memory") {
|
|
231
|
+
redisStateAdapter = void 0;
|
|
232
|
+
return createQueuedStateAdapter(createConnectingStateAdapter(withOptionalPrefix(createMemoryState(), config.state.keyPrefix)), { activeLockMaxAgeMs });
|
|
233
|
+
}
|
|
234
|
+
if (!config.state.redisUrl) throw new Error("REDIS_URL is required for durable Slack thread state");
|
|
235
|
+
const redisState = createRedisState({ url: config.state.redisUrl });
|
|
236
|
+
redisStateAdapter = redisState;
|
|
237
|
+
return createQueuedStateAdapter(createConnectingStateAdapter(withOptionalPrefix(redisState, config.state.keyPrefix)), { activeLockMaxAgeMs });
|
|
238
|
+
}
|
|
239
|
+
function getOptionalRedisStateAdapter() {
|
|
240
|
+
getStateAdapter();
|
|
241
|
+
return redisStateAdapter;
|
|
242
|
+
}
|
|
243
|
+
async function getConnectedStateContext() {
|
|
244
|
+
const adapter = getStateAdapter();
|
|
245
|
+
await adapter.connect();
|
|
246
|
+
return {
|
|
247
|
+
redisStateAdapter: getOptionalRedisStateAdapter(),
|
|
248
|
+
stateAdapter: adapter
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Return the Redis adapter only when the caller is using the default state adapter. */
|
|
252
|
+
async function getDefaultRedisStateAdapterFor(adapter) {
|
|
253
|
+
if (adapter !== stateAdapter) return;
|
|
254
|
+
const context = await getConnectedStateContext();
|
|
255
|
+
return context.stateAdapter === adapter ? context.redisStateAdapter : void 0;
|
|
256
|
+
}
|
|
257
|
+
function getStateAdapter() {
|
|
258
|
+
if (!stateAdapter) stateAdapter = createStateAdapter();
|
|
259
|
+
return stateAdapter;
|
|
260
|
+
}
|
|
261
|
+
async function disconnectStateAdapter() {
|
|
262
|
+
if (!stateAdapter) return;
|
|
263
|
+
try {
|
|
264
|
+
await stateAdapter.disconnect();
|
|
265
|
+
} finally {
|
|
266
|
+
stateAdapter = void 0;
|
|
267
|
+
redisStateAdapter = void 0;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
export { acquireActiveLock as a, MUTATION_LOCK_TTL_MS as i, getDefaultRedisStateAdapterFor as n, fenceLock as o, getStateAdapter as r, withLock as s, disconnectStateAdapter as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as setUserAdminFromSql, d as getDb, n as listAdminUsersFromSql } from "./viewer-B2_ABsYi.js";
|
|
2
2
|
import { CLI_USAGE } from "./cli/run.js";
|
|
3
|
-
|
|
3
|
+
// src/cli/admin.ts
|
|
4
4
|
/**
|
|
5
5
|
* Operator CLI for the Junior-wide admin role.
|
|
6
6
|
*
|
|
@@ -29,5 +29,4 @@ async function runAdmin(argv) {
|
|
|
29
29
|
console.error(CLI_USAGE);
|
|
30
30
|
return 1;
|
|
31
31
|
}
|
|
32
|
-
//#endregion
|
|
33
32
|
export { runAdmin };
|