@cursor/july 0.1.40 → 0.1.41
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/AGENTS.md +4 -3
- package/dist/bin/agent-serve.js +28 -9
- package/dist/channels/slack/attachments.d.ts +82 -0
- package/dist/channels/slack/attachments.d.ts.map +1 -0
- package/dist/channels/slack/attachments.js +520 -0
- package/dist/channels/slack/cursor-account.d.ts +7 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +2 -2
- package/dist/channels/slack/dispatch.d.ts +4 -3
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +84 -21
- package/dist/channels/slack/inbound.d.ts +6 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +48 -2
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +7 -4
- package/dist/channels/slack/types.d.ts +49 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +6 -6
- package/dist/docs/assets/{ab.md.6cLOW7--.js → ab.md.hdxsvX5M.js} +2 -2
- package/dist/docs/assets/{app.DpGLSiym.js → app.mIw24pb1.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.txrcGU2B.js → building-with-agents.md.PeZaZA1P.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BA7V8dEJ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.B11XEMST.js → VPLocalSearchBox.hOzpPwrG.js} +1 -1
- package/dist/docs/assets/chunks/{theme.iTidHsAx.js → theme.BtFhUYmh.js} +2 -2
- package/dist/docs/assets/{deployment.md.CuK5SNjN.js → deployment.md.BHVjVqRa.js} +4 -4
- package/dist/docs/assets/{deployment.md.CuK5SNjN.lean.js → deployment.md.BHVjVqRa.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.BQXI3rXy.js → evals.md.qeoGgPw0.js} +3 -3
- package/dist/docs/assets/example-agents_index.md.xmJ87d_3.js +2 -0
- package/dist/docs/assets/{guides_webhooks.md.BERuBSJW.js → guides_webhooks.md.DB-r_er9.js} +47 -4
- package/dist/docs/assets/{guides_webhooks.md.BERuBSJW.lean.js → guides_webhooks.md.DB-r_er9.lean.js} +1 -1
- package/dist/docs/assets/index.md.BKpbkCa6.js +24 -0
- package/dist/docs/assets/{index.md.CmhptOmN.lean.js → index.md.BKpbkCa6.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.C_b6ESpD.js → quickstart.md.rIbfahJM.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.Byvrg8eu.js → reference_cli.md.DqEqQpGn.js} +5 -5
- package/dist/docs/assets/{reference_cli.md.Byvrg8eu.lean.js → reference_cli.md.DqEqQpGn.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BGDw4VLm.js → reference_hooks.md.BHeG-vjK.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.BGDw4VLm.lean.js → reference_hooks.md.BHeG-vjK.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.mQDtIULc.js → storage.md.DcGSnIxX.js} +10 -4
- package/dist/docs/assets/{storage.md.mQDtIULc.lean.js → storage.md.DcGSnIxX.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.CkgwmVI0.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.B5RVX_tL.lean.js → troubleshooting.md.CkgwmVI0.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +6 -6
- package/dist/docs/evals.html +7 -7
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +5 -5
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +49 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +7 -7
- package/dist/docs/quickstart.html +8 -8
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/artifacts.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +8 -8
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +14 -8
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +22 -2
- package/dist/internal/cli-deploy.d.ts +6 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +14 -4
- package/dist/internal/cli-mcp.js +4 -4
- package/dist/internal/deploy-client.js +1 -1
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +35 -7
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +3 -1
- package/dist/internal/durable-session-store.d.ts +48 -0
- package/dist/internal/durable-session-store.d.ts.map +1 -0
- package/dist/internal/durable-session-store.js +86 -0
- package/dist/internal/hosting.d.ts +1 -1
- package/dist/internal/hosting.js +2 -2
- package/dist/internal/init-project.d.ts +34 -0
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +121 -2
- package/dist/internal/ledger-serving.d.ts +101 -0
- package/dist/internal/ledger-serving.d.ts.map +1 -0
- package/dist/internal/ledger-serving.js +174 -0
- package/dist/internal/listen-port.d.ts +22 -0
- package/dist/internal/listen-port.d.ts.map +1 -0
- package/dist/internal/listen-port.js +77 -0
- package/dist/internal/playground/static.d.ts +21 -4
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +82 -18
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +10 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +61 -47
- package/dist/internal/session-engine.d.ts +57 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +117 -28
- package/dist/internal/slack-provision-client.js +1 -1
- package/dist/internal/workspace.d.ts +6 -2
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +10 -2
- package/dist/kv/memory-kv.d.ts +23 -0
- package/dist/kv/memory-kv.d.ts.map +1 -0
- package/dist/kv/memory-kv.js +103 -0
- package/dist/kv.d.ts +22 -0
- package/dist/kv.d.ts.map +1 -0
- package/dist/kv.js +20 -0
- package/dist/ledger/session-ledger.d.ts +204 -0
- package/dist/ledger/session-ledger.d.ts.map +1 -0
- package/dist/ledger/session-ledger.js +382 -0
- package/dist/ledger.d.ts +11 -0
- package/dist/ledger.d.ts.map +1 -0
- package/dist/ledger.js +9 -0
- package/dist/playground/assets/index-B3HBneZZ.js +85 -0
- package/dist/playground/assets/index-Bqk9nplh.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +25 -3
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +50 -2
- package/dist/storage-backends/file-kv.d.ts +5 -2
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +107 -7
- package/dist/storage.d.ts +60 -5
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +28 -4
- package/dist/types.d.ts +123 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -0
- package/docs/README.md +10 -7
- package/docs/ab.md +2 -2
- package/docs/building-with-agents.md +1 -1
- package/docs/deployment.md +34 -11
- package/docs/evals.md +3 -3
- package/docs/example-agents/index.md +1 -1
- package/docs/guides/webhooks.md +87 -0
- package/docs/quickstart.md +7 -8
- package/docs/reference/cli.md +15 -6
- package/docs/reference/hooks.md +8 -2
- package/docs/storage.md +67 -7
- package/docs/troubleshooting.md +10 -2
- package/package.json +20 -7
- package/skills/create-agent/SKILL.md +1 -1
- package/src/bin/agent-serve.ts +27 -11
- package/src/channels/slack/attachments.ts +635 -0
- package/src/channels/slack/cursor-account.ts +8 -0
- package/src/channels/slack/dispatch.ts +121 -6
- package/src/channels/slack/inbound.ts +60 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/manifest.ts +1 -0
- package/src/channels/slack/slack-channel.ts +7 -0
- package/src/channels/slack/types.ts +47 -1
- package/src/index.ts +9 -0
- package/src/internal/cli-ax.ts +25 -1
- package/src/internal/cli-deploy.ts +22 -4
- package/src/internal/cli-mcp.ts +4 -4
- package/src/internal/deploy-client.ts +1 -1
- package/src/internal/discovery.ts +42 -5
- package/src/internal/distribution.ts +3 -1
- package/src/internal/durable-session-store.ts +95 -0
- package/src/internal/hosting.ts +2 -2
- package/src/internal/init-project.ts +151 -2
- package/src/internal/ledger-serving.ts +240 -0
- package/src/internal/listen-port.ts +85 -0
- package/src/internal/playground/static.ts +111 -20
- package/src/internal/sdk-runner.ts +11 -1
- package/src/internal/server.ts +68 -61
- package/src/internal/session-engine.ts +192 -16
- package/src/internal/slack-provision-client.ts +1 -1
- package/src/internal/workspace.ts +14 -3
- package/src/kv/memory-kv.ts +99 -0
- package/src/kv.ts +27 -0
- package/src/ledger/session-ledger.ts +535 -0
- package/src/ledger.ts +29 -0
- package/src/storage-backends/cursor-hosted.ts +108 -3
- package/src/storage-backends/file-kv.ts +128 -12
- package/src/storage.ts +90 -6
- package/src/types.ts +130 -4
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.D82_RVtF.js +0 -1
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +0 -2
- package/dist/docs/assets/index.md.CmhptOmN.js +0 -24
- package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/multi-tenant.d.ts +0 -80
- package/dist/multi-tenant.d.ts.map +0 -1
- package/dist/multi-tenant.js +0 -69
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/index-BRhBbnd4.css +0 -1
- package/dist/playground/assets/index-Bc1oFgFG.js +0 -85
- package/dist/storage-backends/postgres-kv.d.ts +0 -82
- package/dist/storage-backends/postgres-kv.d.ts.map +0 -1
- package/dist/storage-backends/postgres-kv.js +0 -185
- package/src/storage-backends/postgres-kv.ts +0 -253
- /package/dist/docs/assets/{ab.md.6cLOW7--.lean.js → ab.md.hdxsvX5M.lean.js} +0 -0
- /package/dist/docs/assets/{building-with-agents.md.txrcGU2B.lean.js → building-with-agents.md.PeZaZA1P.lean.js} +0 -0
- /package/dist/docs/assets/{evals.md.BQXI3rXy.lean.js → evals.md.qeoGgPw0.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_index.md.DgGBwckv.lean.js → example-agents_index.md.xmJ87d_3.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.C_b6ESpD.lean.js → quickstart.md.rIbfahJM.lean.js} +0 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download and classify Slack file uploads for agent turns.
|
|
3
|
+
*
|
|
4
|
+
* Images become vision inputs (SDK `images`). Documents and videos land under
|
|
5
|
+
* `slack-attachments/` in the session workspace so the model can Read them.
|
|
6
|
+
*/
|
|
7
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
import { callSlackApiSoft, isSlackApiTransport } from "./api.js";
|
|
17
|
+
import { tryResolveBotToken } from "./credentials.js";
|
|
18
|
+
export const SLACK_ATTACHMENTS_DIR = "slack-attachments";
|
|
19
|
+
export const SLACK_ATTACHMENT_ONLY_PROMPT = "The user shared Slack attachment(s) with no message text. Review the attached files.";
|
|
20
|
+
const DEFAULT_MAX_FILE_BYTES = 15 * 1024 * 1024;
|
|
21
|
+
const DEFAULT_MAX_TOTAL_BYTES = 35 * 1024 * 1024;
|
|
22
|
+
const DEFAULT_MAX_FILES = 8;
|
|
23
|
+
const DEFAULT_DOWNLOAD_TIMEOUT_MS = 10000;
|
|
24
|
+
const TEXT_SLACK_FILETYPES = new Set([
|
|
25
|
+
"text",
|
|
26
|
+
"markdown",
|
|
27
|
+
"md",
|
|
28
|
+
"diff",
|
|
29
|
+
"csv",
|
|
30
|
+
"tsv",
|
|
31
|
+
"json",
|
|
32
|
+
"xml",
|
|
33
|
+
"yaml",
|
|
34
|
+
"c",
|
|
35
|
+
"csharp",
|
|
36
|
+
"cpp",
|
|
37
|
+
"css",
|
|
38
|
+
"clojure",
|
|
39
|
+
"coffeescript",
|
|
40
|
+
"dart",
|
|
41
|
+
"dockerfile",
|
|
42
|
+
"email",
|
|
43
|
+
"erlang",
|
|
44
|
+
"fsharp",
|
|
45
|
+
"go",
|
|
46
|
+
"groovy",
|
|
47
|
+
"html",
|
|
48
|
+
"haskell",
|
|
49
|
+
"java",
|
|
50
|
+
"javascript",
|
|
51
|
+
"kotlin",
|
|
52
|
+
"latex",
|
|
53
|
+
"lisp",
|
|
54
|
+
"lua",
|
|
55
|
+
"matlab",
|
|
56
|
+
"objc",
|
|
57
|
+
"ocaml",
|
|
58
|
+
"pascal",
|
|
59
|
+
"perl",
|
|
60
|
+
"php",
|
|
61
|
+
"powershell",
|
|
62
|
+
"python",
|
|
63
|
+
"r",
|
|
64
|
+
"ruby",
|
|
65
|
+
"rust",
|
|
66
|
+
"sql",
|
|
67
|
+
"sass",
|
|
68
|
+
"scala",
|
|
69
|
+
"scheme",
|
|
70
|
+
"shell",
|
|
71
|
+
"swift",
|
|
72
|
+
"typescript",
|
|
73
|
+
"vb",
|
|
74
|
+
"vbscript",
|
|
75
|
+
]);
|
|
76
|
+
function asRecord(value) {
|
|
77
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
function asString(value) {
|
|
83
|
+
return typeof value === "string" ? value : undefined;
|
|
84
|
+
}
|
|
85
|
+
function asNumber(value) {
|
|
86
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
87
|
+
? value
|
|
88
|
+
: undefined;
|
|
89
|
+
}
|
|
90
|
+
function normalizeMimeType(mimeType) {
|
|
91
|
+
return (mimeType !== null && mimeType !== void 0 ? mimeType : "").split(";")[0].trim().toLowerCase();
|
|
92
|
+
}
|
|
93
|
+
function getLowercaseFileExtension(filename) {
|
|
94
|
+
if (filename === undefined || filename.length === 0) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
const extensionStart = filename.lastIndexOf(".");
|
|
98
|
+
if (extensionStart < 0 || extensionStart === filename.length - 1) {
|
|
99
|
+
return "";
|
|
100
|
+
}
|
|
101
|
+
return filename.slice(extensionStart + 1).toLowerCase();
|
|
102
|
+
}
|
|
103
|
+
/** Keep path-safe basename pieces (mirrors cloud-agent sanitizeFilename). */
|
|
104
|
+
export function sanitizeSlackFilename(name) {
|
|
105
|
+
const trimmed = name.trim().replace(/[/\\?%*:|"<>]/g, "_");
|
|
106
|
+
return trimmed.length > 0 ? trimmed.slice(0, 180) : "file";
|
|
107
|
+
}
|
|
108
|
+
export function isSupportedImageFormat(mimeType) {
|
|
109
|
+
return [
|
|
110
|
+
"image/jpeg",
|
|
111
|
+
"image/jpg",
|
|
112
|
+
"image/png",
|
|
113
|
+
"image/gif",
|
|
114
|
+
"image/webp",
|
|
115
|
+
].includes(normalizeMimeType(mimeType));
|
|
116
|
+
}
|
|
117
|
+
export function isSupportedDocumentFormat(args) {
|
|
118
|
+
const mimeType = normalizeMimeType(args.mimeType);
|
|
119
|
+
const extension = getLowercaseFileExtension(args.filename);
|
|
120
|
+
const supportedExtensions = new Set([
|
|
121
|
+
"7z",
|
|
122
|
+
"bz2",
|
|
123
|
+
"doc",
|
|
124
|
+
"docx",
|
|
125
|
+
"gz",
|
|
126
|
+
"pdf",
|
|
127
|
+
"ppt",
|
|
128
|
+
"pptx",
|
|
129
|
+
"rar",
|
|
130
|
+
"tar",
|
|
131
|
+
"tbz",
|
|
132
|
+
"tbz2",
|
|
133
|
+
"tgz",
|
|
134
|
+
"txt",
|
|
135
|
+
"md",
|
|
136
|
+
"markdown",
|
|
137
|
+
"csv",
|
|
138
|
+
"xlsx",
|
|
139
|
+
"xz",
|
|
140
|
+
"json",
|
|
141
|
+
"jsonl",
|
|
142
|
+
"xml",
|
|
143
|
+
"yaml",
|
|
144
|
+
"yml",
|
|
145
|
+
"toml",
|
|
146
|
+
"txz",
|
|
147
|
+
"log",
|
|
148
|
+
"tzst",
|
|
149
|
+
"zip",
|
|
150
|
+
"zst",
|
|
151
|
+
]);
|
|
152
|
+
const supportedMimeTypes = new Set([
|
|
153
|
+
"application/gzip",
|
|
154
|
+
"application/msword",
|
|
155
|
+
"application/pdf",
|
|
156
|
+
"application/json",
|
|
157
|
+
"application/jsonl",
|
|
158
|
+
"application/vnd.rar",
|
|
159
|
+
"application/vnd.ms-powerpoint",
|
|
160
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
161
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
162
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
163
|
+
"application/xml",
|
|
164
|
+
"application/x-7z-compressed",
|
|
165
|
+
"application/x-bzip2",
|
|
166
|
+
"application/x-compressed-tar",
|
|
167
|
+
"application/x-gzip",
|
|
168
|
+
"application/x-gtar",
|
|
169
|
+
"application/x-rar-compressed",
|
|
170
|
+
"application/x-tar",
|
|
171
|
+
"application/x-xz",
|
|
172
|
+
"application/x-yaml",
|
|
173
|
+
"application/x-zip-compressed",
|
|
174
|
+
"application/yaml",
|
|
175
|
+
"application/zip",
|
|
176
|
+
"application/toml",
|
|
177
|
+
"application/zstd",
|
|
178
|
+
"application/x-zstd",
|
|
179
|
+
"text/csv",
|
|
180
|
+
"text/markdown",
|
|
181
|
+
"text/plain",
|
|
182
|
+
"text/xml",
|
|
183
|
+
"text/x-log",
|
|
184
|
+
"text/x-markdown",
|
|
185
|
+
"text/yaml",
|
|
186
|
+
]);
|
|
187
|
+
return (mimeType.startsWith("text/") ||
|
|
188
|
+
supportedMimeTypes.has(mimeType) ||
|
|
189
|
+
supportedExtensions.has(extension));
|
|
190
|
+
}
|
|
191
|
+
export function isSupportedVideoFormat(mimeType) {
|
|
192
|
+
return normalizeMimeType(mimeType).startsWith("video/");
|
|
193
|
+
}
|
|
194
|
+
function hasTextSlackHint(file) {
|
|
195
|
+
if (file.mode === "snippet") {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
const filetype = typeof file.filetype === "string" ? file.filetype.trim().toLowerCase() : "";
|
|
199
|
+
return TEXT_SLACK_FILETYPES.has(filetype);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Classify a Slack file as image / document / video. Tolerates empty
|
|
203
|
+
* `mimetype` on snippets (Slack fills it asynchronously).
|
|
204
|
+
*/
|
|
205
|
+
export function classifySlackFile(file) {
|
|
206
|
+
const populatedMimeType = typeof file.mimetype === "string" ? normalizeMimeType(file.mimetype) : "";
|
|
207
|
+
const textHint = hasTextSlackHint(file);
|
|
208
|
+
const mimeType = populatedMimeType.length > 0
|
|
209
|
+
? populatedMimeType
|
|
210
|
+
: textHint
|
|
211
|
+
? "text/plain"
|
|
212
|
+
: "";
|
|
213
|
+
if (mimeType.length === 0) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
if (isSupportedImageFormat(mimeType)) {
|
|
217
|
+
return { kind: "image", mimeType };
|
|
218
|
+
}
|
|
219
|
+
const filename = typeof file.name === "string"
|
|
220
|
+
? file.name
|
|
221
|
+
: typeof file.title === "string"
|
|
222
|
+
? file.title
|
|
223
|
+
: undefined;
|
|
224
|
+
const isTextLike = textHint || mimeType.startsWith("text/");
|
|
225
|
+
if (isTextLike || isSupportedDocumentFormat({ mimeType, filename })) {
|
|
226
|
+
return { kind: "document", mimeType, isTextLike };
|
|
227
|
+
}
|
|
228
|
+
if (isSupportedVideoFormat(mimeType)) {
|
|
229
|
+
return { kind: "video", mimeType };
|
|
230
|
+
}
|
|
231
|
+
return undefined;
|
|
232
|
+
}
|
|
233
|
+
function isForwardedShareAttachment(value) {
|
|
234
|
+
const record = asRecord(value);
|
|
235
|
+
return record !== null && record.is_share === true;
|
|
236
|
+
}
|
|
237
|
+
/** Top-level uploads plus files nested in forwarded `is_share` attachments. */
|
|
238
|
+
export function collectSlackMessageFiles(message) {
|
|
239
|
+
const record = asRecord(message);
|
|
240
|
+
if (record === null) {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
const files = Array.isArray(record.files)
|
|
244
|
+
? [...record.files]
|
|
245
|
+
: [];
|
|
246
|
+
if (Array.isArray(record.attachments)) {
|
|
247
|
+
for (const attachment of record.attachments) {
|
|
248
|
+
if (isForwardedShareAttachment(attachment) &&
|
|
249
|
+
Array.isArray(attachment.files)) {
|
|
250
|
+
files.push(...attachment.files);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return files;
|
|
255
|
+
}
|
|
256
|
+
export function parseSlackFileRefs(message) {
|
|
257
|
+
const files = collectSlackMessageFiles(message);
|
|
258
|
+
const refs = [];
|
|
259
|
+
for (const file of files) {
|
|
260
|
+
const id = asString(file.id);
|
|
261
|
+
if (id === undefined || id.length === 0) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
refs.push({
|
|
265
|
+
id,
|
|
266
|
+
name: asString(file.name),
|
|
267
|
+
title: asString(file.title),
|
|
268
|
+
mimetype: asString(file.mimetype),
|
|
269
|
+
filetype: asString(file.filetype),
|
|
270
|
+
mode: asString(file.mode),
|
|
271
|
+
size: asNumber(file.size),
|
|
272
|
+
dataBase64: asString(file.dataBase64),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return refs.length > 0 ? refs : undefined;
|
|
276
|
+
}
|
|
277
|
+
function attachmentFilename(file) {
|
|
278
|
+
var _a, _b;
|
|
279
|
+
return sanitizeSlackFilename((_b = (_a = file.name) !== null && _a !== void 0 ? _a : file.title) !== null && _b !== void 0 ? _b : file.id);
|
|
280
|
+
}
|
|
281
|
+
function looksLikeHtml(bytes) {
|
|
282
|
+
const head = Buffer.from(bytes.subarray(0, 100))
|
|
283
|
+
.toString("utf8")
|
|
284
|
+
.toLowerCase();
|
|
285
|
+
return head.includes("<html");
|
|
286
|
+
}
|
|
287
|
+
function isTextLikeBytes(args) {
|
|
288
|
+
if (args.isTextLike || args.mimeType.startsWith("text/")) {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
// Reject obvious binary before attempting utf8 decode for docs.
|
|
292
|
+
for (let i = 0; i < Math.min(args.bytes.length, 512); i++) {
|
|
293
|
+
if (args.bytes[i] === 0) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return (args.mimeType === "application/json" ||
|
|
298
|
+
args.mimeType === "application/jsonl" ||
|
|
299
|
+
args.mimeType === "application/xml" ||
|
|
300
|
+
args.mimeType === "application/yaml" ||
|
|
301
|
+
args.mimeType === "application/x-yaml" ||
|
|
302
|
+
args.mimeType === "application/toml");
|
|
303
|
+
}
|
|
304
|
+
function downloadSlackFileBytes(args) {
|
|
305
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
var _a, _b, _c;
|
|
307
|
+
// cursorAccount transport cannot mint a Bearer for files.slack.com; the
|
|
308
|
+
// relay must pre-attach `dataBase64` on the file ref instead.
|
|
309
|
+
if (isSlackApiTransport(args.botToken)) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
const info = yield callSlackApiSoft({
|
|
313
|
+
botToken: args.botToken,
|
|
314
|
+
operation: "files.info",
|
|
315
|
+
body: { file: args.fileId },
|
|
316
|
+
});
|
|
317
|
+
if (info.ok !== true) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
const file = asRecord(info.file);
|
|
321
|
+
if (file === null) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const downloadUrl = asString(file.url_private_download);
|
|
325
|
+
if (downloadUrl === undefined || downloadUrl.length === 0) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
const fileSize = asNumber(file.size);
|
|
329
|
+
if (fileSize !== undefined && fileSize > args.maxBytes) {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
const botToken = yield tryResolveBotToken({ botToken: args.botToken });
|
|
333
|
+
const headers = {};
|
|
334
|
+
if (botToken !== undefined && botToken.length > 0) {
|
|
335
|
+
headers.Authorization = `Bearer ${botToken}`;
|
|
336
|
+
}
|
|
337
|
+
let response;
|
|
338
|
+
try {
|
|
339
|
+
response = yield fetch(downloadUrl, {
|
|
340
|
+
headers,
|
|
341
|
+
signal: AbortSignal.timeout(args.downloadTimeoutMs),
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
catch (_d) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
if (!response.ok) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
351
|
+
if (contentLengthHeader !== null && contentLengthHeader.length > 0) {
|
|
352
|
+
const contentLength = Number.parseInt(contentLengthHeader, 10);
|
|
353
|
+
if (!Number.isNaN(contentLength) && contentLength > args.maxBytes) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const buffer = Buffer.from(yield response.arrayBuffer());
|
|
358
|
+
if (buffer.length > args.maxBytes) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
const actualContentType = response.headers.get("content-type");
|
|
362
|
+
if (normalizeMimeType(actualContentType !== null && actualContentType !== void 0 ? actualContentType : undefined) === "text/html" ||
|
|
363
|
+
looksLikeHtml(buffer)) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
const responseMimeType = normalizeMimeType(actualContentType !== null && actualContentType !== void 0 ? actualContentType : undefined);
|
|
367
|
+
const metadataMimeType = normalizeMimeType((_a = asString(file.mimetype)) !== null && _a !== void 0 ? _a : args.fallbackMimeType);
|
|
368
|
+
const effectiveMimeType = responseMimeType.length > 0 &&
|
|
369
|
+
responseMimeType !== "application/octet-stream"
|
|
370
|
+
? responseMimeType
|
|
371
|
+
: metadataMimeType;
|
|
372
|
+
return {
|
|
373
|
+
data: new Uint8Array(buffer),
|
|
374
|
+
mimeType: effectiveMimeType.length > 0 ? effectiveMimeType : args.fallbackMimeType,
|
|
375
|
+
filename: sanitizeSlackFilename((_c = (_b = asString(file.name)) !== null && _b !== void 0 ? _b : asString(file.title)) !== null && _c !== void 0 ? _c : args.fileId),
|
|
376
|
+
};
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Download (or use pre-attached) Slack files and split them into vision
|
|
381
|
+
* images + workspace blobs for the turn.
|
|
382
|
+
*/
|
|
383
|
+
export function prepareSlackAttachments(options) {
|
|
384
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
385
|
+
var _a, _b;
|
|
386
|
+
var _c, _d, _e, _f;
|
|
387
|
+
const maxFiles = (_c = options.maxFiles) !== null && _c !== void 0 ? _c : DEFAULT_MAX_FILES;
|
|
388
|
+
const maxFileBytes = (_d = options.maxFileBytes) !== null && _d !== void 0 ? _d : DEFAULT_MAX_FILE_BYTES;
|
|
389
|
+
const maxTotalBytes = (_e = options.maxTotalBytes) !== null && _e !== void 0 ? _e : DEFAULT_MAX_TOTAL_BYTES;
|
|
390
|
+
const downloadTimeoutMs = (_f = options.downloadTimeoutMs) !== null && _f !== void 0 ? _f : DEFAULT_DOWNLOAD_TIMEOUT_MS;
|
|
391
|
+
const loaded = yield Promise.all(options.files.slice(0, maxFiles).map((file) => __awaiter(this, void 0, void 0, function* () {
|
|
392
|
+
var _a, _b;
|
|
393
|
+
const classification = classifySlackFile(file);
|
|
394
|
+
if (classification === undefined) {
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
if (file.size !== undefined && file.size > maxFileBytes) {
|
|
398
|
+
(_a = options.log) === null || _a === void 0 ? void 0 : _a.info("slack attachment skipped (size)", {
|
|
399
|
+
file_id: file.id,
|
|
400
|
+
size: file.size,
|
|
401
|
+
max: maxFileBytes,
|
|
402
|
+
});
|
|
403
|
+
return undefined;
|
|
404
|
+
}
|
|
405
|
+
if (file.dataBase64 !== undefined && file.dataBase64.length > 0) {
|
|
406
|
+
return {
|
|
407
|
+
file,
|
|
408
|
+
classification,
|
|
409
|
+
bytes: new Uint8Array(Buffer.from(file.dataBase64, "base64")),
|
|
410
|
+
mimeType: classification.mimeType,
|
|
411
|
+
filename: attachmentFilename(file),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const downloaded = yield downloadSlackFileBytes({
|
|
415
|
+
botToken: options.botToken,
|
|
416
|
+
fileId: file.id,
|
|
417
|
+
fallbackMimeType: classification.mimeType,
|
|
418
|
+
maxBytes: maxFileBytes,
|
|
419
|
+
downloadTimeoutMs,
|
|
420
|
+
});
|
|
421
|
+
if (downloaded === null) {
|
|
422
|
+
(_b = options.log) === null || _b === void 0 ? void 0 : _b.info("slack attachment download failed", {
|
|
423
|
+
file_id: file.id,
|
|
424
|
+
kind: classification.kind,
|
|
425
|
+
});
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
file,
|
|
430
|
+
classification,
|
|
431
|
+
bytes: downloaded.data,
|
|
432
|
+
mimeType: downloaded.mimeType,
|
|
433
|
+
filename: downloaded.filename,
|
|
434
|
+
};
|
|
435
|
+
})));
|
|
436
|
+
const images = [];
|
|
437
|
+
const workspaceFiles = {};
|
|
438
|
+
const annotations = [];
|
|
439
|
+
let totalBytes = 0;
|
|
440
|
+
let imageIndex = 0;
|
|
441
|
+
let documentIndex = 0;
|
|
442
|
+
let videoIndex = 0;
|
|
443
|
+
for (const item of loaded) {
|
|
444
|
+
if (item === undefined) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const { file, classification, bytes, mimeType, filename } = item;
|
|
448
|
+
if (bytes.length === 0) {
|
|
449
|
+
(_a = options.log) === null || _a === void 0 ? void 0 : _a.info("slack attachment download failed", {
|
|
450
|
+
file_id: file.id,
|
|
451
|
+
kind: classification.kind,
|
|
452
|
+
});
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (bytes.length > maxFileBytes ||
|
|
456
|
+
totalBytes + bytes.length > maxTotalBytes) {
|
|
457
|
+
(_b = options.log) === null || _b === void 0 ? void 0 : _b.info("slack attachment skipped (budget)", {
|
|
458
|
+
file_id: file.id,
|
|
459
|
+
bytes: bytes.length,
|
|
460
|
+
});
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
totalBytes += bytes.length;
|
|
464
|
+
if (classification.kind === "image") {
|
|
465
|
+
if (!isSupportedImageFormat(mimeType)) {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
imageIndex++;
|
|
469
|
+
images.push({
|
|
470
|
+
data: Buffer.from(bytes).toString("base64"),
|
|
471
|
+
mimeType,
|
|
472
|
+
});
|
|
473
|
+
annotations.push(`[Image ${imageIndex}: ${filename}]`);
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
const relativePath = `${SLACK_ATTACHMENTS_DIR}/${filename}`;
|
|
477
|
+
const textLike = classification.kind === "document" &&
|
|
478
|
+
isTextLikeBytes({
|
|
479
|
+
mimeType,
|
|
480
|
+
isTextLike: classification.isTextLike,
|
|
481
|
+
bytes,
|
|
482
|
+
});
|
|
483
|
+
if (textLike) {
|
|
484
|
+
workspaceFiles[relativePath] = Buffer.from(bytes).toString("utf8");
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
workspaceFiles[relativePath] = {
|
|
488
|
+
encoding: "base64",
|
|
489
|
+
data: Buffer.from(bytes).toString("base64"),
|
|
490
|
+
mimeType,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
if (classification.kind === "document") {
|
|
494
|
+
documentIndex++;
|
|
495
|
+
annotations.push(`[Document ${documentIndex}: ${filename} → ${relativePath}]`);
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
videoIndex++;
|
|
499
|
+
annotations.push(`[Video ${videoIndex}: ${filename} → ${relativePath}]`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return { images, workspaceFiles, annotations };
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
/** Merge attachment annotations into the user prompt. */
|
|
506
|
+
export function appendSlackAttachmentAnnotations(prompt, annotations) {
|
|
507
|
+
if (annotations.length === 0) {
|
|
508
|
+
return prompt;
|
|
509
|
+
}
|
|
510
|
+
const block = [
|
|
511
|
+
"<slack_attachments>",
|
|
512
|
+
...annotations,
|
|
513
|
+
"</slack_attachments>",
|
|
514
|
+
].join("\n");
|
|
515
|
+
const trimmed = prompt.trim();
|
|
516
|
+
if (trimmed.length === 0) {
|
|
517
|
+
return `${block}\n\n${SLACK_ATTACHMENT_ONLY_PROMPT}`;
|
|
518
|
+
}
|
|
519
|
+
return `${block}\n\n${trimmed}`;
|
|
520
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import type { ArtifactsApi, HostContext, SendMessageFn } from "../../types.js";
|
|
15
15
|
import type { EventIdDedupe } from "./event-id-dedupe.js";
|
|
16
16
|
import type { SlackLog } from "./log.js";
|
|
17
|
-
import type { SlackApiTransport, SlackChannelOptions, SlackCredentials, SlackMessageHandler } from "./types.js";
|
|
17
|
+
import type { SlackApiTransport, SlackChannelOptions, SlackCredentials, SlackMessageFile, SlackMessageHandler } from "./types.js";
|
|
18
18
|
/**
|
|
19
19
|
* Transport placeholder created at `slackChannel()` definition time and
|
|
20
20
|
* bound to the real backend proxy caller when the serve host starts its
|
|
@@ -45,6 +45,12 @@ export interface CursorSlackEnvelope {
|
|
|
45
45
|
matchedBy: "name" | "thread";
|
|
46
46
|
eventId?: string;
|
|
47
47
|
receivedAtMs: number;
|
|
48
|
+
/**
|
|
49
|
+
* Slack file uploads on the triggering message. When `dataBase64` is set
|
|
50
|
+
* the Cursor backend already downloaded bytes (cursorAccount has no bot
|
|
51
|
+
* token for files.slack.com).
|
|
52
|
+
*/
|
|
53
|
+
files?: SlackMessageFile[];
|
|
48
54
|
}
|
|
49
55
|
/** Serve-time runtime handle for one cursor-account Slack channel. */
|
|
50
56
|
export interface SlackCursorAccountRuntime {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-account.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/cursor-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEhB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor-account.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/cursor-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEhB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,sEAAsE;AACtE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,0EAA0E;IAC1E,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;IACpC,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,MAAM,EAAE,MAAM,QAAQ,CAAC;CACxB;AAID,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,yBAAyB,GACjC,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,GACjB,yBAAyB,GAAG,SAAS,CAEvC;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,yBAAyB,CAAC;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,+BAA+B,CAAC,EAAE,CAChC,iBAAiB,EAAE,MAAM,KACtB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEhB"}
|
|
@@ -67,11 +67,11 @@ export function dispatchCursorSlackEnvelope(args) {
|
|
|
67
67
|
});
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
const message = Object.assign({ text: envelope.text, body: envelope.text, markdown: slackTextToMarkdown(envelope.text), ts: envelope.messageTs, threadTs: envelope.threadTs, channelId: envelope.channelId, teamId: envelope.slackTeamId }, (envelope.slackUserId === undefined
|
|
70
|
+
const message = Object.assign(Object.assign({ text: envelope.text, body: envelope.text, markdown: slackTextToMarkdown(envelope.text), ts: envelope.messageTs, threadTs: envelope.threadTs, channelId: envelope.channelId, teamId: envelope.slackTeamId }, (envelope.slackUserId === undefined
|
|
71
71
|
? {}
|
|
72
72
|
: {
|
|
73
73
|
author: { userId: envelope.slackUserId, isBot: false },
|
|
74
|
-
}));
|
|
74
|
+
})), { files: envelope.files });
|
|
75
75
|
// DMs to @Cursor route as direct messages; everything else (explicit
|
|
76
76
|
// `@Cursor <agent> …` mentions and claimed-thread replies) dispatches on
|
|
77
77
|
// the mention handler — a claimed-thread reply is addressed to the agent
|
|
@@ -14,6 +14,7 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
|
|
|
14
14
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
15
15
|
onAppMention: SlackMessageHandler;
|
|
16
16
|
onDirectMessage: SlackMessageHandler;
|
|
17
|
+
onReactionAdded?: SlackMessageHandler;
|
|
17
18
|
credentials: SlackCredentials | undefined;
|
|
18
19
|
eventIds: EventIdDedupe;
|
|
19
20
|
host: HostContext;
|
|
@@ -45,7 +46,7 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
|
|
|
45
46
|
blockExternals?: boolean;
|
|
46
47
|
}
|
|
47
48
|
export declare function dispatchInboundMessage(args: {
|
|
48
|
-
kind: "app_mention" | "direct_message" | "channel_post" | "block_action";
|
|
49
|
+
kind: "app_mention" | "direct_message" | "channel_post" | "reaction_added" | "block_action";
|
|
49
50
|
message: SlackMessage;
|
|
50
51
|
handler: SlackMessageHandler;
|
|
51
52
|
send: SendMessageFn;
|
|
@@ -68,8 +69,8 @@ export declare function dispatchInboundMessage(args: {
|
|
|
68
69
|
}): Promise<void>;
|
|
69
70
|
/**
|
|
70
71
|
* Parse an Events API body (or Socket Mode `events_api` payload) and dispatch
|
|
71
|
-
* app_mention / DM handlers. Deduplicates by `event_id` when
|
|
72
|
-
* true when a handler was scheduled.
|
|
72
|
+
* app_mention / DM / reaction handlers. Deduplicates by `event_id` when
|
|
73
|
+
* present. Returns true when a handler was scheduled.
|
|
73
74
|
*/
|
|
74
75
|
export declare function dispatchInboundFromEventBody(body: unknown, deps: SlackInboundDispatchDeps): boolean;
|
|
75
76
|
//# sourceMappingURL=dispatch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/dispatch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAEX,aAAa,EACd,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/dispatch.ts"],"names":[],"mappings":"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"}
|