@cursor/july 0.1.1
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 +290 -0
- package/LICENSE.md +3 -0
- package/README.md +1233 -0
- package/dist/ab.d.ts +290 -0
- package/dist/ab.d.ts.map +1 -0
- package/dist/ab.js +386 -0
- package/dist/bin/agent-serve.d.ts +15 -0
- package/dist/bin/agent-serve.d.ts.map +1 -0
- package/dist/bin/agent-serve.js +754 -0
- package/dist/channels/github/api.d.ts +101 -0
- package/dist/channels/github/api.d.ts.map +1 -0
- package/dist/channels/github/api.js +229 -0
- package/dist/channels/github/auth.d.ts +67 -0
- package/dist/channels/github/auth.d.ts.map +1 -0
- package/dist/channels/github/auth.js +239 -0
- package/dist/channels/github/binding.d.ts +73 -0
- package/dist/channels/github/binding.d.ts.map +1 -0
- package/dist/channels/github/binding.js +114 -0
- package/dist/channels/github/defaults.d.ts +24 -0
- package/dist/channels/github/defaults.d.ts.map +1 -0
- package/dist/channels/github/defaults.js +100 -0
- package/dist/channels/github/events.d.ts +18 -0
- package/dist/channels/github/events.d.ts.map +1 -0
- package/dist/channels/github/events.js +59 -0
- package/dist/channels/github/forward.d.ts +137 -0
- package/dist/channels/github/forward.d.ts.map +1 -0
- package/dist/channels/github/forward.js +271 -0
- package/dist/channels/github/github-channel.d.ts +127 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -0
- package/dist/channels/github/github-channel.js +1688 -0
- package/dist/channels/github/index.d.ts +52 -0
- package/dist/channels/github/index.d.ts.map +1 -0
- package/dist/channels/github/index.js +51 -0
- package/dist/channels/github/replay.d.ts +115 -0
- package/dist/channels/github/replay.d.ts.map +1 -0
- package/dist/channels/github/replay.js +282 -0
- package/dist/channels/github/state.d.ts +26 -0
- package/dist/channels/github/state.d.ts.map +1 -0
- package/dist/channels/github/state.js +50 -0
- package/dist/channels/github/types.d.ts +385 -0
- package/dist/channels/github/types.d.ts.map +1 -0
- package/dist/channels/github/types.js +1 -0
- package/dist/channels/slack/api.d.ts +117 -0
- package/dist/channels/slack/api.d.ts.map +1 -0
- package/dist/channels/slack/api.js +437 -0
- package/dist/channels/slack/approvals.d.ts +32 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -0
- package/dist/channels/slack/approvals.js +157 -0
- package/dist/channels/slack/assistant.d.ts +23 -0
- package/dist/channels/slack/assistant.d.ts.map +1 -0
- package/dist/channels/slack/assistant.js +67 -0
- package/dist/channels/slack/auth.d.ts +40 -0
- package/dist/channels/slack/auth.d.ts.map +1 -0
- package/dist/channels/slack/auth.js +71 -0
- package/dist/channels/slack/channel-watch.d.ts +46 -0
- package/dist/channels/slack/channel-watch.d.ts.map +1 -0
- package/dist/channels/slack/channel-watch.js +180 -0
- package/dist/channels/slack/constants.d.ts +17 -0
- package/dist/channels/slack/constants.d.ts.map +1 -0
- package/dist/channels/slack/constants.js +27 -0
- package/dist/channels/slack/credentials.d.ts +35 -0
- package/dist/channels/slack/credentials.d.ts.map +1 -0
- package/dist/channels/slack/credentials.js +88 -0
- package/dist/channels/slack/cursor-account.d.ts +76 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -0
- package/dist/channels/slack/cursor-account.js +88 -0
- package/dist/channels/slack/defaults.d.ts +32 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -0
- package/dist/channels/slack/defaults.js +380 -0
- package/dist/channels/slack/dispatch.d.ts +43 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -0
- package/dist/channels/slack/dispatch.js +185 -0
- package/dist/channels/slack/doctor.d.ts +24 -0
- package/dist/channels/slack/doctor.d.ts.map +1 -0
- package/dist/channels/slack/doctor.js +115 -0
- package/dist/channels/slack/event-id-dedupe.d.ts +10 -0
- package/dist/channels/slack/event-id-dedupe.d.ts.map +1 -0
- package/dist/channels/slack/event-id-dedupe.js +23 -0
- package/dist/channels/slack/inbound.d.ts +41 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -0
- package/dist/channels/slack/inbound.js +166 -0
- package/dist/channels/slack/index.d.ts +45 -0
- package/dist/channels/slack/index.d.ts.map +1 -0
- package/dist/channels/slack/index.js +44 -0
- package/dist/channels/slack/init.d.ts +32 -0
- package/dist/channels/slack/init.d.ts.map +1 -0
- package/dist/channels/slack/init.js +82 -0
- package/dist/channels/slack/interactive.d.ts +19 -0
- package/dist/channels/slack/interactive.d.ts.map +1 -0
- package/dist/channels/slack/interactive.js +142 -0
- package/dist/channels/slack/links.d.ts +10 -0
- package/dist/channels/slack/links.d.ts.map +1 -0
- package/dist/channels/slack/links.js +19 -0
- package/dist/channels/slack/live-delivery.d.ts +75 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -0
- package/dist/channels/slack/live-delivery.js +143 -0
- package/dist/channels/slack/log.d.ts +25 -0
- package/dist/channels/slack/log.d.ts.map +1 -0
- package/dist/channels/slack/log.js +47 -0
- package/dist/channels/slack/manifest.d.ts +57 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -0
- package/dist/channels/slack/manifest.js +110 -0
- package/dist/channels/slack/pr-ref.d.ts +18 -0
- package/dist/channels/slack/pr-ref.d.ts.map +1 -0
- package/dist/channels/slack/pr-ref.js +36 -0
- package/dist/channels/slack/setup.d.ts +14 -0
- package/dist/channels/slack/setup.d.ts.map +1 -0
- package/dist/channels/slack/setup.js +86 -0
- package/dist/channels/slack/slack-channel.d.ts +15 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -0
- package/dist/channels/slack/slack-channel.js +281 -0
- package/dist/channels/slack/socket-mode.d.ts +26 -0
- package/dist/channels/slack/socket-mode.d.ts.map +1 -0
- package/dist/channels/slack/socket-mode.js +116 -0
- package/dist/channels/slack/stream.d.ts +26 -0
- package/dist/channels/slack/stream.d.ts.map +1 -0
- package/dist/channels/slack/stream.js +39 -0
- package/dist/channels/slack/tool-approval-events.d.ts +33 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -0
- package/dist/channels/slack/tool-approval-events.js +129 -0
- package/dist/channels/slack/types.d.ts +326 -0
- package/dist/channels/slack/types.d.ts.map +1 -0
- package/dist/channels/slack/types.js +4 -0
- package/dist/channels.d.ts +116 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +294 -0
- package/dist/connections.d.ts +75 -0
- package/dist/connections.d.ts.map +1 -0
- package/dist/connections.js +75 -0
- package/dist/docs/404.html +22 -0
- package/dist/docs/ab.html +87 -0
- package/dist/docs/assets/ab.md.COdXkces.js +63 -0
- package/dist/docs/assets/ab.md.COdXkces.lean.js +1 -0
- package/dist/docs/assets/app.DqfFEmJd.js +1 -0
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +13 -0
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.lean.js +1 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +1 -0
- package/dist/docs/assets/chunks/VPLocalSearchBox.BaLEdS15.js +9 -0
- package/dist/docs/assets/chunks/framework.CAZyNGu9.js +19 -0
- package/dist/docs/assets/chunks/theme.CZRvu_0q.js +2 -0
- package/dist/docs/assets/concepts.md.Cfb9b-k1.js +4 -0
- package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +1 -0
- package/dist/docs/assets/deployment.md.Dx1TYNk5.js +14 -0
- package/dist/docs/assets/deployment.md.Dx1TYNk5.lean.js +1 -0
- package/dist/docs/assets/evals.md.DPZ_MAnI.js +85 -0
- package/dist/docs/assets/evals.md.DPZ_MAnI.lean.js +1 -0
- package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.js +10 -0
- package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.lean.js +1 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.js +9 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.lean.js +1 -0
- package/dist/docs/assets/guides_github.md.DwbKhCeS.js +20 -0
- package/dist/docs/assets/guides_github.md.DwbKhCeS.lean.js +1 -0
- package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.js +28 -0
- package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.lean.js +1 -0
- package/dist/docs/assets/guides_slack.md.bv41fHfW.js +37 -0
- package/dist/docs/assets/guides_slack.md.bv41fHfW.lean.js +1 -0
- package/dist/docs/assets/guides_webhooks.md.hFTik3lf.js +50 -0
- package/dist/docs/assets/guides_webhooks.md.hFTik3lf.lean.js +1 -0
- package/dist/docs/assets/hillclimbing.md.DHNast08.js +4 -0
- package/dist/docs/assets/hillclimbing.md.DHNast08.lean.js +1 -0
- package/dist/docs/assets/index.md.BPKcj5AI.js +20 -0
- package/dist/docs/assets/index.md.BPKcj5AI.lean.js +1 -0
- package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/dist/docs/assets/quickstart.md.tVPiGK_L.js +35 -0
- package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +1 -0
- package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.js +34 -0
- package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.lean.js +1 -0
- package/dist/docs/assets/reference_channels.md.D7JTR03W.js +53 -0
- package/dist/docs/assets/reference_channels.md.D7JTR03W.lean.js +1 -0
- package/dist/docs/assets/reference_cli.md.DA730zCu.js +33 -0
- package/dist/docs/assets/reference_cli.md.DA730zCu.lean.js +1 -0
- package/dist/docs/assets/reference_connections.md.C3vNH_DE.js +26 -0
- package/dist/docs/assets/reference_connections.md.C3vNH_DE.lean.js +1 -0
- package/dist/docs/assets/reference_hooks.md.BCEc3MyM.js +12 -0
- package/dist/docs/assets/reference_hooks.md.BCEc3MyM.lean.js +1 -0
- package/dist/docs/assets/reference_http-api.md.DBAahtdz.js +11 -0
- package/dist/docs/assets/reference_http-api.md.DBAahtdz.lean.js +1 -0
- package/dist/docs/assets/reference_instructions.md.BC05LEQ8.js +12 -0
- package/dist/docs/assets/reference_instructions.md.BC05LEQ8.lean.js +1 -0
- package/dist/docs/assets/reference_playground.md.CPZhfYaO.js +1 -0
- package/dist/docs/assets/reference_playground.md.CPZhfYaO.lean.js +1 -0
- package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.js +31 -0
- package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.lean.js +1 -0
- package/dist/docs/assets/reference_schedules.md.D7qijxLk.js +82 -0
- package/dist/docs/assets/reference_schedules.md.D7qijxLk.lean.js +1 -0
- package/dist/docs/assets/reference_sessions.md.DdjWabnN.js +8 -0
- package/dist/docs/assets/reference_sessions.md.DdjWabnN.lean.js +1 -0
- package/dist/docs/assets/reference_skills.md.VQnlBT3Q.js +15 -0
- package/dist/docs/assets/reference_skills.md.VQnlBT3Q.lean.js +1 -0
- package/dist/docs/assets/reference_subagents.md.CIRAVcPK.js +10 -0
- package/dist/docs/assets/reference_subagents.md.CIRAVcPK.lean.js +1 -0
- package/dist/docs/assets/reference_tools.md.DF5kwlt0.js +46 -0
- package/dist/docs/assets/reference_tools.md.DF5kwlt0.lean.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +1 -0
- package/dist/docs/assets/style.Bj-IXa5W.css +1 -0
- package/dist/docs/assets/troubleshooting.md.DkovjS7h.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DkovjS7h.lean.js +1 -0
- package/dist/docs/building-with-agents.html +37 -0
- package/dist/docs/concepts.html +28 -0
- package/dist/docs/deployment.html +38 -0
- package/dist/docs/evals.html +109 -0
- package/dist/docs/guides/agent-to-agent.html +34 -0
- package/dist/docs/guides/cloud-runtime.html +33 -0
- package/dist/docs/guides/github.html +44 -0
- package/dist/docs/guides/human-in-the-loop.html +52 -0
- package/dist/docs/guides/slack.html +61 -0
- package/dist/docs/guides/webhooks.html +74 -0
- package/dist/docs/hashmap.json +1 -0
- package/dist/docs/hillclimbing.html +28 -0
- package/dist/docs/index.html +44 -0
- package/dist/docs/quickstart.html +59 -0
- package/dist/docs/reference/agent-config.html +58 -0
- package/dist/docs/reference/channels.html +77 -0
- package/dist/docs/reference/cli.html +57 -0
- package/dist/docs/reference/connections.html +50 -0
- package/dist/docs/reference/hooks.html +36 -0
- package/dist/docs/reference/http-api.html +35 -0
- package/dist/docs/reference/instructions.html +36 -0
- package/dist/docs/reference/playground.html +25 -0
- package/dist/docs/reference/project-layout.html +55 -0
- package/dist/docs/reference/schedules.html +106 -0
- package/dist/docs/reference/sessions.html +32 -0
- package/dist/docs/reference/skills.html +39 -0
- package/dist/docs/reference/subagents.html +34 -0
- package/dist/docs/reference/tools.html +70 -0
- package/dist/docs/scaffolding-agents.html +25 -0
- package/dist/docs/troubleshooting.html +25 -0
- package/dist/docs/vp-icons.css +0 -0
- package/dist/evals.d.ts +312 -0
- package/dist/evals.d.ts.map +1 -0
- package/dist/evals.js +254 -0
- package/dist/hooks.d.ts +23 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +23 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/internal/ab-collector.d.ts +42 -0
- package/dist/internal/ab-collector.d.ts.map +1 -0
- package/dist/internal/ab-collector.js +153 -0
- package/dist/internal/ab-fold.d.ts +36 -0
- package/dist/internal/ab-fold.d.ts.map +1 -0
- package/dist/internal/ab-fold.js +171 -0
- package/dist/internal/ab-snapshot.d.ts +70 -0
- package/dist/internal/ab-snapshot.d.ts.map +1 -0
- package/dist/internal/ab-snapshot.js +208 -0
- package/dist/internal/approval-gate.d.ts +34 -0
- package/dist/internal/approval-gate.d.ts.map +1 -0
- package/dist/internal/approval-gate.js +85 -0
- package/dist/internal/auth.d.ts +8 -0
- package/dist/internal/auth.d.ts.map +1 -0
- package/dist/internal/auth.js +27 -0
- package/dist/internal/authored-alias-hooks.d.ts +31 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -0
- package/dist/internal/authored-alias-hooks.js +43 -0
- package/dist/internal/authored-loaders.d.ts +25 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -0
- package/dist/internal/authored-loaders.js +129 -0
- package/dist/internal/bounded-int.d.ts +11 -0
- package/dist/internal/bounded-int.d.ts.map +1 -0
- package/dist/internal/bounded-int.js +13 -0
- package/dist/internal/brand.d.ts +6 -0
- package/dist/internal/brand.d.ts.map +1 -0
- package/dist/internal/brand.js +17 -0
- package/dist/internal/chat-client.d.ts +19 -0
- package/dist/internal/chat-client.d.ts.map +1 -0
- package/dist/internal/chat-client.js +327 -0
- package/dist/internal/cli-ax.d.ts +58 -0
- package/dist/internal/cli-ax.d.ts.map +1 -0
- package/dist/internal/cli-ax.js +345 -0
- package/dist/internal/cli-cursor.d.ts +20 -0
- package/dist/internal/cli-cursor.d.ts.map +1 -0
- package/dist/internal/cli-cursor.js +227 -0
- package/dist/internal/cli-github.d.ts +47 -0
- package/dist/internal/cli-github.d.ts.map +1 -0
- package/dist/internal/cli-github.js +644 -0
- package/dist/internal/cli-slack.d.ts +18 -0
- package/dist/internal/cli-slack.d.ts.map +1 -0
- package/dist/internal/cli-slack.js +144 -0
- package/dist/internal/cloud-merge.d.ts +23 -0
- package/dist/internal/cloud-merge.d.ts.map +1 -0
- package/dist/internal/cloud-merge.js +28 -0
- package/dist/internal/cron.d.ts +17 -0
- package/dist/internal/cron.d.ts.map +1 -0
- package/dist/internal/cron.js +60 -0
- package/dist/internal/cursor/account-mcp.d.ts +95 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -0
- package/dist/internal/cursor/account-mcp.js +342 -0
- package/dist/internal/cursor/backend-client.d.ts +118 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -0
- package/dist/internal/cursor/backend-client.js +477 -0
- package/dist/internal/cursor/credentials.d.ts +112 -0
- package/dist/internal/cursor/credentials.d.ts.map +1 -0
- package/dist/internal/cursor/credentials.js +329 -0
- package/dist/internal/cursor-event-relay.d.ts +111 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -0
- package/dist/internal/cursor-event-relay.js +181 -0
- package/dist/internal/cursor-relay-core.d.ts +113 -0
- package/dist/internal/cursor-relay-core.d.ts.map +1 -0
- package/dist/internal/cursor-relay-core.js +364 -0
- package/dist/internal/cursor-slack-relay.d.ts +94 -0
- package/dist/internal/cursor-slack-relay.d.ts.map +1 -0
- package/dist/internal/cursor-slack-relay.js +171 -0
- package/dist/internal/describe-error.d.ts +3 -0
- package/dist/internal/describe-error.d.ts.map +1 -0
- package/dist/internal/describe-error.js +4 -0
- package/dist/internal/dev-mode.d.ts +13 -0
- package/dist/internal/dev-mode.d.ts.map +1 -0
- package/dist/internal/dev-mode.js +17 -0
- package/dist/internal/discovery.d.ts +55 -0
- package/dist/internal/discovery.d.ts.map +1 -0
- package/dist/internal/discovery.js +1427 -0
- package/dist/internal/distribution.d.ts +47 -0
- package/dist/internal/distribution.d.ts.map +1 -0
- package/dist/internal/distribution.js +82 -0
- package/dist/internal/docs-site.d.ts +28 -0
- package/dist/internal/docs-site.d.ts.map +1 -0
- package/dist/internal/docs-site.js +169 -0
- package/dist/internal/duration.d.ts +8 -0
- package/dist/internal/duration.d.ts.map +1 -0
- package/dist/internal/duration.js +35 -0
- package/dist/internal/eval-run-store.d.ts +81 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -0
- package/dist/internal/eval-run-store.js +396 -0
- package/dist/internal/eval-runner.d.ts +76 -0
- package/dist/internal/eval-runner.d.ts.map +1 -0
- package/dist/internal/eval-runner.js +336 -0
- package/dist/internal/event-log.d.ts +51 -0
- package/dist/internal/event-log.d.ts.map +1 -0
- package/dist/internal/event-log.js +167 -0
- package/dist/internal/event-mapper.d.ts +46 -0
- package/dist/internal/event-mapper.d.ts.map +1 -0
- package/dist/internal/event-mapper.js +226 -0
- package/dist/internal/frontmatter.d.ts +12 -0
- package/dist/internal/frontmatter.d.ts.map +1 -0
- package/dist/internal/frontmatter.js +61 -0
- package/dist/internal/github-fanout.d.ts +32 -0
- package/dist/internal/github-fanout.d.ts.map +1 -0
- package/dist/internal/github-fanout.js +122 -0
- package/dist/internal/handleAgentServeTrigger.d.ts +59 -0
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -0
- package/dist/internal/handleAgentServeTrigger.js +115 -0
- package/dist/internal/host-platforms.d.ts +40 -0
- package/dist/internal/host-platforms.d.ts.map +1 -0
- package/dist/internal/host-platforms.js +113 -0
- package/dist/internal/http-channel.d.ts +54 -0
- package/dist/internal/http-channel.d.ts.map +1 -0
- package/dist/internal/http-channel.js +382 -0
- package/dist/internal/ids.d.ts +19 -0
- package/dist/internal/ids.d.ts.map +1 -0
- package/dist/internal/ids.js +34 -0
- package/dist/internal/init-project.d.ts +22 -0
- package/dist/internal/init-project.d.ts.map +1 -0
- package/dist/internal/init-project.js +125 -0
- package/dist/internal/json-dir-store.d.ts +32 -0
- package/dist/internal/json-dir-store.d.ts.map +1 -0
- package/dist/internal/json-dir-store.js +100 -0
- package/dist/internal/json-schema.d.ts +18 -0
- package/dist/internal/json-schema.d.ts.map +1 -0
- package/dist/internal/json-schema.js +53 -0
- package/dist/internal/log-ring.d.ts +23 -0
- package/dist/internal/log-ring.d.ts.map +1 -0
- package/dist/internal/log-ring.js +42 -0
- package/dist/internal/map-pool.d.ts +6 -0
- package/dist/internal/map-pool.d.ts.map +1 -0
- package/dist/internal/map-pool.js +41 -0
- package/dist/internal/mcp-endpoint.d.ts +59 -0
- package/dist/internal/mcp-endpoint.d.ts.map +1 -0
- package/dist/internal/mcp-endpoint.js +355 -0
- package/dist/internal/mcp-host.d.ts +28 -0
- package/dist/internal/mcp-host.d.ts.map +1 -0
- package/dist/internal/mcp-host.js +162 -0
- package/dist/internal/net.d.ts +5 -0
- package/dist/internal/net.d.ts.map +1 -0
- package/dist/internal/net.js +30 -0
- package/dist/internal/peer-connections.d.ts +44 -0
- package/dist/internal/peer-connections.d.ts.map +1 -0
- package/dist/internal/peer-connections.js +67 -0
- package/dist/internal/playground/static.d.ts +35 -0
- package/dist/internal/playground/static.d.ts.map +1 -0
- package/dist/internal/playground/static.js +162 -0
- package/dist/internal/playground/toolchain.d.ts +57 -0
- package/dist/internal/playground/toolchain.d.ts.map +1 -0
- package/dist/internal/playground/toolchain.js +226 -0
- package/dist/internal/reminder-runner.d.ts +62 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -0
- package/dist/internal/reminder-runner.js +582 -0
- package/dist/internal/reminder-schedule.d.ts +22 -0
- package/dist/internal/reminder-schedule.d.ts.map +1 -0
- package/dist/internal/reminder-schedule.js +82 -0
- package/dist/internal/reminder-store.d.ts +58 -0
- package/dist/internal/reminder-store.d.ts.map +1 -0
- package/dist/internal/reminder-store.js +106 -0
- package/dist/internal/resolved-connections.d.ts +41 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -0
- package/dist/internal/resolved-connections.js +73 -0
- package/dist/internal/review-comments.d.ts +50 -0
- package/dist/internal/review-comments.d.ts.map +1 -0
- package/dist/internal/review-comments.js +194 -0
- package/dist/internal/router.d.ts +33 -0
- package/dist/internal/router.d.ts.map +1 -0
- package/dist/internal/router.js +93 -0
- package/dist/internal/run-client.d.ts +49 -0
- package/dist/internal/run-client.d.ts.map +1 -0
- package/dist/internal/run-client.js +208 -0
- package/dist/internal/schedule-runner.d.ts +31 -0
- package/dist/internal/schedule-runner.d.ts.map +1 -0
- package/dist/internal/schedule-runner.js +126 -0
- package/dist/internal/sdk-runner.d.ts +41 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -0
- package/dist/internal/sdk-runner.js +221 -0
- package/dist/internal/server.d.ts +25 -0
- package/dist/internal/server.d.ts.map +1 -0
- package/dist/internal/server.js +1374 -0
- package/dist/internal/session-engine.d.ts +287 -0
- package/dist/internal/session-engine.d.ts.map +1 -0
- package/dist/internal/session-engine.js +1377 -0
- package/dist/internal/session-store.d.ts +29 -0
- package/dist/internal/session-store.d.ts.map +1 -0
- package/dist/internal/session-store.js +140 -0
- package/dist/internal/session-urls.d.ts +10 -0
- package/dist/internal/session-urls.d.ts.map +1 -0
- package/dist/internal/session-urls.js +25 -0
- package/dist/internal/stream-progress.d.ts +14 -0
- package/dist/internal/stream-progress.d.ts.map +1 -0
- package/dist/internal/stream-progress.js +195 -0
- package/dist/internal/tool-result.d.ts +20 -0
- package/dist/internal/tool-result.d.ts.map +1 -0
- package/dist/internal/tool-result.js +45 -0
- package/dist/internal/trajectory.d.ts +56 -0
- package/dist/internal/trajectory.d.ts.map +1 -0
- package/dist/internal/trajectory.js +248 -0
- package/dist/internal/workspace.d.ts +42 -0
- package/dist/internal/workspace.d.ts.map +1 -0
- package/dist/internal/workspace.js +199 -0
- package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
- package/dist/playground/assets/index-1K-hG-7p.css +1 -0
- package/dist/playground/assets/index-FlWjhg3x.js +79 -0
- package/dist/playground/index.html +17 -0
- package/dist/reminders.d.ts +23 -0
- package/dist/reminders.d.ts.map +1 -0
- package/dist/reminders.js +22 -0
- package/dist/schedules.d.ts +23 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +26 -0
- package/dist/skills.d.ts +22 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +22 -0
- package/dist/tools.d.ts +92 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +68 -0
- package/dist/types.d.ts +1609 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +80 -0
- package/docs/README.md +174 -0
- package/docs/ab.md +355 -0
- package/docs/building-with-agents.md +129 -0
- package/docs/concepts.md +177 -0
- package/docs/deployment.md +218 -0
- package/docs/evals.md +383 -0
- package/docs/guides/agent-to-agent.md +118 -0
- package/docs/guides/cloud-runtime.md +122 -0
- package/docs/guides/github.md +172 -0
- package/docs/guides/human-in-the-loop.md +131 -0
- package/docs/guides/slack.md +245 -0
- package/docs/guides/webhooks.md +201 -0
- package/docs/hillclimbing.md +93 -0
- package/docs/quickstart.md +183 -0
- package/docs/reference/agent-config.md +154 -0
- package/docs/reference/channels.md +206 -0
- package/docs/reference/cli.md +257 -0
- package/docs/reference/connections.md +137 -0
- package/docs/reference/hooks.md +74 -0
- package/docs/reference/http-api.md +219 -0
- package/docs/reference/instructions.md +77 -0
- package/docs/reference/playground.md +67 -0
- package/docs/reference/project-layout.md +119 -0
- package/docs/reference/schedules.md +220 -0
- package/docs/reference/sessions.md +165 -0
- package/docs/reference/skills.md +79 -0
- package/docs/reference/subagents.md +74 -0
- package/docs/reference/tools.md +203 -0
- package/docs/scaffolding-agents.md +113 -0
- package/docs/troubleshooting.md +95 -0
- package/package.json +185 -0
- package/skills/ab/SKILL.md +139 -0
- package/skills/create-agent/SKILL.md +219 -0
- package/skills/debug/SKILL.md +71 -0
- package/skills/evals/SKILL.md +217 -0
- package/skills/framework-map/SKILL.md +142 -0
- package/skills/github/SKILL.md +144 -0
- package/skills/hillclimb/SKILL.md +162 -0
- package/skills/setup-slack/SKILL.md +180 -0
- package/src/ab.ts +675 -0
- package/src/bin/agent-serve.ts +949 -0
- package/src/channels/github/api.ts +374 -0
- package/src/channels/github/auth.ts +275 -0
- package/src/channels/github/binding.ts +223 -0
- package/src/channels/github/defaults.ts +111 -0
- package/src/channels/github/events.ts +72 -0
- package/src/channels/github/forward.ts +381 -0
- package/src/channels/github/github-channel.ts +2270 -0
- package/src/channels/github/index.ts +52 -0
- package/src/channels/github/replay.ts +387 -0
- package/src/channels/github/state.ts +95 -0
- package/src/channels/github/types.ts +490 -0
- package/src/channels/slack/api.ts +580 -0
- package/src/channels/slack/approvals.ts +198 -0
- package/src/channels/slack/assistant.ts +76 -0
- package/src/channels/slack/auth.ts +112 -0
- package/src/channels/slack/channel-watch.ts +219 -0
- package/src/channels/slack/constants.ts +30 -0
- package/src/channels/slack/credentials.ts +90 -0
- package/src/channels/slack/cursor-account.ts +166 -0
- package/src/channels/slack/defaults.ts +450 -0
- package/src/channels/slack/dispatch.ts +293 -0
- package/src/channels/slack/doctor.ts +135 -0
- package/src/channels/slack/event-id-dedupe.ts +30 -0
- package/src/channels/slack/inbound.ts +219 -0
- package/src/channels/slack/index.ts +45 -0
- package/src/channels/slack/init.ts +133 -0
- package/src/channels/slack/interactive.ts +194 -0
- package/src/channels/slack/links.ts +23 -0
- package/src/channels/slack/live-delivery.ts +201 -0
- package/src/channels/slack/log.ts +83 -0
- package/src/channels/slack/manifest.ts +179 -0
- package/src/channels/slack/pr-ref.ts +50 -0
- package/src/channels/slack/setup.ts +97 -0
- package/src/channels/slack/slack-channel.ts +374 -0
- package/src/channels/slack/socket-mode.ts +154 -0
- package/src/channels/slack/stream.ts +63 -0
- package/src/channels/slack/tool-approval-events.ts +136 -0
- package/src/channels/slack/types.ts +349 -0
- package/src/channels.ts +385 -0
- package/src/connections.ts +89 -0
- package/src/evals.ts +501 -0
- package/src/hooks.ts +33 -0
- package/src/index.ts +184 -0
- package/src/internal/ab-collector.ts +210 -0
- package/src/internal/ab-fold.ts +228 -0
- package/src/internal/ab-snapshot.ts +335 -0
- package/src/internal/approval-gate.ts +115 -0
- package/src/internal/auth.ts +39 -0
- package/src/internal/authored-alias-hooks.ts +69 -0
- package/src/internal/authored-loaders.ts +138 -0
- package/src/internal/bounded-int.ts +27 -0
- package/src/internal/brand.ts +29 -0
- package/src/internal/chat-client.ts +407 -0
- package/src/internal/cli-ax.ts +474 -0
- package/src/internal/cli-cursor.ts +275 -0
- package/src/internal/cli-github.ts +849 -0
- package/src/internal/cli-slack.ts +175 -0
- package/src/internal/cloud-merge.ts +41 -0
- package/src/internal/cron.ts +78 -0
- package/src/internal/cursor/account-mcp.ts +472 -0
- package/src/internal/cursor/backend-client.ts +614 -0
- package/src/internal/cursor/credentials.ts +401 -0
- package/src/internal/cursor-event-relay.ts +281 -0
- package/src/internal/cursor-relay-core.ts +444 -0
- package/src/internal/cursor-slack-relay.ts +242 -0
- package/src/internal/describe-error.ts +4 -0
- package/src/internal/dev-mode.ts +20 -0
- package/src/internal/discovery.ts +1709 -0
- package/src/internal/distribution.ts +97 -0
- package/src/internal/docs-site.ts +191 -0
- package/src/internal/duration.ts +39 -0
- package/src/internal/eval-run-store.ts +519 -0
- package/src/internal/eval-runner.ts +522 -0
- package/src/internal/event-log.ts +175 -0
- package/src/internal/event-mapper.ts +272 -0
- package/src/internal/frontmatter.ts +77 -0
- package/src/internal/github-fanout.ts +159 -0
- package/src/internal/handleAgentServeTrigger.ts +156 -0
- package/src/internal/host-platforms.ts +144 -0
- package/src/internal/http-channel.ts +546 -0
- package/src/internal/ids.ts +44 -0
- package/src/internal/init-project.ts +165 -0
- package/src/internal/json-dir-store.ts +109 -0
- package/src/internal/json-schema.ts +69 -0
- package/src/internal/log-ring.ts +59 -0
- package/src/internal/map-pool.ts +32 -0
- package/src/internal/mcp-endpoint.ts +518 -0
- package/src/internal/mcp-host.ts +211 -0
- package/src/internal/net.ts +31 -0
- package/src/internal/peer-connections.ts +100 -0
- package/src/internal/playground/static.ts +189 -0
- package/src/internal/playground/toolchain.ts +277 -0
- package/src/internal/reminder-runner.ts +756 -0
- package/src/internal/reminder-schedule.ts +106 -0
- package/src/internal/reminder-store.ts +145 -0
- package/src/internal/resolved-connections.ts +145 -0
- package/src/internal/review-comments.ts +268 -0
- package/src/internal/router.ts +145 -0
- package/src/internal/run-client.ts +320 -0
- package/src/internal/schedule-runner.ts +161 -0
- package/src/internal/sdk-runner.ts +315 -0
- package/src/internal/server.ts +1737 -0
- package/src/internal/session-engine.ts +1810 -0
- package/src/internal/session-store.ts +147 -0
- package/src/internal/session-urls.ts +40 -0
- package/src/internal/stream-progress.ts +254 -0
- package/src/internal/tool-result.ts +54 -0
- package/src/internal/trajectory.ts +306 -0
- package/src/internal/workspace.ts +223 -0
- package/src/reminders.ts +35 -0
- package/src/schedules.ts +37 -0
- package/src/skills.ts +27 -0
- package/src/tools.ts +127 -0
- package/src/types.ts +1848 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack Block Kit cards for human-in-the-loop tool approvals.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ApprovalDecision } from "../../types.js";
|
|
6
|
+
|
|
7
|
+
export const SLACK_APPROVE_ACTION_ID = "agent_serve_approve";
|
|
8
|
+
export const SLACK_DENY_ACTION_ID = "agent_serve_deny";
|
|
9
|
+
|
|
10
|
+
export interface SlackApprovalActionValue {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
callId: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function encodeApprovalActionValue(
|
|
16
|
+
payload: SlackApprovalActionValue
|
|
17
|
+
): string {
|
|
18
|
+
return JSON.stringify(payload);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function parseApprovalActionValue(
|
|
22
|
+
raw: string
|
|
23
|
+
): SlackApprovalActionValue | null {
|
|
24
|
+
try {
|
|
25
|
+
const value: unknown = JSON.parse(raw);
|
|
26
|
+
if (
|
|
27
|
+
typeof value !== "object" ||
|
|
28
|
+
value === null ||
|
|
29
|
+
typeof (value as SlackApprovalActionValue).sessionId !== "string" ||
|
|
30
|
+
typeof (value as SlackApprovalActionValue).callId !== "string"
|
|
31
|
+
) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const sessionId = (value as SlackApprovalActionValue).sessionId;
|
|
35
|
+
const callId = (value as SlackApprovalActionValue).callId;
|
|
36
|
+
if (sessionId === "" || callId === "") {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return { sessionId, callId };
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function decisionFromActionId(
|
|
46
|
+
actionId: string
|
|
47
|
+
): ApprovalDecision | null {
|
|
48
|
+
if (actionId === SLACK_APPROVE_ACTION_ID) {
|
|
49
|
+
return "approve";
|
|
50
|
+
}
|
|
51
|
+
if (actionId === SLACK_DENY_ACTION_ID) {
|
|
52
|
+
return "deny";
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const REDACTED = "[REDACTED]";
|
|
58
|
+
const SENSITIVE_KEY =
|
|
59
|
+
/(?:pass(?:word|wd)?|secret|token|api[_-]?key|authorization|credential|private[_-]?key|access[_-]?key)/i;
|
|
60
|
+
|
|
61
|
+
/** Strip likely secrets before args are shown in Slack cards. */
|
|
62
|
+
export function redactSensitiveValues(value: unknown): unknown {
|
|
63
|
+
if (value === null || value === undefined) {
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
return value.map((item) => redactSensitiveValues(item));
|
|
68
|
+
}
|
|
69
|
+
if (typeof value === "object") {
|
|
70
|
+
const out: Record<string, unknown> = {};
|
|
71
|
+
for (const [key, nested] of Object.entries(
|
|
72
|
+
value as Record<string, unknown>
|
|
73
|
+
)) {
|
|
74
|
+
out[key] = SENSITIVE_KEY.test(key)
|
|
75
|
+
? REDACTED
|
|
76
|
+
: redactSensitiveValues(nested);
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const SLACK_FIELD_MRDKWN_MAX = 2000;
|
|
84
|
+
const SLACK_ARGS_LABEL = "*Args (redacted)*\n```";
|
|
85
|
+
|
|
86
|
+
/** Max arg body that fits a section `fields` mrkdwn entry (2000 chars incl. label + fences). */
|
|
87
|
+
const SLACK_ARGS_DISPLAY_MAX =
|
|
88
|
+
SLACK_FIELD_MRDKWN_MAX - SLACK_ARGS_LABEL.length - "```".length - 1;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Full redacted JSON for Slack display. Never silently truncates without
|
|
92
|
+
* noting that execution still uses the complete args.
|
|
93
|
+
*/
|
|
94
|
+
export function formatArgsForSlackDisplay(value: unknown): string {
|
|
95
|
+
if (value === undefined || value === null) {
|
|
96
|
+
return "";
|
|
97
|
+
}
|
|
98
|
+
const redacted = redactSensitiveValues(value);
|
|
99
|
+
const text =
|
|
100
|
+
typeof redacted === "string" ? redacted : JSON.stringify(redacted, null, 2);
|
|
101
|
+
if (text.length <= SLACK_ARGS_DISPLAY_MAX) {
|
|
102
|
+
return text;
|
|
103
|
+
}
|
|
104
|
+
const suffix = `\n(${text.length} chars total; execution uses full args)`;
|
|
105
|
+
const bodyBudget = Math.max(0, SLACK_ARGS_DISPLAY_MAX - suffix.length - 1);
|
|
106
|
+
const out = `${text.slice(0, bodyBudget)}…${suffix}`;
|
|
107
|
+
return out.length <= SLACK_ARGS_DISPLAY_MAX
|
|
108
|
+
? out
|
|
109
|
+
: out.slice(0, SLACK_ARGS_DISPLAY_MAX);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function buildApprovalBlocks(args: {
|
|
113
|
+
sessionId: string;
|
|
114
|
+
callId: string;
|
|
115
|
+
toolName: string;
|
|
116
|
+
args?: unknown;
|
|
117
|
+
}): unknown[] {
|
|
118
|
+
const value = encodeApprovalActionValue({
|
|
119
|
+
sessionId: args.sessionId,
|
|
120
|
+
callId: args.callId,
|
|
121
|
+
});
|
|
122
|
+
const argsText = formatArgsForSlackDisplay(args.args);
|
|
123
|
+
const fields: Array<{ type: "mrkdwn"; text: string }> = [
|
|
124
|
+
{
|
|
125
|
+
type: "mrkdwn",
|
|
126
|
+
text: `*Tool*\n\`${args.toolName}\``,
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
if (argsText !== "") {
|
|
130
|
+
fields.push({
|
|
131
|
+
type: "mrkdwn",
|
|
132
|
+
text: `*Args (redacted)*\n\`\`\`${argsText}\`\`\``,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return [
|
|
137
|
+
{
|
|
138
|
+
type: "header",
|
|
139
|
+
text: {
|
|
140
|
+
type: "plain_text",
|
|
141
|
+
text: "Approval required",
|
|
142
|
+
emoji: true,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: "section",
|
|
147
|
+
text: {
|
|
148
|
+
type: "mrkdwn",
|
|
149
|
+
text: "A tool call is parked until someone in this thread approves or denies it.",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
type: "section",
|
|
154
|
+
fields,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
type: "actions",
|
|
158
|
+
block_id: `approval_${args.callId}`.slice(0, 255),
|
|
159
|
+
elements: [
|
|
160
|
+
{
|
|
161
|
+
type: "button",
|
|
162
|
+
action_id: SLACK_APPROVE_ACTION_ID,
|
|
163
|
+
text: { type: "plain_text", text: "Approve", emoji: true },
|
|
164
|
+
style: "primary",
|
|
165
|
+
value,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: "button",
|
|
169
|
+
action_id: SLACK_DENY_ACTION_ID,
|
|
170
|
+
text: { type: "plain_text", text: "Deny", emoji: true },
|
|
171
|
+
style: "danger",
|
|
172
|
+
value,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function buildResolvedApprovalBlocks(args: {
|
|
180
|
+
toolName: string;
|
|
181
|
+
decision: ApprovalDecision;
|
|
182
|
+
byUserId?: string;
|
|
183
|
+
}): unknown[] {
|
|
184
|
+
const verb = args.decision === "approve" ? "Approved" : "Denied";
|
|
185
|
+
const by =
|
|
186
|
+
args.byUserId === undefined || args.byUserId === ""
|
|
187
|
+
? ""
|
|
188
|
+
: ` by <@${args.byUserId}>`;
|
|
189
|
+
return [
|
|
190
|
+
{
|
|
191
|
+
type: "section",
|
|
192
|
+
text: {
|
|
193
|
+
type: "mrkdwn",
|
|
194
|
+
text: `*${verb}*${by} — \`${args.toolName}\``,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assistant thread UX: titles and suggested prompts.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { setSuggestedPrompts, setThreadTitle, truncateTitle } from "./api.js";
|
|
6
|
+
import { defaultSlackLog, type SlackLog } from "./log.js";
|
|
7
|
+
import type { SlackBotToken, SlackSuggestedPrompt } from "./types.js";
|
|
8
|
+
|
|
9
|
+
export function firstNonEmptyLine(text: string): string | undefined {
|
|
10
|
+
for (const line of text.split(/\r?\n/u)) {
|
|
11
|
+
const trimmed = line.trim();
|
|
12
|
+
if (trimmed.length > 0) {
|
|
13
|
+
return trimmed;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function firstLineTitle(text: string): string {
|
|
20
|
+
return truncateTitle(firstNonEmptyLine(text) ?? "Conversation");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function maybeSetThreadTitle(args: {
|
|
24
|
+
botToken: SlackBotToken | undefined;
|
|
25
|
+
channelId: string;
|
|
26
|
+
threadTs: string;
|
|
27
|
+
title: string;
|
|
28
|
+
log?: SlackLog;
|
|
29
|
+
}): Promise<boolean> {
|
|
30
|
+
const log = args.log ?? defaultSlackLog;
|
|
31
|
+
const result = await setThreadTitle({
|
|
32
|
+
botToken: args.botToken,
|
|
33
|
+
channelId: args.channelId,
|
|
34
|
+
threadTs: args.threadTs,
|
|
35
|
+
title: args.title,
|
|
36
|
+
});
|
|
37
|
+
if (!result.ok) {
|
|
38
|
+
log.warn("setTitle not-ok", {
|
|
39
|
+
error: result.error,
|
|
40
|
+
channel: args.channelId,
|
|
41
|
+
thread_ts: args.threadTs,
|
|
42
|
+
});
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function maybeSetSuggestedPrompts(args: {
|
|
49
|
+
botToken: SlackBotToken | undefined;
|
|
50
|
+
channelId: string;
|
|
51
|
+
threadTs: string;
|
|
52
|
+
prompts: SlackSuggestedPrompt[];
|
|
53
|
+
title?: string;
|
|
54
|
+
log?: SlackLog;
|
|
55
|
+
}): Promise<boolean> {
|
|
56
|
+
const log = args.log ?? defaultSlackLog;
|
|
57
|
+
if (args.prompts.length === 0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const result = await setSuggestedPrompts({
|
|
61
|
+
botToken: args.botToken,
|
|
62
|
+
channelId: args.channelId,
|
|
63
|
+
threadTs: args.threadTs,
|
|
64
|
+
prompts: args.prompts,
|
|
65
|
+
...(args.title === undefined ? {} : { title: args.title }),
|
|
66
|
+
});
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
log.warn("setSuggestedPrompts not-ok", {
|
|
69
|
+
error: result.error,
|
|
70
|
+
channel: args.channelId,
|
|
71
|
+
thread_ts: args.threadTs,
|
|
72
|
+
});
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack auth helpers — AuthContext builders for thread-scoped sessions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { samePrincipal } from "../../internal/auth.js";
|
|
6
|
+
import type { AuthContext } from "../../types.js";
|
|
7
|
+
import type { SlackBinding, SlackMessage } from "./types.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build a thread-scoped principal so any participant in the same Slack
|
|
11
|
+
* thread can continue the session. The triggering user is preserved in
|
|
12
|
+
* attributes for message context.
|
|
13
|
+
*/
|
|
14
|
+
export function buildSlackAuthContext(args: {
|
|
15
|
+
channelId: string;
|
|
16
|
+
threadTs: string;
|
|
17
|
+
teamId?: string;
|
|
18
|
+
userId?: string;
|
|
19
|
+
userName?: string;
|
|
20
|
+
isBot?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Engagement surface that started the session (e.g. `"channel_post"` for
|
|
23
|
+
* the opt-in channel watch). Recorded as an attribute; the principal stays
|
|
24
|
+
* thread-scoped so an @mention in the same thread continues the session.
|
|
25
|
+
*/
|
|
26
|
+
engagement?: string;
|
|
27
|
+
}): AuthContext {
|
|
28
|
+
const team = args.teamId ?? "unknown";
|
|
29
|
+
const principalId = `slack:${team}:${args.channelId}:${args.threadTs}`;
|
|
30
|
+
const attributes: Record<string, string> = {
|
|
31
|
+
channel_id: args.channelId,
|
|
32
|
+
thread_ts: args.threadTs,
|
|
33
|
+
};
|
|
34
|
+
if (args.teamId !== undefined) {
|
|
35
|
+
attributes.team_id = args.teamId;
|
|
36
|
+
}
|
|
37
|
+
if (args.userId !== undefined) {
|
|
38
|
+
attributes.user_id = args.userId;
|
|
39
|
+
}
|
|
40
|
+
if (args.userName !== undefined) {
|
|
41
|
+
attributes.user_name = args.userName;
|
|
42
|
+
}
|
|
43
|
+
if (args.isBot === true) {
|
|
44
|
+
attributes.author_type = "bot";
|
|
45
|
+
}
|
|
46
|
+
if (args.engagement !== undefined) {
|
|
47
|
+
attributes.engagement = args.engagement;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
authenticator: "slack",
|
|
51
|
+
principalId,
|
|
52
|
+
principalType: "user",
|
|
53
|
+
attributes,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Auth for a Slack user clicking an interactive Approve/Deny button.
|
|
59
|
+
* Uses the clicker's identity for {@link SessionEngine.resolveApproval},
|
|
60
|
+
* not the stored session principal (which would bypass ownership checks).
|
|
61
|
+
*/
|
|
62
|
+
export function buildSlackInteractiveApprovalAuth(args: {
|
|
63
|
+
sessionAuth: AuthContext;
|
|
64
|
+
channelId: string;
|
|
65
|
+
threadTs: string;
|
|
66
|
+
teamId?: string;
|
|
67
|
+
clickingUserId: string;
|
|
68
|
+
}): AuthContext {
|
|
69
|
+
const clickerAuth = buildSlackAuthContext({
|
|
70
|
+
channelId: args.channelId,
|
|
71
|
+
threadTs: args.threadTs,
|
|
72
|
+
teamId: args.teamId,
|
|
73
|
+
userId: args.clickingUserId,
|
|
74
|
+
});
|
|
75
|
+
if (samePrincipal(args.sessionAuth, clickerAuth)) {
|
|
76
|
+
return clickerAuth;
|
|
77
|
+
}
|
|
78
|
+
const userSuffix = `:${args.clickingUserId}`;
|
|
79
|
+
if (
|
|
80
|
+
args.clickingUserId !== "" &&
|
|
81
|
+
args.sessionAuth.principalId.endsWith(userSuffix)
|
|
82
|
+
) {
|
|
83
|
+
return {
|
|
84
|
+
...clickerAuth,
|
|
85
|
+
principalId: args.sessionAuth.principalId,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return clickerAuth;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function defaultSlackAuth(
|
|
92
|
+
message: SlackMessage,
|
|
93
|
+
ctx: SlackBinding,
|
|
94
|
+
options?: { engagement?: string }
|
|
95
|
+
): AuthContext | null {
|
|
96
|
+
if (message.author === undefined) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return buildSlackAuthContext({
|
|
100
|
+
channelId: ctx.slack.channelId,
|
|
101
|
+
threadTs: ctx.slack.threadTs,
|
|
102
|
+
...(message.teamId === undefined ? {} : { teamId: message.teamId }),
|
|
103
|
+
userId: message.author.userId,
|
|
104
|
+
...(message.author.userName === undefined
|
|
105
|
+
? {}
|
|
106
|
+
: { userName: message.author.userName }),
|
|
107
|
+
isBot: message.author.isBot,
|
|
108
|
+
...(options?.engagement === undefined
|
|
109
|
+
? {}
|
|
110
|
+
: { engagement: options.engagement }),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in channel watch: dispatch on posts in allowlisted channels.
|
|
3
|
+
*
|
|
4
|
+
* Filtering rules (the anti-slop guarantees):
|
|
5
|
+
* - Only explicitly allowlisted channels are watched — no wildcard.
|
|
6
|
+
* - Top-level posts only by default; thread replies never dispatch unless
|
|
7
|
+
* `posts: "all"` is configured.
|
|
8
|
+
* - Posts that @mention the bot are skipped here (the `app_mention` path
|
|
9
|
+
* owns them), and bot-authored posts are dropped upstream in parsing.
|
|
10
|
+
* - An optional debounce window lets rapid edits settle: edits update the
|
|
11
|
+
* pending text, deleting the post cancels the dispatch.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { WebClient } from "@slack/web-api";
|
|
15
|
+
import type { SlackChannelMessageEvent } from "./inbound.js";
|
|
16
|
+
import { defaultSlackLog, type SlackLog } from "./log.js";
|
|
17
|
+
import type { SlackChannelPostsOptions, SlackMessage } from "./types.js";
|
|
18
|
+
|
|
19
|
+
const CHANNEL_ID_PATTERN = /^[CG][A-Z0-9]+$/;
|
|
20
|
+
|
|
21
|
+
/** Allowlist over channel ids and `#names` (names resolve lazily). */
|
|
22
|
+
export class SlackChannelAllowlist {
|
|
23
|
+
private readonly ids = new Set<string>();
|
|
24
|
+
private readonly names = new Set<string>();
|
|
25
|
+
|
|
26
|
+
constructor(entries: readonly string[]) {
|
|
27
|
+
for (const raw of entries) {
|
|
28
|
+
const entry = raw.trim();
|
|
29
|
+
if (entry === "") {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (entry.startsWith("#")) {
|
|
33
|
+
this.names.add(entry.slice(1).toLowerCase());
|
|
34
|
+
} else if (CHANNEL_ID_PATTERN.test(entry)) {
|
|
35
|
+
this.ids.add(entry);
|
|
36
|
+
} else {
|
|
37
|
+
// Bare name without "#" — treat as a name for forgiving authoring.
|
|
38
|
+
this.names.add(entry.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
matches(channelId: string): boolean {
|
|
44
|
+
return this.ids.has(channelId);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
unresolvedNames(): string[] {
|
|
48
|
+
return [...this.names];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Fold resolved `name → id` pairs into the id set. */
|
|
52
|
+
applyResolvedNames(resolved: ReadonlyMap<string, string>): void {
|
|
53
|
+
for (const name of this.names) {
|
|
54
|
+
const id = resolved.get(name);
|
|
55
|
+
if (id !== undefined) {
|
|
56
|
+
this.ids.add(id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve channel `#names` to ids via `conversations.list`. Best-effort:
|
|
64
|
+
* returns whatever resolved; the caller logs names that stayed unresolved.
|
|
65
|
+
*/
|
|
66
|
+
export async function resolveChannelNames(
|
|
67
|
+
client: WebClient,
|
|
68
|
+
names: readonly string[],
|
|
69
|
+
log: SlackLog = defaultSlackLog
|
|
70
|
+
): Promise<Map<string, string>> {
|
|
71
|
+
const wanted = new Set(names.map((name) => name.toLowerCase()));
|
|
72
|
+
const resolved = new Map<string, string>();
|
|
73
|
+
if (wanted.size === 0) {
|
|
74
|
+
return resolved;
|
|
75
|
+
}
|
|
76
|
+
let cursor: string | undefined;
|
|
77
|
+
for (let page = 0; page < 20 && resolved.size < wanted.size; page += 1) {
|
|
78
|
+
const response = await client.conversations.list({
|
|
79
|
+
types: "public_channel,private_channel",
|
|
80
|
+
exclude_archived: true,
|
|
81
|
+
limit: 200,
|
|
82
|
+
...(cursor === undefined ? {} : { cursor }),
|
|
83
|
+
});
|
|
84
|
+
for (const channel of response.channels ?? []) {
|
|
85
|
+
const name = channel.name?.toLowerCase();
|
|
86
|
+
if (name !== undefined && wanted.has(name) && channel.id !== undefined) {
|
|
87
|
+
resolved.set(name, channel.id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
cursor = response.response_metadata?.next_cursor || undefined;
|
|
91
|
+
if (cursor === undefined) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (const name of wanted) {
|
|
96
|
+
if (!resolved.has(name)) {
|
|
97
|
+
log.error("channel watch: could not resolve channel name", {
|
|
98
|
+
name: `#${name}`,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return resolved;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface ChannelPostWatcher {
|
|
106
|
+
/** Handle a parsed channel message event. Returns true when consumed. */
|
|
107
|
+
handle(event: SlackChannelMessageEvent, eventId?: string): boolean;
|
|
108
|
+
/** Cancel pending debounced dispatches. */
|
|
109
|
+
stop(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function createChannelPostWatcher(args: {
|
|
113
|
+
options: SlackChannelPostsOptions;
|
|
114
|
+
allowlist: SlackChannelAllowlist;
|
|
115
|
+
/** Bot user id (from `auth.test`) so bot mentions route via app_mention. */
|
|
116
|
+
getBotUserId: () => string | undefined;
|
|
117
|
+
dispatch: (message: SlackMessage, eventId?: string) => void;
|
|
118
|
+
log?: SlackLog;
|
|
119
|
+
}): ChannelPostWatcher {
|
|
120
|
+
const log = args.log ?? defaultSlackLog;
|
|
121
|
+
const includeReplies = args.options.posts === "all";
|
|
122
|
+
const debounceMs = args.options.debounceMs ?? 0;
|
|
123
|
+
const pending = new Map<
|
|
124
|
+
string,
|
|
125
|
+
{
|
|
126
|
+
timer: ReturnType<typeof setTimeout>;
|
|
127
|
+
message: SlackMessage;
|
|
128
|
+
eventId?: string;
|
|
129
|
+
}
|
|
130
|
+
>();
|
|
131
|
+
|
|
132
|
+
const pendingKey = (channelId: string, ts: string): string =>
|
|
133
|
+
`${channelId}:${ts}`;
|
|
134
|
+
|
|
135
|
+
function skip(reason: string, message: SlackMessage): true {
|
|
136
|
+
log.debug(`channel watch skip (${reason})`, {
|
|
137
|
+
channel: message.channelId,
|
|
138
|
+
message_ts: message.ts,
|
|
139
|
+
thread_ts: message.threadTs,
|
|
140
|
+
});
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function fire(message: SlackMessage, eventId: string | undefined): void {
|
|
145
|
+
log.info("channel watch dispatch", {
|
|
146
|
+
channel: message.channelId,
|
|
147
|
+
message_ts: message.ts,
|
|
148
|
+
thread_ts: message.threadTs,
|
|
149
|
+
event_id: eventId,
|
|
150
|
+
});
|
|
151
|
+
args.dispatch(message, eventId);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
handle(event, eventId) {
|
|
156
|
+
if (event.kind === "deleted") {
|
|
157
|
+
const key = pendingKey(event.channelId, event.ts);
|
|
158
|
+
const entry = pending.get(key);
|
|
159
|
+
if (entry !== undefined) {
|
|
160
|
+
clearTimeout(entry.timer);
|
|
161
|
+
pending.delete(key);
|
|
162
|
+
log.info("channel watch cancel (post deleted)", {
|
|
163
|
+
channel: event.channelId,
|
|
164
|
+
message_ts: event.ts,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const message = event.message;
|
|
171
|
+
if (!args.allowlist.matches(message.channelId)) {
|
|
172
|
+
return skip("channel not allowlisted", message);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (event.kind === "edited") {
|
|
176
|
+
const entry = pending.get(pendingKey(message.channelId, message.ts));
|
|
177
|
+
if (entry !== undefined) {
|
|
178
|
+
entry.message = { ...entry.message, ...message };
|
|
179
|
+
}
|
|
180
|
+
// Edits never (re-)dispatch on their own.
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!includeReplies && message.ts !== message.threadTs) {
|
|
185
|
+
return skip("thread reply (posts: top-level)", message);
|
|
186
|
+
}
|
|
187
|
+
const botUserId = args.getBotUserId();
|
|
188
|
+
if (botUserId !== undefined && message.text.includes(`<@${botUserId}>`)) {
|
|
189
|
+
return skip("bot mention (app_mention path owns it)", message);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (debounceMs <= 0) {
|
|
193
|
+
fire(message, eventId);
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
const key = pendingKey(message.channelId, message.ts);
|
|
197
|
+
const existing = pending.get(key);
|
|
198
|
+
if (existing !== undefined) {
|
|
199
|
+
clearTimeout(existing.timer);
|
|
200
|
+
}
|
|
201
|
+
const entry = {
|
|
202
|
+
timer: setTimeout(() => {
|
|
203
|
+
pending.delete(key);
|
|
204
|
+
fire(entry.message, entry.eventId);
|
|
205
|
+
}, debounceMs),
|
|
206
|
+
message,
|
|
207
|
+
...(eventId === undefined ? {} : { eventId }),
|
|
208
|
+
};
|
|
209
|
+
pending.set(key, entry);
|
|
210
|
+
return true;
|
|
211
|
+
},
|
|
212
|
+
stop() {
|
|
213
|
+
for (const entry of pending.values()) {
|
|
214
|
+
clearTimeout(entry.timer);
|
|
215
|
+
}
|
|
216
|
+
pending.clear();
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Defaults for the Slack channel pack. */
|
|
2
|
+
|
|
3
|
+
export const SLACK_CHANNEL_ID = "slack";
|
|
4
|
+
export const SLACK_TYPING_MIN_GROWTH = 4;
|
|
5
|
+
export const SLACK_TYPING_MIN_INTERVAL_MS = 5_000;
|
|
6
|
+
/**
|
|
7
|
+
* Slack `assistant.threads.setStatus` limits each `loading_messages[]`
|
|
8
|
+
* entry to under 51 characters. `status` is often mirrored into that array,
|
|
9
|
+
* so keep both at 50.
|
|
10
|
+
*/
|
|
11
|
+
export const SLACK_STATUS_MAX_LEN = 50;
|
|
12
|
+
export const SLACK_LOADING_MESSAGE_MAX_LEN = 50;
|
|
13
|
+
export const SLACK_TITLE_MAX_LEN = 80;
|
|
14
|
+
|
|
15
|
+
/** Rotating assistant status lines (Slack `loading_messages`). */
|
|
16
|
+
export const SLACK_DEFAULT_LOADING_MESSAGES = [
|
|
17
|
+
"Thinking…",
|
|
18
|
+
"Working on it…",
|
|
19
|
+
"Almost there…",
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
/** Slack API errors that mean a feature is unavailable for this app. */
|
|
23
|
+
export const SLACK_UNSUPPORTED_ERRORS: Set<string> = new Set([
|
|
24
|
+
"method_not_found",
|
|
25
|
+
"not_allowed",
|
|
26
|
+
"missing_scope",
|
|
27
|
+
"not_enabled",
|
|
28
|
+
"feature_not_enabled",
|
|
29
|
+
"unknown_method",
|
|
30
|
+
]);
|