@sentry/junior 0.267.0 → 0.268.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-DZSokpwj.js → actor-CP9K2Idu.js} +2 -1
- package/dist/{adapter-BybMEezj.js → adapter-04AcD2SO.js} +4 -6
- package/dist/{admin-DOs1_EiW.js → admin-DIU1QyG3.js} +1 -1
- package/dist/{agent-invocations-CxKldAeB.js → agent-invocations-C1RNOCs8.js} +2 -0
- package/dist/{agent-runner-DgNATN4D.js → agent-runner-CAYfFmU7.js} +4409 -3020
- package/dist/api/schema.d.ts +2 -5629
- package/dist/api/schema.js +4 -4
- package/dist/api.d.ts +1 -1
- package/dist/api.js +154 -32
- package/dist/{app-DAB3fzyp.d.ts → app-z6Uuyq3j.d.ts} +3 -2
- package/dist/app.d.ts +1 -1
- package/dist/app.js +332 -98
- package/dist/{briefs-CWKjka7v.js → briefs-DQbV2jNr.js} +2 -2
- package/dist/{catalog-runtime-cMlAI5LY.js → catalog-runtime-BD9GSpc6.js} +1 -1
- package/dist/cli/chat.js +15 -15
- package/dist/cli/check.js +3 -3
- package/dist/cli/main.js +3 -3
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +4 -4
- package/dist/cli/upgrade.d.ts +1 -1
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-BjgbMawj.js → client-C1yDYjoS.js} +2 -2
- package/dist/{config-CdB6yJj5.js → config-DrTeF80T.js} +2 -2
- package/dist/{connections-RE_65jzK.js → connections-D46f8vvi.js} +10 -11
- package/dist/{conversation-privacy-BzgJC5k0.js → conversation-privacy-CxlOCiUo.js} +1 -1
- package/dist/{credential-sync-DhEGEpgq.js → credential-sync-sm9fegLY.js} +29 -34
- package/dist/{credentialed-CIGwoLU2.js → credentialed-lukuD-cc.js} +39 -13
- package/dist/db-BU4LQD8s.d.ts +6 -0
- package/dist/{executor-VYrx_K4w.js → executor-4vhvsMZJ.js} +78 -4
- package/dist/instrumentation.js +2 -2
- package/dist/{assistant-reply-CT7VcXQe.js → interruption-marker-CkncDT8d.js} +8 -2
- package/dist/{job-queue-C0BZSa7r.js → job-queue-In9QKz-I.js} +2 -2
- package/dist/{list-1XQP-o6K.js → list-BkgnXEEB.js} +298 -807
- package/dist/{logging-DuZ1A4ab.js → logging-DLSpkSSr.js} +1 -1
- package/dist/{message-NKSbbnA6.js → message-BObyg59s.js} +4 -4
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-callback-server-qAHLPtml.js → oauth-callback-server-B-WbSdoH.js} +2 -2
- package/dist/{registry-FQutO926.js → registry-BgecKva0.js} +2 -2
- package/dist/{web-message-id-CJSUiksE.js → reporting-window-DVCD_10C.js} +1 -10
- package/dist/{resolve-Bk4yeuHy.js → resolve-Cpa4Bu1O.js} +3 -3
- package/dist/{result-B9e9ATOU.js → result-D3TSmZZ8.js} +8 -8
- package/dist/{runner-C3S2ObH-.js → runner-DS5OKhEp.js} +10 -10
- package/dist/{sandbox-egress-signals-DqpGzzMB.js → sandbox-egress-signals-CnDjY5rx.js} +1 -1
- package/dist/{schema-X7Fj4fv1.js → schema-0050HFnB.js} +80 -4
- package/dist/schema-ZngqcOWM.d.ts +5813 -0
- package/dist/{service-account-Do30HUNv.js → service-account-CKV2WTY7.js} +3 -3
- package/dist/{service-account-BQasl-qq.js → service-account-DGjnDw9y.js} +3 -3
- package/dist/{session-stop-DkOjt46_.js → session-stop-Dam1EI7B.js} +494 -18
- package/dist/{skills-CQHrwfOa.js → skills-CfAnfImD.js} +2 -2
- package/dist/{spawn-BHuqN14f.js → spawn-cmq9p4Ly.js} +2 -2
- package/dist/{store-6EetVP-m.js → store-C5PN02QO.js} +4 -4
- package/dist/{store-B8CABbmR.d.ts → store-xMuuXRE0.d.ts} +13 -7
- package/dist/{store-DvNZIsCr.js → store-zPEoJPBB.js} +3 -3
- package/dist/{task-queue-B0DLgd2P.js → task-queue-_mf28dSu.js} +3 -3
- package/dist/{task-runner-B-PD_JOj.js → task-runner-DMI2prDO.js} +11 -12
- package/dist/{tasks-0ilmuCux.js → tasks-SB9z-VTU.js} +124 -21
- package/dist/{thread-state-DRmdJ2QN.js → thread-state-BbbPh0Sn.js} +8 -18
- package/dist/{turn-failure-response-G11cs2gE.js → turn-failure-response-BKKmnMB5.js} +10 -15
- package/dist/{turn-lifecycle-OzLIwvi1.js → turn-lifecycle-oP0kVeGz.js} +1 -1
- package/dist/{validation-CxEmt1id.js → validation--JsAGLwc.js} +1 -1
- package/dist/{version-Bapedn4A.js → version-jHwJp4hC.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-DrN3oC2X.js → viewer-CpXTGlep.js} +323 -235
- package/dist/{user-input-request-BDFBdF8r.js → web-message-id-DlHNANtd.js} +17 -1
- package/dist/{work-DUQoNcqP.js → work-3N-GHY9m.js} +10 -10
- package/dist/{worker-D1l4Ugk0.js → worker-CCdbcItd.js} +6 -6
- package/migrations/0065_user_customization.sql +1 -0
- package/migrations/0066_review_items.sql +53 -0
- package/migrations/0067_review_item_dedupe_tenant.sql +2 -0
- package/migrations/0068_review_item_slack_cards.sql +10 -0
- package/migrations/meta/0065_snapshot.json +3511 -0
- package/migrations/meta/0066_snapshot.json +4099 -0
- package/migrations/meta/0067_snapshot.json +3921 -0
- package/migrations/meta/0068_snapshot.json +4176 -0
- package/migrations/meta/_journal.json +29 -1
- package/package.json +5 -5
- package/dist/db-Bg-zC3r5.d.ts +0 -5
- package/dist/images-CecjXAAz.js +0 -64
- package/dist/turn-session-routing-Dyut9l7Y.js +0 -76
package/dist/app.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { C as automationVersionOf,
|
|
2
|
-
import { _ as snapshotRuntimeConfig, d as restoreRuntimeConfig, f as setBotModelConfig, g as setSlackReactionConfig, h as setRuntimeLimits, i as getChatConfig, m as setProfiles, n as botConfig, o as getSlackBotToken, p as setCrossActorMidRunMode, u as resetRuntimeConfig } from "./config-
|
|
3
|
-
import { A as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, E as withSpan, N as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException, r as createRequestContext, w as withContext, z as normalizeIdentityEmail } from "./logging-
|
|
1
|
+
import { $t as CONVERSATION_WORK_STALE_ENQUEUE_MS, C as automationVersionOf, I as eventGuidance, _n as isInvalidConversationRecordError, _r as setConfigDefaults, _t as settleConversationTitleWork, ar as getThreadStopDecision, b as admitEventAutomationRun, c as withScheduledAutomationLock, dr as setExperimentalFeatures, dt as appendConversationMessages, gr as getConfigDefaults, hn as hasRunnableConversationWork, i as readScheduledAutomation, l as blockEventAutomation, lr as getExperimentalFeatures, mt as projectConversationMessages, n as listScheduledAutomationsForTeam, nr as SubscribedReplyReason, o as saveScheduledAutomationInLock, p as findMatchingEventAutomations, s as scheduledRunId, u as collectEventAutomationMatchKeys, ur as isExperimentalFeatureEnabled, x as eventAutomationRunLimitReason } from "./tasks-SB9z-VTU.js";
|
|
2
|
+
import { _ as snapshotRuntimeConfig, d as restoreRuntimeConfig, f as setBotModelConfig, g as setSlackReactionConfig, h as setRuntimeLimits, i as getChatConfig, m as setProfiles, n as botConfig, o as getSlackBotToken, p as setCrossActorMidRunMode, u as resetRuntimeConfig } from "./config-DrTeF80T.js";
|
|
3
|
+
import { A as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, E as withSpan, N as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException, r as createRequestContext, w as withContext, z as normalizeIdentityEmail } from "./logging-DLSpkSSr.js";
|
|
4
4
|
import { n as captureMessage } from "./sentry-MDkYAVPV.js";
|
|
5
|
-
import { t as JUNIOR_VERSION } from "./version-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { a as juniorAgentInvocations, d as juniorDestinations, i as juniorAgentBindings, s as juniorConversations } from "./agent-invocations-
|
|
9
|
-
import {
|
|
10
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { c as withLock
|
|
5
|
+
import { t as JUNIOR_VERSION } from "./version-jHwJp4hC.js";
|
|
6
|
+
import { f as parseSlackTeamId, g as slackMessageTsSchema, h as slackMessageTsFromMs, m as parseSlackMessageTs, n as createSlackActor, p as parseSlackUserId, s as parseActorUserId, u as parseSlackChannelId } from "./actor-CP9K2Idu.js";
|
|
7
|
+
import { O as recordGoogleSignIn, _ as withConversationEventLock, b as withConversationMutationLock, d as getConversationEventStore, h as getSqlExecutor, i as readActorIdentity, l as closeDb, m as getDb, o as resolveViewerUser, p as getConversationStore } from "./viewer-CpXTGlep.js";
|
|
8
|
+
import { a as juniorAgentInvocations, d as juniorDestinations, i as juniorAgentBindings, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
|
|
9
|
+
import { d as juniorAutomations, g as juniorConversationBriefs, l as juniorAutomationRuns, y as juniorConversationEvents } from "./executor-4vhvsMZJ.js";
|
|
10
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-BD9GSpc6.js";
|
|
11
|
+
import { C as getOpenSlackUserInput, Ct as requestAttachmentDeletion, Dt as recordSubagentEnded, E as parseSlackThreadId, Et as stopConversationSession, G as parseSlackReviewItemClick, H as syncReviewItemSlackCards, J as buildSlackUserInputModal, K as parseSlackReviewItemFormTarget, N as logScheduledAutomationRunSkipped, Nt as processWorkspaceSnapshotJob, P as scheduledAutomationRunAttributes, Pt as ingestEvent, Q as slackUserInputAnswerNote, R as effectiveTaskOutcomes, S as closeSlackUserInput, T as releaseSlackUserInput, V as readSlackReviewItemCardConversationId, W as buildSlackReviewItemModal, X as parseSlackUserInputSubmission, Y as parseSlackUserInputFormTarget, Z as slackUserInputAction, _ as unpublishedArtifactHeaders, _t as recordWebConversationActivity, dt as sendReviewItemMessages, et as runWithSlackInstallation, g as readPublicArtifact, h as publicArtifactHeaders, mt as conversationTurnIdForMessage, n as executeAgentRun, pt as appendAndEnqueueWebMessage, t as createAgentRunner, tt as verifySlackSignature, ut as renderReviewItemMessage, v as lookupSlackUserProfile, vt as webActorFromEmail, w as persistSlackUserInputReply, x as claimSlackUserInput, xt as collectAttachmentGarbage } from "./agent-runner-CAYfFmU7.js";
|
|
12
|
+
import { $ as openSlackModal, I as isVercelSandboxEgressRequest, In as createPluginLogger, Jt as bindScheduledAutomationCredentialSubject, Kt as takeDueTimerWatches, L as proxyVercelSandboxEgressRequest, Ln as readConversationAccessFromSql, Nn as createPluginState, Qt as verifySlackDirectCredentialSubject, Tt as normalizeSandboxEgressTracePropagationDomains, Ut as findMatchingWatches, V as resolveBaseUrl, Xt as verifyEventAutomationCredentialSubject, Yt as bindSlackDirectCredentialSubject, Zt as verifyScheduledAutomationCredentialSubject, _n as getDashboardTaskLink, _t as consumeSandboxEgressPermissionDeniedSignal, at as slackEntitySchema, c as getPluginRoutes, cr as createPluginCache, dn as getWorkspaceTeamId, er as resolveRootVisibility, et as postSlackEphemeralMessage, fn as runWithWorkspaceTeamId, gt as consumeSandboxEgressAuthRequiredSignal, h as validatePlugins, ht as clearSandboxEgressSignals, in as getSlackClient, lr as createCache, m as setPlugins, mn as getDashboardConversationLink, n as createUserTokenStore, on as isDmChannel, ot as slackExternalRefIdSchema, p as getPlugins, q as slackMention, qt as bindEventAutomationCredentialSubject, rr as listConversationAnnotations, s as getPluginApiRoutes, v as setBriefsConfig, vn as setDashboardConversationLinkOptions, yt as parseSandboxEgressCredentialToken, zt as collectEventMatchKeys } from "./credentialed-lukuD-cc.js";
|
|
13
|
+
import { a as MUTATION_LOCK_TTL_MS, c as withLock, i as getStateAdapter, s as fenceLock, t as disconnectStateAdapter } from "./adapter-04AcD2SO.js";
|
|
14
14
|
import { n as getNextRunAtMs } from "./cadence-R7Em4RjE.js";
|
|
15
15
|
import { D as conversationSurfaceSchema, I as annotationCard, T as conversationReportStatusSchema, h as conversationFeedQuerySchema } from "./conversation-DSo310Ps.js";
|
|
16
|
-
import { b as listPendingAgentInvocationMailboxAppends, x as listPendingAgentInvocationResults } from "./store-
|
|
17
|
-
import { S as renderTaskInput, d as getEventCatalog, f as SLACK_EVENT_NAMESPACE, g as slackChannelMessageRunsAutomation, h as slackChannelMessageReplyThreadTs, m as slackChannelMessageEvent } from "./session-stop-
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
16
|
+
import { b as listPendingAgentInvocationMailboxAppends, x as listPendingAgentInvocationResults } from "./store-C5PN02QO.js";
|
|
17
|
+
import { E as renderSlackObjectCard, S as renderTaskInput, d as getEventCatalog, f as SLACK_EVENT_NAMESPACE, g as slackChannelMessageRunsAutomation, h as slackChannelMessageReplyThreadTs, m as slackChannelMessageEvent } from "./session-stop-Dam1EI7B.js";
|
|
18
|
+
import { a as isEmptyUserInputAnswer, i as formatUserInputAnswer, o as normalizeUserInputAnswer, r as buttonUserInputField } from "./web-message-id-DlHNANtd.js";
|
|
19
|
+
import { c as setSandboxResourceConfig, o as getSandboxResourceConfig } from "./resolve-Cpa4Bu1O.js";
|
|
20
|
+
import { a as getVercelConversationWorkQueue, d as getQueueProvider, g as isConversationQueueMessageRejectedError, h as conversationQueueMessageSchema, i as verifyWorkspaceSnapshotJobMessage, o as resolveConversationWorkQueueTopic, s as verifyConversationQueueMessage, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-In9QKz-I.js";
|
|
21
|
+
import { S as removeActiveConversation, _ as hasRunnableConversationWork$1, c as clearExpiredConversationLease, g as getConversationWorkState, h as getConversation, m as ensureConversationWake, r as appendAndEnqueueInboundMessage, v as listActiveConversationIds } from "./store-zPEoJPBB.js";
|
|
22
22
|
import { D as scheduledRunSchema } from "./automation-CmeFBSEh.js";
|
|
23
|
-
import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation
|
|
23
|
+
import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation--JsAGLwc.js";
|
|
24
24
|
import { a as pluginRuntimeRegistrationsFromPluginSet, n as pluginCatalogConfigFromEnv, r as pluginCatalogConfigFromPluginSet, t as defineJuniorPlugins } from "./plugins-DOm9Y6qI.js";
|
|
25
|
-
import {
|
|
26
|
-
import { C as existingConversationId, N as recordAutomationExecution, c as getDispatchConversationId, d as getDispatchRecord, h as listPendingDispatchMailboxAppends, i as buildDispatchId, m as isTerminalDispatchStatus, o as confirmDispatchMailboxAppend, p as getPluginDispatchProjection, s as createOrGetDispatch, t as processPluginTask, x as notifyAutomationBlocked, y as markDispatchFailed } from "./task-runner-
|
|
27
|
-
import { o as getAuthPausedConversationTurnId, t as enqueueAgentInvocationResult } from "./result-
|
|
28
|
-
import { r as enqueueAgentInvocation } from "./work-
|
|
29
|
-
import {
|
|
30
|
-
import { o as unlinkProvider } from "./connections-
|
|
31
|
-
import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-
|
|
32
|
-
import { a as pluginTaskQueueConsumer, c as queueCallback, n as createVercelPluginTaskCallback, o as registerVercelPluginTaskDevConsumer } from "./task-queue-
|
|
33
|
-
import { t as processConversationWork } from "./worker-
|
|
34
|
-
import { t as bindMessageAgent } from "./message-
|
|
35
|
-
import { t as bindSpawnAgent } from "./spawn-
|
|
25
|
+
import { A as assertNoLegacyAllowedDomains, B as normalizeIncomingSlackThreadId, E as readViewerAutomationSummary, F as recordSkippedConversationMessage, G as parseContent, H as stopConversationTurn, I as buildSlackInboundMessage, J as canActOnReviewItem, K as ReviewItemActionError, L as clearSlackPendingReactions, M as isAllowedSignInEmail, N as readEnvList, P as resolveAllowedDomains, Q as getAttachmentStorage, R as isSlackMessageStopped, U as THREAD_OPTOUT_ACK, V as withNormalizedThreadId, W as startProcessingReaction, X as readReviewItemForUser, Z as reviewItemChange, _ as createProductionConversationWorkOptions, b as createSlackWebApiStatusSender, et as enqueueAgentDispatch, j as isAllowedDomain, q as actOnReviewItem, t as readConversationFeed, tt as GET$3, v as createProductionSlackWebhookServices, y as getProductionSlackAdapter, z as stopSlackThread } from "./list-BkgnXEEB.js";
|
|
26
|
+
import { C as existingConversationId, N as recordAutomationExecution, c as getDispatchConversationId, d as getDispatchRecord, h as listPendingDispatchMailboxAppends, i as buildDispatchId, m as isTerminalDispatchStatus, o as confirmDispatchMailboxAppend, p as getPluginDispatchProjection, s as createOrGetDispatch, t as processPluginTask, x as notifyAutomationBlocked, y as markDispatchFailed } from "./task-runner-DMI2prDO.js";
|
|
27
|
+
import { o as getAuthPausedConversationTurnId, t as enqueueAgentInvocationResult } from "./result-D3TSmZZ8.js";
|
|
28
|
+
import { r as enqueueAgentInvocation } from "./work-3N-GHY9m.js";
|
|
29
|
+
import { o as coerceThreadConversationState } from "./thread-state-BbbPh0Sn.js";
|
|
30
|
+
import { o as unlinkProvider } from "./connections-D46f8vvi.js";
|
|
31
|
+
import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-sm9fegLY.js";
|
|
32
|
+
import { a as pluginTaskQueueConsumer, c as queueCallback, n as createVercelPluginTaskCallback, o as registerVercelPluginTaskDevConsumer } from "./task-queue-_mf28dSu.js";
|
|
33
|
+
import { t as processConversationWork } from "./worker-CCdbcItd.js";
|
|
34
|
+
import { t as bindMessageAgent } from "./message-BObyg59s.js";
|
|
35
|
+
import { t as bindSpawnAgent } from "./spawn-cmq9p4Ly.js";
|
|
36
36
|
import { createRequire } from "node:module";
|
|
37
37
|
import { Hono } from "hono";
|
|
38
38
|
import { z } from "zod";
|
|
@@ -40,7 +40,6 @@ import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypt
|
|
|
40
40
|
import { and, asc, eq, inArray, isNotNull, isNull, lte, or, sql } from "drizzle-orm";
|
|
41
41
|
import { EVENT_SUMMARY_MAX_LENGTH, EVENT_TEXT_MAX_LENGTH, dispatchOptionsSchema, eventSchema, eventTriggerFiltersText, isSlackDestination, userSchema } from "@sentry/junior-plugin-api";
|
|
42
42
|
import { pathToFileURL } from "node:url";
|
|
43
|
-
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
44
43
|
import net from "node:net";
|
|
45
44
|
import { decodeJwt } from "jose";
|
|
46
45
|
import https from "node:https";
|
|
@@ -1697,6 +1696,261 @@ async function isSlackWorkspaceMember(raw, state) {
|
|
|
1697
1696
|
};
|
|
1698
1697
|
});
|
|
1699
1698
|
}
|
|
1699
|
+
// src/chat/ingress/slack-interaction-input.ts
|
|
1700
|
+
/**
|
|
1701
|
+
* Build the Slack input that a click or form makes in a thread, as a
|
|
1702
|
+
* mention from the person who acted. The input has no Slack message of its
|
|
1703
|
+
* own, so `messageId` is not a timestamp. Every Slack timestamp reader, such
|
|
1704
|
+
* as reactions, the actor `slack_ts`, and attachment lookup, then resolves
|
|
1705
|
+
* `raw.ts`: the message that the person clicked. `inputTs` sets the time of
|
|
1706
|
+
* the input.
|
|
1707
|
+
*/
|
|
1708
|
+
function buildSlackInteractionInput(args) {
|
|
1709
|
+
const event = {
|
|
1710
|
+
type: "message",
|
|
1711
|
+
channel: args.channelId,
|
|
1712
|
+
team: args.payload.team?.id,
|
|
1713
|
+
text: args.text,
|
|
1714
|
+
thread_ts: args.threadTs,
|
|
1715
|
+
ts: args.inputTs,
|
|
1716
|
+
user: args.userId,
|
|
1717
|
+
user_team: args.payload.user?.team_id
|
|
1718
|
+
};
|
|
1719
|
+
const parsed = args.adapter.parseMessage(event);
|
|
1720
|
+
return new Message({
|
|
1721
|
+
attachments: parsed.attachments,
|
|
1722
|
+
author: parsed.author,
|
|
1723
|
+
formatted: parsed.formatted,
|
|
1724
|
+
id: args.messageId,
|
|
1725
|
+
isMention: true,
|
|
1726
|
+
links: parsed.links,
|
|
1727
|
+
metadata: parsed.metadata,
|
|
1728
|
+
raw: {
|
|
1729
|
+
...event,
|
|
1730
|
+
ts: args.messageTs
|
|
1731
|
+
},
|
|
1732
|
+
text: parsed.text,
|
|
1733
|
+
threadId: parsed.threadId
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
1736
|
+
// src/chat/ingress/slack-review-item.ts
|
|
1737
|
+
async function tellPerson(target, userId, text) {
|
|
1738
|
+
await postSlackEphemeralMessage({
|
|
1739
|
+
channelId: target.channelId,
|
|
1740
|
+
text,
|
|
1741
|
+
threadTs: target.threadTs,
|
|
1742
|
+
userId
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Resolve the Junior User of the person who acted. An action starts a Turn
|
|
1747
|
+
* as that person, so it needs the same workspace and allowed domain checks
|
|
1748
|
+
* as a Slack mention.
|
|
1749
|
+
*/
|
|
1750
|
+
async function resolveActingUser(services, payload, target) {
|
|
1751
|
+
const slackUserId = parseActorUserId(payload.user?.id);
|
|
1752
|
+
const teamId = payload.team?.id ?? payload.user?.team_id;
|
|
1753
|
+
if (!slackUserId || !teamId) throw new Error("Slack review item payload is missing a user or team");
|
|
1754
|
+
if (!await isSlackWorkspaceMember({
|
|
1755
|
+
user: slackUserId,
|
|
1756
|
+
user_team: payload.user?.team_id
|
|
1757
|
+
}, services.state) || !await services.isAuthorAllowed(slackUserId)) return;
|
|
1758
|
+
const user = (await readActorIdentity(createSlackActor(teamId, slackUserId, void 0)))?.user;
|
|
1759
|
+
if (!user) {
|
|
1760
|
+
await tellPerson(target, slackUserId, "Junior does not know your account yet. Sign in to the Junior dashboard, then try again.");
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
return {
|
|
1764
|
+
slackUserId,
|
|
1765
|
+
user
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
/** Show the current state of an item, such as after a click on a stale card. */
|
|
1769
|
+
async function refreshCards(services, user, itemId) {
|
|
1770
|
+
const item = await readReviewItemForUser(user, itemId).catch(() => void 0);
|
|
1771
|
+
if (!item) return;
|
|
1772
|
+
await syncReviewItemSlackCards({
|
|
1773
|
+
getSlackAdapter: () => services.adapter,
|
|
1774
|
+
itemId: item.id
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Do one person action from a Slack card. The thread of the card gets the
|
|
1779
|
+
* action as Slack input from the person, like an answer to
|
|
1780
|
+
* `requestUserInput`. The other linked Conversations get messages from
|
|
1781
|
+
* `actOnReviewItem`. An expected failure, such as an item that is already
|
|
1782
|
+
* closed, goes to the person as an ephemeral message.
|
|
1783
|
+
*/
|
|
1784
|
+
async function act(args) {
|
|
1785
|
+
const { services, target } = args;
|
|
1786
|
+
const actor = await resolveActingUser(services, args.payload, target);
|
|
1787
|
+
if (!actor) return;
|
|
1788
|
+
const conversationId = await readSlackReviewItemCardConversationId({
|
|
1789
|
+
...target,
|
|
1790
|
+
itemId: args.itemId
|
|
1791
|
+
}) ?? `slack:${target.channelId}:${target.threadTs}`;
|
|
1792
|
+
let item;
|
|
1793
|
+
try {
|
|
1794
|
+
const current = await readReviewItemForUser(actor.user, args.itemId);
|
|
1795
|
+
item = await actOnReviewItem({
|
|
1796
|
+
action: args.action,
|
|
1797
|
+
exceptConversationId: conversationId,
|
|
1798
|
+
firstCloseOnly: true,
|
|
1799
|
+
getSlackAdapter: () => services.adapter,
|
|
1800
|
+
id: current.id,
|
|
1801
|
+
queue: services.queue,
|
|
1802
|
+
user: actor.user,
|
|
1803
|
+
...args.answer ? { answer: args.answer(current) } : void 0
|
|
1804
|
+
});
|
|
1805
|
+
} catch (error) {
|
|
1806
|
+
if (!(error instanceof ReviewItemActionError)) throw error;
|
|
1807
|
+
await tellPerson(target, actor.slackUserId, error.message);
|
|
1808
|
+
await refreshCards(services, actor.user, args.itemId);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
if (!item.conversationIds.includes(conversationId)) return;
|
|
1812
|
+
const change = reviewItemChange(args.action, actor.user);
|
|
1813
|
+
try {
|
|
1814
|
+
await services.persistMessage(buildSlackInteractionInput({
|
|
1815
|
+
adapter: services.adapter,
|
|
1816
|
+
channelId: target.channelId,
|
|
1817
|
+
inputTs: args.inputTs,
|
|
1818
|
+
messageId: args.messageId,
|
|
1819
|
+
messageTs: target.messageTs,
|
|
1820
|
+
payload: args.payload,
|
|
1821
|
+
text: renderReviewItemMessage(item, change),
|
|
1822
|
+
threadTs: target.threadTs,
|
|
1823
|
+
userId: actor.slackUserId
|
|
1824
|
+
}));
|
|
1825
|
+
} catch (error) {
|
|
1826
|
+
logException(error, "review_item.slack_input.persist.failed", { "app.review_item.id": item.id });
|
|
1827
|
+
await sendReviewItemMessages({
|
|
1828
|
+
change,
|
|
1829
|
+
item,
|
|
1830
|
+
nowMs: Date.now(),
|
|
1831
|
+
queue: services.queue
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
function cardTarget(payload) {
|
|
1836
|
+
const channelId = parseSlackChannelId(payload.channel?.id);
|
|
1837
|
+
const messageTs = parseSlackMessageTs(payload.message?.ts);
|
|
1838
|
+
if (!channelId || !messageTs) throw new Error("Slack review item payload is incomplete");
|
|
1839
|
+
return {
|
|
1840
|
+
channelId,
|
|
1841
|
+
messageTs,
|
|
1842
|
+
threadTs: parseSlackMessageTs(payload.message?.thread_ts) ?? messageTs
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
async function openAnswerForm(args) {
|
|
1846
|
+
const { target } = args;
|
|
1847
|
+
const triggerId = args.payload.trigger_id;
|
|
1848
|
+
if (!triggerId) throw new Error("Slack review item form payload is missing a trigger id");
|
|
1849
|
+
const actor = await resolveActingUser(args.services, args.payload, target);
|
|
1850
|
+
if (!actor) return;
|
|
1851
|
+
let item;
|
|
1852
|
+
try {
|
|
1853
|
+
item = await readReviewItemForUser(actor.user, args.itemId);
|
|
1854
|
+
} catch (error) {
|
|
1855
|
+
if (!(error instanceof ReviewItemActionError)) throw error;
|
|
1856
|
+
await tellPerson(target, actor.slackUserId, error.message);
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
if (!canActOnReviewItem(item, actor.user.id)) {
|
|
1860
|
+
await tellPerson(target, actor.slackUserId, item.status === "open" ? "Only an assignee can act on this item." : "This item is already closed.");
|
|
1861
|
+
await refreshCards(args.services, actor.user, item.id);
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
const view = buildSlackReviewItemModal(item, {
|
|
1865
|
+
...target,
|
|
1866
|
+
itemId: item.id
|
|
1867
|
+
});
|
|
1868
|
+
if (!view) return;
|
|
1869
|
+
await openSlackModal({
|
|
1870
|
+
triggerId,
|
|
1871
|
+
view
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
/** Handle one click on a Review item card. */
|
|
1875
|
+
async function handleSlackReviewItemClick(args) {
|
|
1876
|
+
const { click, payload, services } = args;
|
|
1877
|
+
const target = cardTarget(payload);
|
|
1878
|
+
if (click.kind === "answer") {
|
|
1879
|
+
await openAnswerForm({
|
|
1880
|
+
itemId: click.itemId,
|
|
1881
|
+
payload,
|
|
1882
|
+
services,
|
|
1883
|
+
target
|
|
1884
|
+
});
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
const actionTs = parseSlackMessageTs(args.action.action_ts);
|
|
1888
|
+
if (!actionTs) throw new Error("Slack review item click payload is incomplete");
|
|
1889
|
+
const common = {
|
|
1890
|
+
inputTs: actionTs,
|
|
1891
|
+
itemId: click.itemId,
|
|
1892
|
+
messageId: `slack-review-item:${actionTs}`,
|
|
1893
|
+
payload,
|
|
1894
|
+
services,
|
|
1895
|
+
target
|
|
1896
|
+
};
|
|
1897
|
+
if (click.kind === "done") {
|
|
1898
|
+
await act({
|
|
1899
|
+
...common,
|
|
1900
|
+
action: "complete"
|
|
1901
|
+
});
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1904
|
+
if (click.kind === "dismiss") {
|
|
1905
|
+
await act({
|
|
1906
|
+
...common,
|
|
1907
|
+
action: "dismiss"
|
|
1908
|
+
});
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1911
|
+
await act({
|
|
1912
|
+
...common,
|
|
1913
|
+
action: "submit",
|
|
1914
|
+
answer: (item) => {
|
|
1915
|
+
const field = item.request && buttonUserInputField(item.request);
|
|
1916
|
+
if (!field?.options.some((option) => option.label === click.label)) throw new ReviewItemActionError("conflict", "This card changed. Use the updated card.");
|
|
1917
|
+
return {
|
|
1918
|
+
requestId: item.id,
|
|
1919
|
+
values: { [field.id]: [click.label] }
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
/** Submit the answer of a Review item form. */
|
|
1925
|
+
async function handleSlackReviewItemSubmission(args) {
|
|
1926
|
+
const view = args.payload.view;
|
|
1927
|
+
const formTarget = parseSlackReviewItemFormTarget(view?.private_metadata);
|
|
1928
|
+
const channelId = parseSlackChannelId(formTarget?.channelId);
|
|
1929
|
+
const messageTs = parseSlackMessageTs(formTarget?.messageTs);
|
|
1930
|
+
const threadTs = parseSlackMessageTs(formTarget?.threadTs);
|
|
1931
|
+
if (!view?.id || !formTarget || !channelId || !messageTs || !threadTs) throw new Error("Slack review item form submission is incomplete");
|
|
1932
|
+
await act({
|
|
1933
|
+
action: "submit",
|
|
1934
|
+
answer: (item) => item.request ? parseSlackUserInputSubmission({
|
|
1935
|
+
request: item.request,
|
|
1936
|
+
requestId: item.id,
|
|
1937
|
+
values: view.state?.values ?? {}
|
|
1938
|
+
}) : {
|
|
1939
|
+
requestId: item.id,
|
|
1940
|
+
values: {}
|
|
1941
|
+
},
|
|
1942
|
+
inputTs: slackMessageTsFromMs(Date.now()),
|
|
1943
|
+
itemId: formTarget.itemId,
|
|
1944
|
+
messageId: `slack-review-item:${view.id}`,
|
|
1945
|
+
payload: args.payload,
|
|
1946
|
+
services: args.services,
|
|
1947
|
+
target: {
|
|
1948
|
+
channelId,
|
|
1949
|
+
messageTs,
|
|
1950
|
+
threadTs
|
|
1951
|
+
}
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1700
1954
|
// src/chat/ingress/slack-interactive.ts
|
|
1701
1955
|
function requireSlackPayloadUserId(value, source) {
|
|
1702
1956
|
const userId = parseActorUserId(value);
|
|
@@ -1745,31 +1999,16 @@ async function answerSlackUserInput(args) {
|
|
|
1745
1999
|
claimedBy: userId,
|
|
1746
2000
|
messageTs
|
|
1747
2001
|
})) return;
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
2002
|
+
const message = buildSlackInteractionInput({
|
|
2003
|
+
adapter: args.adapter,
|
|
2004
|
+
channelId,
|
|
2005
|
+
inputTs: args.inputTs,
|
|
2006
|
+
messageId: args.messageId,
|
|
2007
|
+
messageTs,
|
|
2008
|
+
payload: args.payload,
|
|
1752
2009
|
text: formatUserInputAnswer(open.request, answer),
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
user: userId,
|
|
1756
|
-
user_team: userTeam
|
|
1757
|
-
};
|
|
1758
|
-
const parsed = args.adapter.parseMessage(event);
|
|
1759
|
-
const message = new Message({
|
|
1760
|
-
attachments: parsed.attachments,
|
|
1761
|
-
author: parsed.author,
|
|
1762
|
-
formatted: parsed.formatted,
|
|
1763
|
-
id: args.messageId,
|
|
1764
|
-
isMention: true,
|
|
1765
|
-
links: parsed.links,
|
|
1766
|
-
metadata: parsed.metadata,
|
|
1767
|
-
raw: {
|
|
1768
|
-
...event,
|
|
1769
|
-
ts: messageTs
|
|
1770
|
-
},
|
|
1771
|
-
text: parsed.text,
|
|
1772
|
-
threadId: parsed.threadId
|
|
2010
|
+
threadTs: args.threadTs,
|
|
2011
|
+
userId
|
|
1773
2012
|
});
|
|
1774
2013
|
try {
|
|
1775
2014
|
await args.persistMessage(message);
|
|
@@ -1784,7 +2023,7 @@ async function answerSlackUserInput(args) {
|
|
|
1784
2023
|
note: slackUserInputAnswerNote({
|
|
1785
2024
|
answer,
|
|
1786
2025
|
request: open.request,
|
|
1787
|
-
userId
|
|
2026
|
+
who: slackMention(userId)
|
|
1788
2027
|
}),
|
|
1789
2028
|
open
|
|
1790
2029
|
});
|
|
@@ -1864,17 +2103,34 @@ async function handleUserInputSubmission(args) {
|
|
|
1864
2103
|
});
|
|
1865
2104
|
}
|
|
1866
2105
|
/**
|
|
1867
|
-
* Handle Slack interactions from App Home
|
|
1868
|
-
* block actions and submitted
|
|
2106
|
+
* Handle Slack interactions from App Home, user input requests, and Review
|
|
2107
|
+
* item cards: block actions and submitted forms.
|
|
1869
2108
|
*/
|
|
1870
2109
|
async function handleSlackInteractivePayload(args) {
|
|
1871
2110
|
const spanAttributes = { userId: args.payload.user?.id?.trim() || void 0 };
|
|
2111
|
+
if (args.payload.type === "view_submission" && args.payload.view?.callback_id === "junior_review_item") {
|
|
2112
|
+
await withSpan("chat.slack_review_item_submit", "chat.slack_review_item_submit", spanAttributes, () => handleSlackReviewItemSubmission({
|
|
2113
|
+
payload: args.payload,
|
|
2114
|
+
services: args
|
|
2115
|
+
}));
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
1872
2118
|
if (args.payload.type === "view_submission" && args.payload.view?.callback_id === "junior_user_input") {
|
|
1873
2119
|
await withSpan("chat.slack_user_input_submit", "chat.slack_user_input_submit", spanAttributes, () => handleUserInputSubmission(args));
|
|
1874
2120
|
return;
|
|
1875
2121
|
}
|
|
1876
2122
|
if (args.payload.type !== "block_actions") return;
|
|
1877
2123
|
for (const action of args.payload.actions ?? []) {
|
|
2124
|
+
const click = parseSlackReviewItemClick(action);
|
|
2125
|
+
if (click) {
|
|
2126
|
+
await withSpan("chat.slack_review_item_click", "chat.slack_review_item_click", spanAttributes, () => handleSlackReviewItemClick({
|
|
2127
|
+
action,
|
|
2128
|
+
click,
|
|
2129
|
+
payload: args.payload,
|
|
2130
|
+
services: args
|
|
2131
|
+
}));
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
1878
2134
|
const kind = slackUserInputAction(action.action_id);
|
|
1879
2135
|
if (kind === "choice") {
|
|
1880
2136
|
await withSpan("chat.slack_user_input_click", "chat.slack_user_input_click", spanAttributes, () => handleUserInputChoice({
|
|
@@ -1931,6 +2187,7 @@ async function handleSlackForm(args) {
|
|
|
1931
2187
|
payload,
|
|
1932
2188
|
isAuthorAllowed: (userId) => args.isAuthorAllowed(userId, installation),
|
|
1933
2189
|
persistMessage: (message) => args.persistMessage(message, installation),
|
|
2190
|
+
queue: args.queue,
|
|
1934
2191
|
state,
|
|
1935
2192
|
userTokenStore: args.getUserTokenStore()
|
|
1936
2193
|
})
|
|
@@ -2495,7 +2752,7 @@ async function handleSlackThreadStop(args) {
|
|
|
2495
2752
|
});
|
|
2496
2753
|
await appendConversationMessages(getConversationEventStore(), {
|
|
2497
2754
|
conversation,
|
|
2498
|
-
conversationId
|
|
2755
|
+
conversationId
|
|
2499
2756
|
});
|
|
2500
2757
|
await thread.post(THREAD_OPTOUT_ACK);
|
|
2501
2758
|
}
|
|
@@ -2598,6 +2855,11 @@ async function routeParsedMessage(args) {
|
|
|
2598
2855
|
teamId: args.installation.teamId,
|
|
2599
2856
|
user: args.event.user
|
|
2600
2857
|
})) return;
|
|
2858
|
+
const conversationId = await resolveSlackConversationId({
|
|
2859
|
+
canonicalThreadId,
|
|
2860
|
+
conversationStore: args.conversationStore,
|
|
2861
|
+
installation: args.installation
|
|
2862
|
+
});
|
|
2601
2863
|
if (isSubscribed && !isExperimentalFeatureEnabled("passive-routing")) {
|
|
2602
2864
|
const content = parseContent(message);
|
|
2603
2865
|
const conversation = coerceThreadConversationState(void 0);
|
|
@@ -2609,15 +2871,10 @@ async function routeParsedMessage(args) {
|
|
|
2609
2871
|
});
|
|
2610
2872
|
await appendConversationMessages(getConversationEventStore(), {
|
|
2611
2873
|
conversation,
|
|
2612
|
-
conversationId
|
|
2874
|
+
conversationId
|
|
2613
2875
|
});
|
|
2614
2876
|
return;
|
|
2615
2877
|
}
|
|
2616
|
-
const conversationId = await resolveSlackConversationId({
|
|
2617
|
-
canonicalThreadId,
|
|
2618
|
-
conversationStore: args.conversationStore,
|
|
2619
|
-
installation: args.installation
|
|
2620
|
-
});
|
|
2621
2878
|
const persist = () => persistSlackMessage({
|
|
2622
2879
|
adapter: args.adapter,
|
|
2623
2880
|
installation: args.installation,
|
|
@@ -2639,7 +2896,7 @@ async function routeParsedMessage(args) {
|
|
|
2639
2896
|
isSaved: (error) => error instanceof SlackEventPersistenceError && error.saved,
|
|
2640
2897
|
note: (request) => slackUserInputAnswerNote({
|
|
2641
2898
|
request,
|
|
2642
|
-
|
|
2899
|
+
who: slackMention(message.author.userId)
|
|
2643
2900
|
}),
|
|
2644
2901
|
persist,
|
|
2645
2902
|
state: args.state,
|
|
@@ -2703,7 +2960,7 @@ async function handleSlackEvent(args) {
|
|
|
2703
2960
|
if (!await isSlackWorkspaceMember(event, state)) return;
|
|
2704
2961
|
const channelId = event.channel;
|
|
2705
2962
|
const threadTs = event.thread_ts;
|
|
2706
|
-
if (!(await withLock
|
|
2963
|
+
if (!(await withLock(state, `slack:ingress:slack:${channelId}:${threadTs}`, () => handleSlackSessionStop({
|
|
2707
2964
|
adapter,
|
|
2708
2965
|
channelId,
|
|
2709
2966
|
conversationStore: args.services.conversationStore,
|
|
@@ -2722,7 +2979,7 @@ async function handleSlackEvent(args) {
|
|
|
2722
2979
|
setSpanAttributes({ "app.slack.membership": member ? "verified" : "unverified" });
|
|
2723
2980
|
if (!member) return;
|
|
2724
2981
|
const message = adapter.parseMessage(event);
|
|
2725
|
-
if (!(await withLock
|
|
2982
|
+
if (!(await withLock(state, `slack:ingress:${normalizeMessageThreadId(message).threadId}`, () => routeParsedMessage({
|
|
2726
2983
|
adapter,
|
|
2727
2984
|
event,
|
|
2728
2985
|
installation,
|
|
@@ -2749,7 +3006,7 @@ async function handleSlackEvent(args) {
|
|
|
2749
3006
|
async function persistSlackMentionWithLock(args) {
|
|
2750
3007
|
const { message, threadId } = normalizeMessageThreadId(args.message);
|
|
2751
3008
|
try {
|
|
2752
|
-
if (!(await withLock
|
|
3009
|
+
if (!(await withLock(args.state, `slack:ingress:${threadId}`, () => persistSlackMessage({
|
|
2753
3010
|
adapter: args.adapter,
|
|
2754
3011
|
installation: args.installation,
|
|
2755
3012
|
message,
|
|
@@ -2799,6 +3056,7 @@ async function handleSlackWebhook(args) {
|
|
|
2799
3056
|
services: args.services,
|
|
2800
3057
|
state
|
|
2801
3058
|
}),
|
|
3059
|
+
queue: args.services.queue,
|
|
2802
3060
|
state,
|
|
2803
3061
|
waitUntil: args.waitUntil
|
|
2804
3062
|
});
|
|
@@ -3280,35 +3538,6 @@ function resolvePublicOrigin(request, configured) {
|
|
|
3280
3538
|
url.hash = "";
|
|
3281
3539
|
return url;
|
|
3282
3540
|
}
|
|
3283
|
-
// src/api/acp/state.ts
|
|
3284
|
-
const MUTATION_LOCK_TTL_MS = 1e4;
|
|
3285
|
-
/** Run one ACP state mutation while its shared lock remains owned. */
|
|
3286
|
-
async function withLock(state, key, run, options = {}) {
|
|
3287
|
-
const ttlMs = options.ttlMs ?? 1e4;
|
|
3288
|
-
const startedAtMs = Date.now();
|
|
3289
|
-
let lock;
|
|
3290
|
-
while (true) {
|
|
3291
|
-
lock = await state.acquireLock(key, ttlMs);
|
|
3292
|
-
if (lock) break;
|
|
3293
|
-
if (Date.now() - startedAtMs >= (options.waitMs ?? 0)) return { acquired: false };
|
|
3294
|
-
await setTimeout$1(options.retryMs ?? 25, void 0, { ref: false });
|
|
3295
|
-
}
|
|
3296
|
-
const heartbeat = options.keepAlive ? setInterval(() => void state.extendLock(lock, ttlMs).catch(() => void 0), Math.floor(ttlMs / 3)) : void 0;
|
|
3297
|
-
heartbeat?.unref();
|
|
3298
|
-
try {
|
|
3299
|
-
return {
|
|
3300
|
-
acquired: true,
|
|
3301
|
-
value: await run(lock)
|
|
3302
|
-
};
|
|
3303
|
-
} finally {
|
|
3304
|
-
if (heartbeat) clearInterval(heartbeat);
|
|
3305
|
-
await state.releaseLock(lock);
|
|
3306
|
-
}
|
|
3307
|
-
}
|
|
3308
|
-
/** Prove ACP lock ownership immediately before a blind state write. */
|
|
3309
|
-
async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
|
|
3310
|
-
if (!await state.extendLock(lock, ttlMs)) throw new Error(`ACP lock ownership was lost before write for ${lock.threadId}`);
|
|
3311
|
-
}
|
|
3312
3541
|
// src/api/acp/schema.ts
|
|
3313
3542
|
/** Validate the ACP wire messages that Junior supports. */
|
|
3314
3543
|
const ACP_SESSION_ID_PATTERN = /^local:acp:[a-f0-9]{32}$/;
|
|
@@ -6149,6 +6378,7 @@ function dashboardHostRoutePaths(dashboard, authenticatedRoutes = []) {
|
|
|
6149
6378
|
`${conversationsPath}/*`,
|
|
6150
6379
|
pagePath("locations"),
|
|
6151
6380
|
`${pagePath("locations")}/*`,
|
|
6381
|
+
pagePath("review"),
|
|
6152
6382
|
peoplePath,
|
|
6153
6383
|
`${peoplePath}/*`,
|
|
6154
6384
|
pagePath("automations"),
|
|
@@ -6182,6 +6412,8 @@ function dashboardHostRoutePaths(dashboard, authenticatedRoutes = []) {
|
|
|
6182
6412
|
"/api/plugin-reports",
|
|
6183
6413
|
"/api/user-pages",
|
|
6184
6414
|
"/api/user-pages/*",
|
|
6415
|
+
"/api/user-customization",
|
|
6416
|
+
"/api/user-customization/*",
|
|
6185
6417
|
"/api/automations",
|
|
6186
6418
|
"/api/automations/*",
|
|
6187
6419
|
"/api/skills",
|
|
@@ -6196,6 +6428,8 @@ function dashboardHostRoutePaths(dashboard, authenticatedRoutes = []) {
|
|
|
6196
6428
|
"/api/locations/*",
|
|
6197
6429
|
"/api/people",
|
|
6198
6430
|
"/api/people/*",
|
|
6431
|
+
"/api/review-items",
|
|
6432
|
+
"/api/review-items/*",
|
|
6199
6433
|
"/api/personal-tokens",
|
|
6200
6434
|
"/api/personal-tokens/*",
|
|
6201
6435
|
"/api/service-accounts",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as completeObject } from "./client-
|
|
1
|
+
import { i as completeObject } from "./client-C1yDYjoS.js";
|
|
2
2
|
import { r as defaultModelId } from "./model-profile-Bg8EoCKD.js";
|
|
3
3
|
import { J as briefCodeChangeSchema, Q as parseBriefInput, d as conversationDetailReportSchema, p as conversationEventPageSchema } from "./conversation-DSo310Ps.js";
|
|
4
4
|
import { n as briefEntriesFromReportEvents, s as generateBrief, t as BRIEF_PROMPT } from "./prompt-BW9jFsqZ.js";
|
|
@@ -267,7 +267,7 @@ async function parseRunOptions(argv) {
|
|
|
267
267
|
* `DATABASE_URL` at import, and `briefs pull` must work with only a token.
|
|
268
268
|
*/
|
|
269
269
|
async function configuredDefaultModelId() {
|
|
270
|
-
const { botConfig } = await import("./config-
|
|
270
|
+
const { botConfig } = await import("./config-DrTeF80T.js").then((n) => n.r);
|
|
271
271
|
return defaultModelId(botConfig);
|
|
272
272
|
}
|
|
273
273
|
function apiUrl(baseUrl, pathname) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import { t as createPluginCatalogRuntime } from "./registry-
|
|
2
|
+
import { t as createPluginCatalogRuntime } from "./registry-BgecKva0.js";
|
|
3
3
|
// src/chat/plugins/catalog-runtime.ts
|
|
4
4
|
var catalog_runtime_exports = /* @__PURE__ */ __exportAll({ pluginCatalogRuntime: () => pluginCatalogRuntime });
|
|
5
5
|
const pluginCatalogRuntime = createPluginCatalogRuntime();
|