@cursor/july 0.1.107 → 0.1.109
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 +2 -6
- package/README.md +13 -11
- package/dist/bin/agent-serve.js +30 -8
- package/dist/channels/bitbucket/api.d.ts +41 -0
- package/dist/channels/bitbucket/api.d.ts.map +1 -1
- package/dist/channels/bitbucket/api.js +260 -0
- package/dist/channels/bitbucket/binding.d.ts +4 -0
- package/dist/channels/bitbucket/binding.d.ts.map +1 -1
- package/dist/channels/bitbucket/binding.js +16 -0
- package/dist/channels/bitbucket/index.d.ts +1 -1
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +1 -1
- package/dist/channels/github/github-channel.js +8 -5
- package/dist/channels/github/types.d.ts +5 -1
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/gitlab/api.d.ts +27 -0
- package/dist/channels/gitlab/api.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +88 -0
- package/dist/channels/gitlab/binding.d.ts +5 -0
- package/dist/channels/gitlab/binding.d.ts.map +1 -1
- package/dist/channels/gitlab/binding.js +10 -0
- package/dist/channels/gitlab/index.d.ts +1 -1
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +1 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +27 -13
- package/dist/channels/origin/types.d.ts +5 -1
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.d.ts +10 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +20 -3
- package/dist/channels/slack/slack-channel.d.ts +12 -5
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +59 -8
- package/dist/channels.d.ts +45 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +106 -7
- package/dist/connections.d.ts +2 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +2 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.CtuckIiL.js → app.Cr-wVbnB.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.D0KbSkJn.js} +2 -2
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.D0KbSkJn.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CFVQ4S17.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Bkkhnu8K.js → VPLocalSearchBox.CVQERt56.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DhpIe0Pa.js → theme.Dnsd3XOn.js} +2 -2
- package/dist/docs/assets/concepts.md.B4o63Gul.js +1 -0
- package/dist/docs/assets/{deployment.md.MFPKqsqI.js → deployment.md.JenwuCCB.js} +4 -4
- package/dist/docs/assets/{deployment.md.MFPKqsqI.lean.js → deployment.md.JenwuCCB.lean.js} +1 -1
- package/dist/docs/assets/evals.md.C7JLjoEP.js +211 -0
- package/dist/docs/assets/evals.md.C7JLjoEP.lean.js +1 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.js +10 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.lean.js +1 -0
- package/dist/docs/assets/guides_cloud-agents.md.BsloyHdY.js +9 -0
- package/dist/docs/assets/{guides_cloud-agents.md.DS8RIjwx.lean.js → guides_cloud-agents.md.BsloyHdY.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.c0gdGJ-D.js → guides_github.md.TZaTZlfz.js} +13 -3
- package/dist/docs/assets/{guides_github.md.c0gdGJ-D.lean.js → guides_github.md.TZaTZlfz.lean.js} +1 -1
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.js +14 -0
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.lean.js +1 -0
- package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.js → guides_grokbot-agents.md.DyV-WArv.js} +1 -1
- package/dist/docs/assets/guides_improve.md.BGVk32bK.js +14 -0
- package/dist/docs/assets/guides_improve.md.BGVk32bK.lean.js +1 -0
- package/dist/docs/assets/{guides_slack.md.9oHPye9o.js → guides_slack.md.D4RVMM4G.js} +3 -3
- package/dist/docs/assets/{guides_slack.md.9oHPye9o.lean.js → guides_slack.md.D4RVMM4G.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.CJK484ex.js} +2 -2
- package/dist/docs/assets/{hillclimbing.md.CpTGTCle.js → hillclimbing.md.BOiVo1tf.js} +1 -1
- package/dist/docs/assets/index.md.DD9Q2XuJ.js +5 -0
- package/dist/docs/assets/{index.md.BW_6tOgR.lean.js → index.md.DD9Q2XuJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.js → reference_agent-config.md.CvoL6pof.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.CAo-iK4j.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.Dm67hd2D.js → reference_cli.md.Deg7849l.js} +7 -7
- package/dist/docs/assets/{reference_cli.md.Dm67hd2D.lean.js → reference_cli.md.Deg7849l.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.Di6jJAXF.js → reference_connections.md.BojkC6c5.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CGmMLblt.js → reference_extensions.md.ZAVUyuEX.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.BlM_bOg6.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.BlM_bOg6.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.BwaCo-VO.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.DLnoaczX.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.DLnoaczX.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.js → reference_project-layout.md.BEU8MtQV.js} +3 -3
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.BEU8MtQV.lean.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.CyXV1MUw.js +1 -0
- package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.js → scaffolding-agents.md.Kctn3OVb.js} +1 -1
- package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.js → skills_create-agent.md.Q3h6Je-e.js} +1 -1
- package/dist/docs/assets/{skills_debug.md.CDbPhHfg.js → skills_debug.md.CVjCXMFF.js} +1 -1
- package/dist/docs/assets/{skills_debug.md.CDbPhHfg.lean.js → skills_debug.md.CVjCXMFF.lean.js} +1 -1
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.js +35 -0
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.lean.js +1 -0
- package/dist/docs/assets/skills_evals.md.DFxYPErF.js +25 -0
- package/dist/docs/assets/skills_evals.md.DFxYPErF.lean.js +1 -0
- package/dist/docs/assets/skills_framework-map.md.BxLSOhSY.js +1 -0
- package/dist/docs/assets/{skills_framework-map.md.haibFyoB.lean.js → skills_framework-map.md.BxLSOhSY.lean.js} +1 -1
- package/dist/docs/assets/{skills_github.md.D0JahM8c.js → skills_github.md.hgFX_oKY.js} +1 -1
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.js +1 -0
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.lean.js +1 -0
- package/dist/docs/assets/{storage.md.BOHeqk2M.js → storage.md.BUrhJ-Zz.js} +4 -4
- package/dist/docs/assets/{storage.md.BOHeqk2M.lean.js → storage.md.BUrhJ-Zz.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.CYEAO9bM.js +1 -0
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/building-with-agents.md +3 -2
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +2 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +7 -2
- package/dist/docs/evals.html +161 -35
- package/dist/docs/evals.md +612 -296
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/bitbucket.html +36 -0
- package/dist/docs/guides/bitbucket.md +84 -0
- package/dist/docs/guides/cloud-agents.html +6 -6
- package/dist/docs/guides/cloud-agents.md +4 -3
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +17 -7
- package/dist/docs/guides/github.md +33 -1
- package/dist/docs/guides/gitlab.html +40 -0
- package/dist/docs/guides/gitlab.md +92 -0
- package/dist/docs/guides/grokbot-agents.html +6 -6
- package/dist/docs/guides/grokbot-agents.md +2 -2
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/improve.html +40 -0
- package/dist/docs/guides/improve.md +91 -0
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +5 -5
- package/dist/docs/guides/slack.html +7 -7
- package/dist/docs/guides/slack.md +2 -1
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/guides/webhooks.md +4 -2
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/hillclimbing.md +2 -2
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +14 -6
- package/dist/docs/llms-full.txt +1274 -814
- package/dist/docs/llms.txt +7 -5
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +5 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/channels.md +16 -3
- package/dist/docs/reference/cli.html +11 -11
- package/dist/docs/reference/cli.md +24 -15
- package/dist/docs/reference/connections.html +6 -6
- package/dist/docs/reference/connections.md +2 -1
- package/dist/docs/reference/extensions.html +8 -8
- package/dist/docs/reference/extensions.md +2 -3
- package/dist/docs/reference/hooks.html +7 -7
- package/dist/docs/reference/hooks.md +9 -12
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -3
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/playground.md +0 -4
- package/dist/docs/reference/project-layout.html +7 -7
- package/dist/docs/reference/project-layout.md +1 -8
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/result.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +1 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/scaffolding-agents.md +2 -1
- package/dist/docs/skills/create-agent.html +6 -6
- package/dist/docs/skills/create-agent.md +1 -1
- package/dist/docs/skills/debug.html +5 -5
- package/dist/docs/skills/debug.md +1 -1
- package/dist/docs/skills/deploy.html +61 -0
- package/dist/docs/skills/deploy.md +161 -0
- package/dist/docs/skills/evals.html +8 -8
- package/dist/docs/skills/evals.md +44 -6
- package/dist/docs/skills/framework-map.html +5 -5
- package/dist/docs/skills/framework-map.md +5 -4
- package/dist/docs/skills/github.html +6 -6
- package/dist/docs/skills/github.md +1 -1
- package/dist/docs/skills/hillclimb.html +4 -4
- package/dist/docs/skills/index.html +6 -6
- package/dist/docs/skills/index.md +1 -1
- package/dist/docs/skills/mcp-auth.html +4 -4
- package/dist/docs/skills/otel.html +4 -4
- package/dist/docs/skills/setup-slack.html +4 -4
- package/dist/docs/storage.html +8 -8
- package/dist/docs/storage.md +15 -24
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/grokbot-agents.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +1 -1
- package/dist/extensions/improve/extension.d.ts +46 -0
- package/dist/extensions/improve/extension.d.ts.map +1 -0
- package/dist/extensions/improve/extension.js +41 -0
- package/dist/extensions/improve/skills/yourself.d.ts +4 -0
- package/dist/extensions/improve/skills/yourself.d.ts.map +1 -0
- package/dist/extensions/improve/skills/yourself.js +43 -0
- package/dist/extensions.d.ts +2 -3
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +2 -5
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/internal/authored-alias-hooks.d.ts +5 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +17 -0
- package/dist/internal/authored-loaders.d.ts +4 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +21 -2
- package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
- package/dist/internal/builtin-tools/artifacts.js +2 -3
- package/dist/internal/channel-route-dispatch.d.ts +13 -0
- package/dist/internal/channel-route-dispatch.d.ts.map +1 -0
- package/dist/internal/channel-route-dispatch.js +62 -0
- package/dist/internal/channel-state.d.ts +17 -0
- package/dist/internal/channel-state.d.ts.map +1 -0
- package/dist/internal/channel-state.js +78 -0
- package/dist/internal/cli-ax.d.ts +8 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +100 -3
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +2 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +38 -14
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +15 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +12 -0
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +8 -2
- package/dist/internal/continuation-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +2 -2
- package/dist/internal/continuation-identity.js +8 -3
- package/dist/internal/cursor/credentials.d.ts +8 -2
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +27 -5
- package/dist/internal/deploy-client.d.ts +27 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +32 -0
- package/dist/internal/deploy-manifest.d.ts +23 -0
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +84 -1
- package/dist/internal/describe-error.d.ts +1 -0
- package/dist/internal/describe-error.d.ts.map +1 -1
- package/dist/internal/describe-error.js +25 -0
- package/dist/internal/discovery/agent.d.ts +1 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +0 -5
- package/dist/internal/discovery/extension-overlay.d.ts +1 -2
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
- package/dist/internal/discovery/extension-overlay.js +0 -14
- package/dist/internal/discovery/extensions.d.ts +1 -2
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +4 -22
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +42 -24
- package/dist/internal/discovery/modules.js +0 -1
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +0 -16
- package/dist/internal/eval-runner.js +0 -1
- package/dist/internal/framework-file-storage.d.ts +4 -5
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +4 -5
- package/dist/internal/framework-storage-selection.d.ts +2 -2
- package/dist/internal/framework-storage-selection.js +2 -2
- package/dist/internal/guest-network.d.ts +4 -10
- package/dist/internal/guest-network.d.ts.map +1 -1
- package/dist/internal/guest-network.js +42 -26
- package/dist/internal/hosted-admission-adapter.d.ts +2 -0
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -1
- package/dist/internal/hosted-catch-protocol.d.ts +51 -0
- package/dist/internal/hosted-catch-protocol.d.ts.map +1 -0
- package/dist/internal/hosted-catch-protocol.js +103 -0
- package/dist/internal/hosted-catch.d.ts +40 -0
- package/dist/internal/hosted-catch.d.ts.map +1 -0
- package/dist/internal/hosted-catch.js +149 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +41 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +249 -0
- package/dist/internal/hosted-delivery.d.ts +10 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +100 -22
- package/dist/internal/hosted-execution-diag.d.ts +4 -1
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
- package/dist/internal/hosted-execution-diag.js +13 -4
- package/dist/internal/hosted-execution-flush.d.ts +3 -0
- package/dist/internal/hosted-execution-flush.d.ts.map +1 -1
- package/dist/internal/hosted-execution-flush.js +2 -4
- package/dist/internal/http-control-plane-session.d.ts +30 -0
- package/dist/internal/http-control-plane-session.d.ts.map +1 -0
- package/dist/internal/http-control-plane-session.js +83 -0
- package/dist/internal/init-scaffold.d.ts.map +1 -1
- package/dist/internal/init-scaffold.js +1 -2
- package/dist/internal/install-cursor-skills.d.ts +5 -2
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +25 -5
- package/dist/internal/legacy-command-guard.d.ts +22 -0
- package/dist/internal/legacy-command-guard.d.ts.map +1 -0
- package/dist/internal/legacy-command-guard.js +51 -0
- package/dist/internal/platform-timers.d.ts +7 -0
- package/dist/internal/platform-timers.d.ts.map +1 -1
- package/dist/internal/platform-timers.js +139 -0
- package/dist/internal/reminder-control-plane-protocol.d.ts +2 -0
- package/dist/internal/reminder-control-plane-protocol.d.ts.map +1 -1
- package/dist/internal/reminder-control-plane-protocol.js +9 -2
- package/dist/internal/reminder-runner.d.ts +8 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +36 -9
- package/dist/internal/resolve-prod-target.d.ts +2 -0
- package/dist/internal/resolve-prod-target.d.ts.map +1 -1
- package/dist/internal/resolve-prod-target.js +13 -0
- package/dist/internal/run-client.d.ts +1 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +5 -4
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +57 -70
- package/dist/internal/session-engine.d.ts +7 -41
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +110 -227
- package/dist/internal/storage-coordinator.d.ts +5 -19
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +3 -62
- package/dist/internal/storage-roles.d.ts +4 -9
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/storage-roles.js +2 -2
- package/dist/playground/assets/index-Bhxzrcf6.css +1 -0
- package/dist/playground/assets/index-CqLX5uF3.js +67 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +4 -5
- package/dist/storage-backends/cursor-hosted.d.ts +7 -2
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +29 -31
- package/dist/storage-backends/file-kv.d.ts +9 -12
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +11 -47
- package/dist/storage-protocol.d.ts +3 -11
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +3 -11
- package/dist/storage.d.ts +8 -36
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +8 -44
- package/dist/types.d.ts +53 -62
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +14 -6
- package/docs/building-with-agents.md +3 -2
- package/docs/concepts.md +2 -4
- package/docs/deployment.md +7 -2
- package/docs/evals.md +613 -297
- package/docs/guides/bitbucket.md +89 -0
- package/docs/guides/cloud-agents.md +4 -3
- package/docs/guides/github.md +33 -1
- package/docs/guides/gitlab.md +97 -0
- package/docs/guides/grokbot-agents.md +2 -2
- package/docs/guides/improve.md +96 -0
- package/docs/guides/slack.md +2 -1
- package/docs/guides/webhooks.md +4 -2
- package/docs/hillclimbing.md +2 -2
- package/docs/reference/agent-config.md +5 -2
- package/docs/reference/channels.md +16 -3
- package/docs/reference/cli.md +24 -15
- package/docs/reference/connections.md +2 -1
- package/docs/reference/extensions.md +2 -3
- package/docs/reference/hooks.md +9 -12
- package/docs/reference/http-api.md +2 -3
- package/docs/reference/playground.md +0 -4
- package/docs/reference/project-layout.md +1 -8
- package/docs/reference/sessions.md +1 -2
- package/docs/scaffolding-agents.md +2 -1
- package/docs/skills/index.md +2 -2
- package/docs/storage.md +15 -24
- package/docs/troubleshooting.md +1 -1
- package/package.json +8 -7
- package/skills/create-agent/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/deploy/SKILL.md +169 -0
- package/skills/evals/SKILL.md +45 -8
- package/skills/framework-map/SKILL.md +5 -4
- package/skills/github/SKILL.md +1 -1
- package/src/bin/agent-serve.ts +27 -2
- package/src/channels/bitbucket/api.ts +341 -0
- package/src/channels/bitbucket/binding.ts +25 -0
- package/src/channels/bitbucket/index.ts +2 -0
- package/src/channels/github/github-channel.ts +8 -8
- package/src/channels/github/types.ts +5 -0
- package/src/channels/gitlab/api.ts +123 -0
- package/src/channels/gitlab/binding.ts +12 -0
- package/src/channels/gitlab/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +29 -13
- package/src/channels/origin/types.ts +5 -0
- package/src/channels/slack/dispatch.ts +30 -0
- package/src/channels/slack/slack-channel.ts +69 -7
- package/src/channels.ts +157 -10
- package/src/connections.ts +2 -1
- package/src/extensions/improve/extension.ts +70 -0
- package/src/extensions/improve/skills/yourself.ts +50 -0
- package/src/extensions.ts +2 -6
- package/src/index.ts +0 -3
- package/src/internal/authored-alias-hooks.ts +32 -0
- package/src/internal/authored-loaders.ts +26 -2
- package/src/internal/builtin-tools/artifacts.ts +2 -3
- package/src/internal/channel-route-dispatch.ts +66 -0
- package/src/internal/channel-state.ts +96 -0
- package/src/internal/cli-ax.ts +111 -3
- package/src/internal/cli-cursor.ts +4 -1
- package/src/internal/cli-deploy.ts +50 -10
- package/src/internal/cli-mcp-oauth.ts +18 -0
- package/src/internal/cli-mcp.ts +11 -0
- package/src/internal/cli-slack.ts +15 -2
- package/src/internal/continuation-channel.ts +2 -1
- package/src/internal/continuation-identity.ts +10 -2
- package/src/internal/cursor/credentials.ts +35 -7
- package/src/internal/deploy-client.ts +54 -0
- package/src/internal/deploy-manifest.ts +115 -1
- package/src/internal/describe-error.ts +28 -0
- package/src/internal/discovery/agent.ts +1 -7
- package/src/internal/discovery/extension-overlay.ts +0 -18
- package/src/internal/discovery/extensions.ts +2 -26
- package/src/internal/discovery/info.ts +3 -13
- package/src/internal/discovery/modules.ts +0 -1
- package/src/internal/discovery/project.ts +0 -16
- package/src/internal/eval-runner.ts +0 -1
- package/src/internal/framework-file-storage.ts +4 -5
- package/src/internal/framework-storage-selection.ts +2 -2
- package/src/internal/guest-network.ts +43 -29
- package/src/internal/hosted-admission-adapter.ts +2 -0
- package/src/internal/hosted-catch-protocol.ts +130 -0
- package/src/internal/hosted-catch.ts +192 -0
- package/src/internal/hosted-delivery-protocol.ts +387 -0
- package/src/internal/hosted-delivery.ts +155 -22
- package/src/internal/hosted-execution-diag.ts +21 -3
- package/src/internal/hosted-execution-flush.ts +6 -3
- package/src/internal/http-control-plane-session.ts +104 -0
- package/src/internal/init-scaffold.ts +1 -2
- package/src/internal/install-cursor-skills.ts +38 -5
- package/src/internal/legacy-command-guard.ts +59 -0
- package/src/internal/platform-timers.ts +191 -0
- package/src/internal/reminder-control-plane-protocol.ts +15 -2
- package/src/internal/reminder-runner.ts +60 -9
- package/src/internal/resolve-prod-target.ts +15 -0
- package/src/internal/run-client.ts +1 -1
- package/src/internal/sdk-runner.ts +3 -2
- package/src/internal/server.ts +89 -95
- package/src/internal/session-engine.ts +155 -285
- package/src/internal/storage-coordinator.ts +5 -76
- package/src/internal/storage-roles.ts +4 -9
- package/src/storage-backends/cursor-hosted-v2.ts +4 -7
- package/src/storage-backends/cursor-hosted.ts +40 -38
- package/src/storage-backends/file-kv.ts +10 -51
- package/src/storage-protocol.ts +3 -17
- package/src/storage.ts +10 -101
- package/src/types.ts +58 -62
- package/templates/demo/README.md +10 -6
- package/templates/demo/agent/channels/github.ts +2 -0
- package/templates/demo/agent/channels/queue.ts +6 -2
- package/templates/demo/agent/lib/repos.ts +5 -0
- package/templates/demo/init.json +25 -0
- package/dist/ab.d.ts +0 -209
- package/dist/ab.d.ts.map +0 -1
- package/dist/ab.js +0 -246
- package/dist/docs/ab.html +0 -80
- package/dist/docs/ab.md +0 -332
- package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
- package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DXXZxiMv.js +0 -1
- package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
- package/dist/docs/assets/evals.md.CbMoebP1.js +0 -85
- package/dist/docs/assets/evals.md.CbMoebP1.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-agents.md.DS8RIjwx.js +0 -9
- package/dist/docs/assets/index.md.BW_6tOgR.js +0 -5
- package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
- package/dist/docs/assets/skills_evals.md.723kpUmA.js +0 -25
- package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +0 -1
- package/dist/docs/assets/skills_framework-map.md.haibFyoB.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Cus_YZga.js +0 -1
- package/dist/docs/skills/ab.html +0 -52
- package/dist/docs/skills/ab.md +0 -50
- package/dist/internal/ab-collector.d.ts +0 -44
- package/dist/internal/ab-collector.d.ts.map +0 -1
- package/dist/internal/ab-collector.js +0 -142
- package/dist/internal/ab-fold.d.ts +0 -36
- package/dist/internal/ab-fold.d.ts.map +0 -1
- package/dist/internal/ab-fold.js +0 -175
- package/dist/internal/ab-snapshot.d.ts +0 -68
- package/dist/internal/ab-snapshot.d.ts.map +0 -1
- package/dist/internal/ab-snapshot.js +0 -208
- package/dist/internal/discovery/ab.d.ts +0 -9
- package/dist/internal/discovery/ab.d.ts.map +0 -1
- package/dist/internal/discovery/ab.js +0 -113
- package/dist/playground/assets/index-Bq2HpEQB.js +0 -67
- package/dist/playground/assets/index-CZKKNlmb.css +0 -1
- package/docs/ab.md +0 -337
- package/skills/ab/SKILL.md +0 -58
- package/src/ab.ts +0 -430
- package/src/internal/ab-collector.ts +0 -200
- package/src/internal/ab-fold.ts +0 -232
- package/src/internal/ab-snapshot.ts +0 -331
- package/src/internal/discovery/ab.ts +0 -131
- /package/dist/docs/assets/{concepts.md.DgEcZOfT.lean.js → concepts.md.B4o63Gul.lean.js} +0 -0
- /package/dist/docs/assets/{guides_grokbot-agents.md.DVqdhBKb.lean.js → guides_grokbot-agents.md.DyV-WArv.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.CJK484ex.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.CpTGTCle.lean.js → hillclimbing.md.BOiVo1tf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.CHNpiyp4.lean.js → reference_agent-config.md.CvoL6pof.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.Di6jJAXF.lean.js → reference_connections.md.BojkC6c5.lean.js} +0 -0
- /package/dist/docs/assets/{reference_extensions.md.CGmMLblt.lean.js → reference_extensions.md.ZAVUyuEX.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.BwaCo-VO.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.CyXV1MUw.lean.js} +0 -0
- /package/dist/docs/assets/{scaffolding-agents.md.em43xlY1.lean.js → scaffolding-agents.md.Kctn3OVb.lean.js} +0 -0
- /package/dist/docs/assets/{skills_create-agent.md.BVoWPcan.lean.js → skills_create-agent.md.Q3h6Je-e.lean.js} +0 -0
- /package/dist/docs/assets/{skills_github.md.D0JahM8c.lean.js → skills_github.md.hgFX_oKY.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Cus_YZga.lean.js → troubleshooting.md.CYEAO9bM.lean.js} +0 -0
|
@@ -92,6 +92,35 @@ export interface GitLabClient {
|
|
|
92
92
|
request<T = unknown>(input: GitLabRequestInput): Promise<T>;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
export interface GitLabApiMergeRequest {
|
|
96
|
+
iid: number;
|
|
97
|
+
title?: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
state?: string;
|
|
100
|
+
draft?: boolean;
|
|
101
|
+
webUrl?: string;
|
|
102
|
+
headSha?: string;
|
|
103
|
+
sourceBranch?: string;
|
|
104
|
+
targetBranch?: string;
|
|
105
|
+
authorUsername?: string;
|
|
106
|
+
baseSha?: string;
|
|
107
|
+
changedFilesCount?: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface GitLabApiMergeRequestDiff {
|
|
111
|
+
oldPath: string;
|
|
112
|
+
newPath: string;
|
|
113
|
+
patch?: string;
|
|
114
|
+
status: "added" | "modified" | "removed" | "renamed";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Project-bound merge-request reads shared by GitLab agents. */
|
|
118
|
+
export interface GitLabApi {
|
|
119
|
+
getMergeRequest(iid: number): Promise<GitLabApiMergeRequest>;
|
|
120
|
+
getMergeBaseSha(base: string, headSha: string): Promise<string | undefined>;
|
|
121
|
+
listMergeRequestDiffs(iid: number): Promise<GitLabApiMergeRequestDiff[]>;
|
|
122
|
+
}
|
|
123
|
+
|
|
95
124
|
function envValue(value: string | undefined): string | undefined {
|
|
96
125
|
const trimmed = value?.trim();
|
|
97
126
|
return trimmed === undefined || trimmed === "" ? undefined : trimmed;
|
|
@@ -136,6 +165,100 @@ export function gitlabProjectPathSegment(project: number | string): string {
|
|
|
136
165
|
: encodeURIComponent(project.replace(/^\/+|\/+$/g, ""));
|
|
137
166
|
}
|
|
138
167
|
|
|
168
|
+
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
169
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
170
|
+
? (value as Record<string, unknown>)
|
|
171
|
+
: undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function nonEmptyString(value: unknown): string | undefined {
|
|
175
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const GITLAB_DIFFS_PER_PAGE = 100;
|
|
179
|
+
|
|
180
|
+
export function createGitLabApi(
|
|
181
|
+
client: Pick<GitLabClient, "request">,
|
|
182
|
+
project: number | string
|
|
183
|
+
): GitLabApi {
|
|
184
|
+
const projectPath = `/projects/${gitlabProjectPathSegment(project)}`;
|
|
185
|
+
return {
|
|
186
|
+
async getMergeRequest(iid) {
|
|
187
|
+
const raw = await client.request<Record<string, unknown>>({
|
|
188
|
+
method: "GET",
|
|
189
|
+
path: `${projectPath}/merge_requests/${iid}`,
|
|
190
|
+
});
|
|
191
|
+
const diffRefs = asRecord(raw.diff_refs);
|
|
192
|
+
const changesCount = nonEmptyString(raw.changes_count);
|
|
193
|
+
return {
|
|
194
|
+
iid: (raw.iid as number | null | undefined) ?? iid,
|
|
195
|
+
title: raw.title as string | undefined,
|
|
196
|
+
description:
|
|
197
|
+
raw.description === null
|
|
198
|
+
? undefined
|
|
199
|
+
: (raw.description as string | undefined),
|
|
200
|
+
state: raw.state as string | undefined,
|
|
201
|
+
draft:
|
|
202
|
+
typeof raw.draft === "boolean"
|
|
203
|
+
? raw.draft
|
|
204
|
+
: typeof raw.work_in_progress === "boolean"
|
|
205
|
+
? raw.work_in_progress
|
|
206
|
+
: undefined,
|
|
207
|
+
webUrl: raw.web_url as string | undefined,
|
|
208
|
+
headSha:
|
|
209
|
+
(raw.sha as string | null | undefined) ??
|
|
210
|
+
(diffRefs?.head_sha as string | undefined),
|
|
211
|
+
sourceBranch: raw.source_branch as string | undefined,
|
|
212
|
+
targetBranch: raw.target_branch as string | undefined,
|
|
213
|
+
authorUsername: asRecord(raw.author)?.username as string | undefined,
|
|
214
|
+
baseSha: nonEmptyString(diffRefs?.base_sha),
|
|
215
|
+
changedFilesCount:
|
|
216
|
+
changesCount !== undefined && /^\d+$/.test(changesCount)
|
|
217
|
+
? Number(changesCount)
|
|
218
|
+
: undefined,
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
async getMergeBaseSha(base, headSha) {
|
|
222
|
+
const data = await client.request<{ id?: string }>({
|
|
223
|
+
method: "GET",
|
|
224
|
+
path: `${projectPath}/repository/merge_base?refs[]=${encodeURIComponent(base)}&refs[]=${encodeURIComponent(headSha)}`,
|
|
225
|
+
});
|
|
226
|
+
return nonEmptyString(data.id);
|
|
227
|
+
},
|
|
228
|
+
async listMergeRequestDiffs(iid) {
|
|
229
|
+
const files: GitLabApiMergeRequestDiff[] = [];
|
|
230
|
+
for (let page = 1; ; page += 1) {
|
|
231
|
+
const diffs = await client.request<Record<string, unknown>[]>({
|
|
232
|
+
method: "GET",
|
|
233
|
+
path: `${projectPath}/merge_requests/${iid}/diffs`,
|
|
234
|
+
query: { page, per_page: GITLAB_DIFFS_PER_PAGE },
|
|
235
|
+
});
|
|
236
|
+
for (const diff of diffs) {
|
|
237
|
+
const status =
|
|
238
|
+
diff.new_file === true
|
|
239
|
+
? "added"
|
|
240
|
+
: diff.deleted_file === true
|
|
241
|
+
? "removed"
|
|
242
|
+
: diff.renamed_file === true
|
|
243
|
+
? "renamed"
|
|
244
|
+
: "modified";
|
|
245
|
+
const rawPatch =
|
|
246
|
+
typeof diff.diff === "string" ? diff.diff : undefined;
|
|
247
|
+
files.push({
|
|
248
|
+
oldPath: diff.old_path as string,
|
|
249
|
+
newPath: diff.new_path as string,
|
|
250
|
+
status,
|
|
251
|
+
patch: rawPatch?.replace(/\n$/, ""),
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (diffs.length < GITLAB_DIFFS_PER_PAGE) {
|
|
255
|
+
return files;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
139
262
|
function buildQuery(query: GitLabRequestInput["query"]): string {
|
|
140
263
|
if (query === undefined) {
|
|
141
264
|
return "";
|
|
@@ -176,6 +176,18 @@ export function gitlabMergeRequestUrl(
|
|
|
176
176
|
return explicit ?? `${project.webUrl}/-/merge_requests/${iid}`;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Whether an `update` payload marks a draft merge request ready. GitLab uses
|
|
181
|
+
* either `changes.draft` or the legacy `changes.work_in_progress` shape.
|
|
182
|
+
*/
|
|
183
|
+
export function gitlabDraftMarkedReady(
|
|
184
|
+
payload: Record<string, unknown>
|
|
185
|
+
): boolean {
|
|
186
|
+
const changes = asRecord(payload.changes);
|
|
187
|
+
const draft = asRecord(changes?.draft ?? changes?.work_in_progress);
|
|
188
|
+
return draft?.current === false && draft.previous !== false;
|
|
189
|
+
}
|
|
190
|
+
|
|
179
191
|
/** Normalize a merge-request record (`object_attributes` or `merge_request`). */
|
|
180
192
|
export function gitlabMergeRequestFromRecord(
|
|
181
193
|
project: GitLabProjectRef,
|
|
@@ -99,13 +99,20 @@ function asBoolean(value: unknown): boolean | undefined {
|
|
|
99
99
|
function originActor(value: unknown): OriginActor | undefined {
|
|
100
100
|
const record = asRecord(value);
|
|
101
101
|
if (record === undefined) return undefined;
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
|
|
103
|
+
const nestedActors = [
|
|
104
|
+
["user", asRecord(record.user)],
|
|
105
|
+
["app", asRecord(record.app)],
|
|
106
|
+
["service_account", asRecord(record.serviceAccount)],
|
|
107
|
+
] as const;
|
|
108
|
+
for (const [kind, actor] of nestedActors) {
|
|
109
|
+
const id = asNonEmptyString(actor?.id);
|
|
110
|
+
if (id !== undefined) {
|
|
111
|
+
return { id, kind };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const id = asNonEmptyString(record.id);
|
|
109
116
|
if (id === undefined) return undefined;
|
|
110
117
|
const kind = asNonEmptyString(record.kind);
|
|
111
118
|
return kind === undefined ? { id } : { id, kind };
|
|
@@ -361,16 +368,20 @@ export function defaultOriginAuth(
|
|
|
361
368
|
ctx: Omit<OriginEventContext, "host" | "artifacts" | "origin">
|
|
362
369
|
): AuthContext {
|
|
363
370
|
const senderId = ctx.sender?.id;
|
|
371
|
+
const senderKind = ctx.sender?.kind;
|
|
364
372
|
return {
|
|
365
373
|
authenticator: "origin-webhook",
|
|
366
374
|
principalId: senderId ?? "origin",
|
|
367
|
-
principalType:
|
|
375
|
+
principalType:
|
|
376
|
+
senderKind === "app" || senderKind === "service_account"
|
|
377
|
+
? "service"
|
|
378
|
+
: "user",
|
|
368
379
|
attributes: {
|
|
369
380
|
conversation_kind: "pull_request",
|
|
370
381
|
repository: ctx.repository.fullName,
|
|
371
382
|
...(ctx.deliveryId === undefined ? {} : { delivery_id: ctx.deliveryId }),
|
|
372
383
|
...(senderId === undefined ? {} : { subject: senderId }),
|
|
373
|
-
...(
|
|
384
|
+
...(senderKind === undefined ? {} : { user_type: senderKind }),
|
|
374
385
|
issuer: `origin:${ctx.repository.owner}`,
|
|
375
386
|
},
|
|
376
387
|
};
|
|
@@ -461,17 +472,19 @@ async function startTurn(input: {
|
|
|
461
472
|
state: OriginChannelState;
|
|
462
473
|
}): Promise<Response> {
|
|
463
474
|
const source = continuationSource(input.options.continuation, "origin");
|
|
475
|
+
const cloud = input.dispatch.cloud ?? input.cloud;
|
|
476
|
+
const state = { ...input.dispatch.state, ...input.state };
|
|
464
477
|
const session = await input.args.send(input.message, {
|
|
465
478
|
auth: input.dispatch.auth,
|
|
466
479
|
...(source === "engine"
|
|
467
480
|
? { continuationToken: originContinuationKey(input.ctx) }
|
|
468
481
|
: {}),
|
|
469
482
|
title: input.dispatch.title ?? defaultOriginTitle(input.ctx),
|
|
470
|
-
|
|
471
|
-
state:
|
|
483
|
+
cloud,
|
|
484
|
+
state: state as unknown as JsonValue,
|
|
472
485
|
// Resume must refresh the triggering comment / delivery identifiers so
|
|
473
486
|
// reply delivery targets the latest wake, not the session's first.
|
|
474
|
-
refreshState:
|
|
487
|
+
refreshState: state as unknown as JsonValue,
|
|
475
488
|
});
|
|
476
489
|
return turnStarted(session);
|
|
477
490
|
}
|
|
@@ -605,7 +618,10 @@ export async function dispatchOriginWebhook(input: {
|
|
|
605
618
|
ctx,
|
|
606
619
|
dispatch,
|
|
607
620
|
extra: { event: eventType },
|
|
608
|
-
message:
|
|
621
|
+
message:
|
|
622
|
+
commentBody.trim() === ""
|
|
623
|
+
? `Origin comment on ${ctx.repository.fullName}#${ctx.pullRequestNumber}`
|
|
624
|
+
: commentBody.trim(),
|
|
609
625
|
triggeringCommentId: commentId,
|
|
610
626
|
});
|
|
611
627
|
}
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
ChannelEventHandlers,
|
|
8
8
|
ChannelStartArgs,
|
|
9
9
|
HostContext,
|
|
10
|
+
JsonObject,
|
|
10
11
|
SendMessageFn,
|
|
11
12
|
} from "../../types.js";
|
|
12
13
|
import type { OriginTokenProvider } from "./api.js";
|
|
@@ -95,6 +96,10 @@ export type OriginTurnDispatch = {
|
|
|
95
96
|
message?: string;
|
|
96
97
|
title?: string;
|
|
97
98
|
context?: readonly string[];
|
|
99
|
+
/** Per-turn cloud options. Overrides the channel-level `cloud` resolver. */
|
|
100
|
+
cloud?: AgentCloudOptions;
|
|
101
|
+
/** Extra durable channel state. Provider-owned fields take precedence. */
|
|
102
|
+
state?: JsonObject;
|
|
98
103
|
};
|
|
99
104
|
|
|
100
105
|
/** Bound per-delivery helpers passed to an {@link OriginTaskDispatch.task}. */
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type MailboxContinuation,
|
|
9
9
|
normalizeIdentity,
|
|
10
10
|
} from "../../internal/continuation-identity.js";
|
|
11
|
+
import { isDeferredChannelSession } from "../../internal/deferred-channel-session.js";
|
|
11
12
|
import { routeLocalIngressContinuation } from "../../internal/local-ingress.js";
|
|
12
13
|
import { steeringEnabled } from "../../internal/steering.js";
|
|
13
14
|
import type {
|
|
@@ -189,6 +190,14 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
|
|
|
189
190
|
*/
|
|
190
191
|
suggestedPrompts?: SlackSuggestedPrompt[];
|
|
191
192
|
suggestedPromptsTitle?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Rethrow handler failures out of the dispatch promise instead of
|
|
195
|
+
* swallowing them after the error log. Hosted admission sets this so a
|
|
196
|
+
* throwing handler rejects `waitUntil` and surfaces as a retryable 503
|
|
197
|
+
* to the control plane (matching the GitHub/Origin adapters); the
|
|
198
|
+
* long-lived Socket Mode loop keeps the swallow-and-log default.
|
|
199
|
+
*/
|
|
200
|
+
propagateHandlerErrors?: boolean;
|
|
192
201
|
}
|
|
193
202
|
|
|
194
203
|
function triggeringMergeMessage(
|
|
@@ -267,6 +276,8 @@ export async function dispatchInboundMessage(args: {
|
|
|
267
276
|
followUpStatus?: boolean;
|
|
268
277
|
blockExternals?: boolean;
|
|
269
278
|
continuation?: ContinuationIdentity;
|
|
279
|
+
/** See {@link SlackInboundDispatchDeps.propagateHandlerErrors}. */
|
|
280
|
+
propagateHandlerErrors?: boolean;
|
|
270
281
|
}): Promise<void> {
|
|
271
282
|
const { message, kind } = args;
|
|
272
283
|
const log = args.log ?? defaultSlackLog;
|
|
@@ -399,6 +410,9 @@ export async function dispatchInboundMessage(args: {
|
|
|
399
410
|
thread_ts: message.threadTs,
|
|
400
411
|
event_id: args.eventId,
|
|
401
412
|
});
|
|
413
|
+
if (args.propagateHandlerErrors === true) {
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
402
416
|
return;
|
|
403
417
|
}
|
|
404
418
|
if (decision === null || decision === undefined) {
|
|
@@ -527,6 +541,19 @@ export async function dispatchInboundMessage(args: {
|
|
|
527
541
|
|
|
528
542
|
try {
|
|
529
543
|
const session = await args.send(prompt, sendOptions);
|
|
544
|
+
if (isDeferredChannelSession(session)) {
|
|
545
|
+
// Hosted admission captured the send; the control plane allocates
|
|
546
|
+
// the session and runs the turn only after this delivery is
|
|
547
|
+
// acknowledged, so there is nothing to observe or coalesce yet.
|
|
548
|
+
log.info("session send captured (hosted admission)", {
|
|
549
|
+
kind,
|
|
550
|
+
continuation,
|
|
551
|
+
channel: message.channelId,
|
|
552
|
+
thread_ts: message.threadTs,
|
|
553
|
+
event_id: args.eventId,
|
|
554
|
+
});
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
530
557
|
log.info(
|
|
531
558
|
session.coalesced === true ? "session coalesced" : "session start",
|
|
532
559
|
{
|
|
@@ -659,6 +686,7 @@ export function dispatchInboundFromEventBody(
|
|
|
659
686
|
kind: "app_mention",
|
|
660
687
|
message: mention,
|
|
661
688
|
handler: deps.onAppMention,
|
|
689
|
+
propagateHandlerErrors: deps.propagateHandlerErrors,
|
|
662
690
|
send: deps.send,
|
|
663
691
|
credentials: deps.credentials,
|
|
664
692
|
host: deps.host,
|
|
@@ -702,6 +730,7 @@ export function dispatchInboundFromEventBody(
|
|
|
702
730
|
kind: "direct_message",
|
|
703
731
|
message: dm,
|
|
704
732
|
handler: deps.onDirectMessage,
|
|
733
|
+
propagateHandlerErrors: deps.propagateHandlerErrors,
|
|
705
734
|
send: deps.send,
|
|
706
735
|
credentials: deps.credentials,
|
|
707
736
|
host: deps.host,
|
|
@@ -739,6 +768,7 @@ export function dispatchInboundFromEventBody(
|
|
|
739
768
|
kind: "reaction_added",
|
|
740
769
|
message: reaction,
|
|
741
770
|
handler: deps.onReactionAdded,
|
|
771
|
+
propagateHandlerErrors: deps.propagateHandlerErrors,
|
|
742
772
|
send: deps.send,
|
|
743
773
|
credentials: deps.credentials,
|
|
744
774
|
host: deps.host,
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `slackChannel()` — platform channel pack for Slack
|
|
2
|
+
* `slackChannel()` — platform channel pack for Slack.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Request URL or Events HTTP
|
|
6
|
-
* is enabled, Approve/Deny buttons
|
|
7
|
-
* envelopes.
|
|
4
|
+
* Local / self-hosted transport is Socket Mode: inbound events arrive over
|
|
5
|
+
* a WebSocket (`SLACK_APP_TOKEN`); no public Request URL or Events HTTP
|
|
6
|
+
* route is required. When `toolApprovals` is enabled, Approve/Deny buttons
|
|
7
|
+
* arrive as Socket Mode `interactive` envelopes.
|
|
8
|
+
*
|
|
9
|
+
* Hosted v2 transport is the control plane's Events API ingest: the CP
|
|
10
|
+
* verifies the managed app's signature, fans out on the declared
|
|
11
|
+
* `slackEventTypes` (`app_mention`, `message`), and delivers the full
|
|
12
|
+
* `event_callback` body through hosted admission — the attached adapter
|
|
13
|
+
* routes it through the same inbound dispatch as Socket Mode. Without an
|
|
14
|
+
* app token the socket transport idles, so a hosted pod never needs one.
|
|
8
15
|
*/
|
|
9
16
|
|
|
10
17
|
import { allowAll, defineChannel } from "../../channels.js";
|
|
18
|
+
import {
|
|
19
|
+
skipped,
|
|
20
|
+
withPropagatingBackgroundErrors,
|
|
21
|
+
} from "../../internal/channel-dispatch.js";
|
|
11
22
|
import {
|
|
12
23
|
continuationSource,
|
|
13
24
|
normalizeIdentity,
|
|
14
25
|
} from "../../internal/continuation-identity.js";
|
|
26
|
+
import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-adapter.js";
|
|
15
27
|
import type {
|
|
16
28
|
ArtifactsApi,
|
|
17
29
|
ChannelDefinition,
|
|
@@ -51,7 +63,7 @@ import {
|
|
|
51
63
|
emptySlackChannelState,
|
|
52
64
|
type SlackInboundDispatchDeps,
|
|
53
65
|
} from "./dispatch.js";
|
|
54
|
-
import { createEventIdDedupe } from "./event-id-dedupe.js";
|
|
66
|
+
import { createEventIdDedupe, type EventIdDedupe } from "./event-id-dedupe.js";
|
|
55
67
|
import {
|
|
56
68
|
dispatchBlockAction,
|
|
57
69
|
dispatchInteractiveFromPayload,
|
|
@@ -159,6 +171,18 @@ export function slackChannel(
|
|
|
159
171
|
normalizeBotMentionAllowlist(botMentions.allowFrom);
|
|
160
172
|
}
|
|
161
173
|
const eventIds = createEventIdDedupe();
|
|
174
|
+
// Hosted v2 event capability, matching what the engagement flags can
|
|
175
|
+
// dispatch: mentions ride `app_mention`; DMs and watched channel posts
|
|
176
|
+
// both arrive as `message`. Membership of `slack.thread/v2` admits
|
|
177
|
+
// exactly these two, so `reaction_added` (hosted follow-up only inside
|
|
178
|
+
// an existing thread) is deliberately not declared.
|
|
179
|
+
const slackEventTypes: string[] = [];
|
|
180
|
+
if (mentionsEnabled) {
|
|
181
|
+
slackEventTypes.push("app_mention");
|
|
182
|
+
}
|
|
183
|
+
if (directMessagesEnabled || channelPosts !== undefined) {
|
|
184
|
+
slackEventTypes.push("message");
|
|
185
|
+
}
|
|
162
186
|
const toolApprovals = options.toolApprovals === true;
|
|
163
187
|
const interactivity = options.interactivity === true;
|
|
164
188
|
const onBlockAction = options.onBlockAction;
|
|
@@ -201,6 +225,9 @@ export function slackChannel(
|
|
|
201
225
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
202
226
|
host: HostContext;
|
|
203
227
|
artifacts: ArtifactsApi;
|
|
228
|
+
/** Override the channel-level dedupe (hosted admission passes a fresh one). */
|
|
229
|
+
eventIds?: EventIdDedupe;
|
|
230
|
+
propagateHandlerErrors?: boolean;
|
|
204
231
|
hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
|
|
205
232
|
isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
|
|
206
233
|
getContinuationLastBotMessageTs?: (
|
|
@@ -216,7 +243,8 @@ export function slackChannel(
|
|
|
216
243
|
onDirectMessage,
|
|
217
244
|
...(onReactionAdded === undefined ? {} : { onReactionAdded }),
|
|
218
245
|
credentials,
|
|
219
|
-
eventIds,
|
|
246
|
+
eventIds: args.eventIds ?? eventIds,
|
|
247
|
+
propagateHandlerErrors: args.propagateHandlerErrors,
|
|
220
248
|
host: args.host,
|
|
221
249
|
artifacts: args.artifacts,
|
|
222
250
|
log: getLog(),
|
|
@@ -253,6 +281,10 @@ export function slackChannel(
|
|
|
253
281
|
routes: [],
|
|
254
282
|
meta: {
|
|
255
283
|
kind: "slack",
|
|
284
|
+
// Omitted (not empty) when nothing dispatches, so fanout never
|
|
285
|
+
// materializes a subscription with no event types.
|
|
286
|
+
slackEventTypes:
|
|
287
|
+
slackEventTypes.length === 0 ? undefined : slackEventTypes,
|
|
256
288
|
...(channelPosts === undefined
|
|
257
289
|
? {}
|
|
258
290
|
: { slackChannelPosts: [...channelPosts.allow] }),
|
|
@@ -551,6 +583,36 @@ export function slackChannel(
|
|
|
551
583
|
});
|
|
552
584
|
|
|
553
585
|
slackChannelOptionsByDefinition.set(definition, options);
|
|
586
|
+
attachHostedAdmissionAdapter(definition, {
|
|
587
|
+
kind: "slack",
|
|
588
|
+
prepareArgs: withPropagatingBackgroundErrors,
|
|
589
|
+
// The payload is the full `event_callback` body the CP verified — the
|
|
590
|
+
// same shape Socket Mode unwraps — so it routes through the same
|
|
591
|
+
// inbound dispatch. Outcomes: a captured `send` overrides the fallback
|
|
592
|
+
// tag below, so `skipped` surfaces when the engagement rules declined
|
|
593
|
+
// (`not_engaged`) or no handler takes the shape (`not_dispatchable`);
|
|
594
|
+
// a throwing handler rejects `waitUntil` (propagateHandlerErrors) and
|
|
595
|
+
// hosted admission answers a retryable 503, like the PR adapters.
|
|
596
|
+
// The channel-level event_id dedupe is deliberately bypassed with a
|
|
597
|
+
// fresh instance per delivery: the control plane's app-scoped ingress
|
|
598
|
+
// claim already dedupes Slack retries, and on a warm pod the local set
|
|
599
|
+
// would otherwise swallow the control plane's own retry of a delivery
|
|
600
|
+
// that failed after the id was marked handled.
|
|
601
|
+
dispatch: async ({ payload, args }) => {
|
|
602
|
+
const dispatched = dispatchInboundFromEventBody(
|
|
603
|
+
payload,
|
|
604
|
+
inboundDeps({
|
|
605
|
+
send: args.send,
|
|
606
|
+
waitUntil: args.waitUntil,
|
|
607
|
+
host: args.host,
|
|
608
|
+
artifacts: args.artifacts,
|
|
609
|
+
eventIds: createEventIdDedupe(),
|
|
610
|
+
propagateHandlerErrors: true,
|
|
611
|
+
})
|
|
612
|
+
);
|
|
613
|
+
return skipped(dispatched ? "not_engaged" : "not_dispatchable");
|
|
614
|
+
},
|
|
615
|
+
});
|
|
554
616
|
|
|
555
617
|
return definition;
|
|
556
618
|
}
|
package/src/channels.ts
CHANGED
|
@@ -64,9 +64,11 @@ export {
|
|
|
64
64
|
} from "./channels/checks.js";
|
|
65
65
|
|
|
66
66
|
import { Buffer } from "node:buffer";
|
|
67
|
-
import { timingSafeEqual } from "node:crypto";
|
|
67
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
68
68
|
import { brandDefinition } from "./internal/brand.js";
|
|
69
69
|
import { normalizeIdentity } from "./internal/continuation-identity.js";
|
|
70
|
+
import { attachCatchAdmission } from "./internal/hosted-catch.js";
|
|
71
|
+
import { attachHttpControlPlaneAdmission } from "./internal/http-control-plane-session.js";
|
|
70
72
|
import { isLoopbackAddress, isLoopbackHostname } from "./internal/net.js";
|
|
71
73
|
import type {
|
|
72
74
|
AuthContext,
|
|
@@ -117,7 +119,16 @@ export type {
|
|
|
117
119
|
export function defineChannel<TState = JsonValue>(
|
|
118
120
|
config: ChannelConfig<TState>
|
|
119
121
|
): ChannelDefinition<TState> {
|
|
120
|
-
|
|
122
|
+
const definition = brandDefinition("channel", config);
|
|
123
|
+
if (config.routes !== undefined && config.routes.length > 0) {
|
|
124
|
+
// Hosted: the control plane catches declared routes and replays them
|
|
125
|
+
// here. Provider packs attach their own admission afterwards.
|
|
126
|
+
attachCatchAdmission(
|
|
127
|
+
definition as ChannelDefinition<unknown>,
|
|
128
|
+
config.routes
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
return definition;
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
/**
|
|
@@ -127,13 +138,15 @@ export function defineChannel<TState = JsonValue>(
|
|
|
127
138
|
export function httpChannel(
|
|
128
139
|
config: HttpChannelConfig = {}
|
|
129
140
|
): HttpChannelDefinition {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
const definition =
|
|
142
|
+
config.continuation !== undefined
|
|
143
|
+
? brandDefinition("http-channel", {
|
|
144
|
+
...config,
|
|
145
|
+
continuation: normalizeIdentity(config.continuation, "http"),
|
|
146
|
+
})
|
|
147
|
+
: brandDefinition("http-channel", config);
|
|
148
|
+
attachHttpControlPlaneAdmission(definition);
|
|
149
|
+
return definition;
|
|
137
150
|
}
|
|
138
151
|
|
|
139
152
|
// ============================================================================
|
|
@@ -432,7 +445,13 @@ export function publicEndpoint(): AuthPolicy {
|
|
|
432
445
|
principalId: "anonymous",
|
|
433
446
|
principalType: "user",
|
|
434
447
|
});
|
|
435
|
-
|
|
448
|
+
// On the v2 control plane this also makes the channel's routes catchable
|
|
449
|
+
// with handler-side verification (the v1 alias posture): the CP admits
|
|
450
|
+
// every request on a declared route and the handler rejects bad ones.
|
|
451
|
+
return markCatchAuth(
|
|
452
|
+
Object.assign(policy, { [PUBLIC_ENDPOINT_MARKER]: true as const }),
|
|
453
|
+
{ kind: "public" }
|
|
454
|
+
);
|
|
436
455
|
}
|
|
437
456
|
|
|
438
457
|
/** True when a policy was created by {@link publicEndpoint}. */
|
|
@@ -443,3 +462,131 @@ export function isPublicEndpointPolicy(policy: AuthPolicy): boolean {
|
|
|
443
462
|
] === true
|
|
444
463
|
);
|
|
445
464
|
}
|
|
465
|
+
|
|
466
|
+
const CATCH_AUTH_MARKER = Symbol.for("agent-serve.catch-auth");
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* What `deploy` extracts from a {@link sharedSecretAuth} /
|
|
470
|
+
* {@link hmacSignatureAuth} policy into the manifest: the control plane runs
|
|
471
|
+
* the same check with the deployment secret of the same name before any
|
|
472
|
+
* compute starts. `secret` is a name, never a value.
|
|
473
|
+
*/
|
|
474
|
+
export type CatchAuthDeclaration =
|
|
475
|
+
| { kind: "header"; header: string; secret: string }
|
|
476
|
+
| { kind: "hmac-sha256"; header: string; secret: string; prefix?: string }
|
|
477
|
+
/** `publicEndpoint()`: the handler verifies; the control plane only rate limits. */
|
|
478
|
+
| { kind: "public" };
|
|
479
|
+
|
|
480
|
+
function markCatchAuth(
|
|
481
|
+
policy: AuthPolicy,
|
|
482
|
+
declaration: CatchAuthDeclaration
|
|
483
|
+
): AuthPolicy {
|
|
484
|
+
return Object.assign(policy, { [CATCH_AUTH_MARKER]: declaration });
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/** The catch declaration a policy carries, if it is a catch-capable policy. */
|
|
488
|
+
export function catchAuthDeclaration(
|
|
489
|
+
policy: AuthPolicy
|
|
490
|
+
): CatchAuthDeclaration | undefined {
|
|
491
|
+
const declaration = (policy as { [CATCH_AUTH_MARKER]?: unknown })[
|
|
492
|
+
CATCH_AUTH_MARKER
|
|
493
|
+
];
|
|
494
|
+
return typeof declaration === "object" && declaration !== null
|
|
495
|
+
? (declaration as CatchAuthDeclaration)
|
|
496
|
+
: undefined;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function presentedHeaderSecret(headerName: string, value: string): string {
|
|
500
|
+
if (
|
|
501
|
+
headerName === "authorization" &&
|
|
502
|
+
value.toLowerCase().startsWith("bearer ")
|
|
503
|
+
) {
|
|
504
|
+
return value.slice("bearer ".length).trim();
|
|
505
|
+
}
|
|
506
|
+
return value.trim();
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Admit requests whose `header` equals the secret named `secret` (an
|
|
511
|
+
* `Authorization: Bearer <secret>` header also matches). Locally the value
|
|
512
|
+
* is `process.env[secret]`; hosted, the deployment secret of that name. On
|
|
513
|
+
* Cursor hosting this ALSO declares the channel's routes reachable through
|
|
514
|
+
* the control-plane catch API, which runs the same comparison before any
|
|
515
|
+
* compute exists. An unset secret admits nothing.
|
|
516
|
+
*/
|
|
517
|
+
export function sharedSecretAuth(options: {
|
|
518
|
+
header: string;
|
|
519
|
+
secret: string;
|
|
520
|
+
}): AuthPolicy {
|
|
521
|
+
const header = options.header.toLowerCase();
|
|
522
|
+
const policy: AuthPolicy = (request) => {
|
|
523
|
+
const expected = process.env[options.secret];
|
|
524
|
+
const presented = request.headers.get(header);
|
|
525
|
+
if (
|
|
526
|
+
expected === undefined ||
|
|
527
|
+
expected.length === 0 ||
|
|
528
|
+
presented === null ||
|
|
529
|
+
!constantTimeEquals(presentedHeaderSecret(header, presented), expected)
|
|
530
|
+
) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
return {
|
|
534
|
+
authenticator: "shared-secret",
|
|
535
|
+
principalId: "webhook",
|
|
536
|
+
principalType: "service",
|
|
537
|
+
};
|
|
538
|
+
};
|
|
539
|
+
return markCatchAuth(policy, {
|
|
540
|
+
kind: "header",
|
|
541
|
+
header,
|
|
542
|
+
secret: options.secret,
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Admit requests whose `header` carries the hex HMAC-SHA256 of the raw body
|
|
548
|
+
* under the secret named `secret` (optionally behind a literal `prefix`
|
|
549
|
+
* such as `sha256=`). Same local / hosted / catch semantics as
|
|
550
|
+
* {@link sharedSecretAuth}.
|
|
551
|
+
*/
|
|
552
|
+
export function hmacSignatureAuth(options: {
|
|
553
|
+
header: string;
|
|
554
|
+
secret: string;
|
|
555
|
+
prefix?: string;
|
|
556
|
+
}): AuthPolicy {
|
|
557
|
+
const header = options.header.toLowerCase();
|
|
558
|
+
const prefix = options.prefix ?? "";
|
|
559
|
+
const policy: AuthPolicy = async (request) => {
|
|
560
|
+
const secret = process.env[options.secret];
|
|
561
|
+
const presented = request.headers.get(header)?.trim();
|
|
562
|
+
if (
|
|
563
|
+
secret === undefined ||
|
|
564
|
+
secret.length === 0 ||
|
|
565
|
+
presented === undefined ||
|
|
566
|
+
!presented.startsWith(prefix)
|
|
567
|
+
) {
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
const body = Buffer.from(await request.clone().arrayBuffer());
|
|
571
|
+
const expected = createHmac("sha256", secret).update(body).digest("hex");
|
|
572
|
+
if (
|
|
573
|
+
!constantTimeEquals(
|
|
574
|
+
presented.slice(prefix.length).toLowerCase(),
|
|
575
|
+
expected
|
|
576
|
+
)
|
|
577
|
+
) {
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
authenticator: "hmac-signature",
|
|
582
|
+
principalId: "webhook",
|
|
583
|
+
principalType: "service",
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
return markCatchAuth(policy, {
|
|
587
|
+
kind: "hmac-sha256",
|
|
588
|
+
header,
|
|
589
|
+
secret: options.secret,
|
|
590
|
+
prefix: options.prefix,
|
|
591
|
+
});
|
|
592
|
+
}
|