@cursor/july 0.1.95 → 0.1.97
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 +3 -4
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +14 -3
- package/dist/channels/deployments/types.d.ts +1 -1
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/deployments/types.js +1 -0
- package/dist/channels/origin/api.d.ts +72 -15
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +185 -28
- package/dist/channels/origin/binding.d.ts +13 -2
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/checks.d.ts +6 -6
- package/dist/channels/origin/checks.js +6 -6
- package/dist/channels/origin/cursor-account.d.ts +5 -3
- package/dist/channels/origin/cursor-account.d.ts.map +1 -1
- package/dist/channels/origin/cursor-account.js +5 -3
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +3 -0
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/api.d.ts +9 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +36 -5
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +110 -81
- package/dist/channels/slack/dispatch.d.ts +7 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +47 -23
- package/dist/channels/slack/inbound.d.ts +8 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +32 -0
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/live-delivery.d.ts +26 -29
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +172 -73
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +6 -2
- package/dist/channels/slack/nudge-carrier.d.ts +2 -0
- package/dist/channels/slack/nudge-carrier.d.ts.map +1 -1
- package/dist/channels/slack/nudge-carrier.js +48 -1
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +3 -2
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.BBj0klBO.js → app.B3rWNYE1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CUEXpL78.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DabmQnia.js → theme.B40_SXuv.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{index.md.BoHaMdeZ.lean.js → index.md.CVeRUOeZ.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.js → reference_cli.md.RyZf5OTE.js} +10 -6
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +2 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +7 -3
- package/dist/docs/llms-full.txt +398 -653
- package/dist/docs/llms.txt +3 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +14 -10
- package/dist/docs/reference/cli.md +39 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -1
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.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 +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +9 -2
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +28 -0
- package/dist/docs/templates/code-wiki.md +91 -0
- package/dist/docs/templates/demo.html +5 -5
- 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 +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/files-backends/cursor-hosted.d.ts +26 -4
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +32 -4
- package/dist/internal/advertise-tools.d.ts +2 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +30 -10
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- package/dist/internal/bounded.d.ts +7 -0
- package/dist/internal/bounded.d.ts.map +1 -0
- package/dist/internal/bounded.js +32 -0
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +5 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +57 -18
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/conversation-mirror.d.ts +11 -8
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +116 -55
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +22 -48
- package/dist/internal/cursor/session-token.d.ts +45 -0
- package/dist/internal/cursor/session-token.d.ts.map +1 -0
- package/dist/internal/cursor/session-token.js +99 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +2 -0
- package/dist/internal/deploy-client.d.ts +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +61 -0
- package/dist/internal/framework-file-storage.d.ts.map +1 -0
- package/dist/internal/framework-file-storage.js +210 -0
- package/dist/internal/framework-storage-selection.d.ts +11 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +38 -11
- package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +7 -0
- package/dist/internal/hosted-delivery.d.ts +13 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +64 -19
- package/dist/internal/hosted-execution-diag.d.ts +48 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +150 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +81 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +4 -0
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +1 -3
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/managed-delivery.d.ts +80 -0
- package/dist/internal/managed-delivery.d.ts.map +1 -0
- package/dist/internal/managed-delivery.js +86 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/runtime-dispatch-runner.d.ts +5 -1
- package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
- package/dist/internal/runtime-dispatch-runner.js +7 -0
- package/dist/internal/sdk-runner.d.ts +11 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +39 -8
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +49 -21
- package/dist/internal/session-engine.d.ts +101 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +577 -46
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/steering.d.ts +15 -0
- package/dist/internal/steering.d.ts.map +1 -0
- package/dist/internal/steering.js +18 -0
- package/dist/internal/storage-coordinator.d.ts +7 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +28 -5
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +9 -1
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +13 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/{index-CZA1uEWA.js → index-DrkI6y5O.js} +51 -51
- package/dist/playground/assets/index-DzNGwm7q.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +9 -6
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +16 -3
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/types.d.ts +65 -8
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +7 -3
- package/docs/deployment.md +5 -4
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +39 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +2 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +9 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/templates/code-wiki.md +96 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +2 -2
- package/skills/ab/SKILL.md +13 -97
- package/skills/create-agent/SKILL.md +124 -223
- package/skills/debug/SKILL.md +34 -68
- package/skills/evals/SKILL.md +55 -180
- package/skills/framework-map/SKILL.md +83 -145
- package/skills/github/SKILL.md +53 -111
- package/skills/hillclimb/SKILL.md +40 -163
- package/skills/mcp-auth/SKILL.md +51 -107
- package/skills/otel/SKILL.md +22 -68
- package/skills/setup-slack/SKILL.md +91 -212
- package/src/bin/agent-serve.ts +13 -1
- package/src/channels/deployments/types.ts +1 -0
- package/src/channels/origin/api.ts +264 -33
- package/src/channels/origin/binding.ts +57 -28
- package/src/channels/origin/checks.ts +6 -6
- package/src/channels/origin/cursor-account.ts +5 -3
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +4 -0
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/api.ts +41 -5
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +122 -93
- package/src/channels/slack/dispatch.ts +56 -22
- package/src/channels/slack/inbound.ts +43 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +235 -114
- package/src/channels/slack/manifest.ts +6 -2
- package/src/channels/slack/nudge-carrier.ts +48 -1
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +40 -7
- package/src/internal/advertise-tools.ts +49 -12
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/bounded.ts +28 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +91 -9
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/conversation-mirror.ts +145 -69
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor/backend-client.ts +34 -58
- package/src/internal/cursor/session-token.ts +115 -0
- package/src/internal/cursor-agent-template.ts +2 -0
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +228 -0
- package/src/internal/framework-storage-selection.ts +51 -11
- package/src/internal/hosted-delivery-protocol.ts +7 -0
- package/src/internal/hosted-delivery.ts +107 -24
- package/src/internal/hosted-execution-diag.ts +207 -0
- package/src/internal/http-channel.ts +99 -0
- package/src/internal/init-project.ts +4 -0
- package/src/internal/install-cursor-skills.ts +1 -4
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/managed-delivery.ts +125 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/runtime-dispatch-runner.ts +10 -0
- package/src/internal/sdk-runner.ts +56 -8
- package/src/internal/server.ts +61 -9
- package/src/internal/session-engine.ts +723 -60
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/steering.ts +17 -0
- package/src/internal/storage-coordinator.ts +38 -8
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +18 -0
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +22 -8
- package/src/storage.ts +12 -0
- package/src/types.ts +70 -9
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/templates/code-wiki/README.md +34 -0
- package/templates/code-wiki/agent/agent.ts +8 -0
- package/templates/code-wiki/agent/channels/github.ts +144 -0
- package/templates/code-wiki/agent/instructions.md +39 -0
- package/templates/code-wiki/agent/lib/repos.ts +5 -0
- package/templates/code-wiki/agent/lib/wiki.ts +22 -0
- package/templates/code-wiki/agent/tools/apply_wiki.ts +219 -0
- package/templates/code-wiki/evals/evals.config.ts +5 -0
- package/templates/code-wiki/evals/wiki.eval.ts +132 -0
- package/templates/code-wiki/init.json +25 -0
- package/templates/code-wiki/package.json +18 -0
- package/templates/code-wiki/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.BoHaMdeZ.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/internal/deployment-scm-event-stream.d.ts +0 -116
- package/dist/internal/deployment-scm-event-stream.d.ts.map +0 -1
- package/dist/internal/deployment-scm-event-stream.js +0 -474
- package/dist/playground/assets/index-CF7hUDnQ.css +0 -1
- package/docs/design/agsh.md +0 -406
- package/src/internal/deployment-scm-event-stream.ts +0 -593
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
* Cursor-account channels do not use this path — they reply with a single
|
|
5
5
|
* final `chat.postMessage` and put thinking on `assistant.threads.setStatus`
|
|
6
6
|
* (no message edits).
|
|
7
|
+
*
|
|
8
|
+
* Assistant-pane threads only render stream APIs. Start lazily with the
|
|
9
|
+
* first real markdown/chunks plus recipient ids — empty startStream is
|
|
10
|
+
* rejected or never attaches.
|
|
7
11
|
*/
|
|
8
12
|
|
|
9
13
|
import type { ChannelEventContext } from "../../types.js";
|
|
10
14
|
import { appendChatStream, startChatStream, stopChatStream } from "./api.js";
|
|
11
15
|
import type { SlackLog } from "./log.js";
|
|
12
|
-
import { computeStreamAppend } from "./stream.js";
|
|
16
|
+
import { computeStreamAppend, type StreamTaskChunk } from "./stream.js";
|
|
13
17
|
import type { SlackBotToken, SlackChannelState } from "./types.js";
|
|
14
18
|
|
|
15
19
|
type SlackChannel = ChannelEventContext<SlackChannelState>;
|
|
@@ -19,96 +23,195 @@ export interface LiveDeliveryDeps {
|
|
|
19
23
|
getLog: () => SlackLog;
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
type OpenArgs = {
|
|
27
|
+
channel: SlackChannel;
|
|
28
|
+
channelId: string;
|
|
29
|
+
threadTs: string;
|
|
30
|
+
sessionId: string;
|
|
31
|
+
markdown_text?: string;
|
|
32
|
+
chunks?: StreamTaskChunk[];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type StreamArgs = {
|
|
36
|
+
channel: SlackChannel;
|
|
37
|
+
channelId: string;
|
|
38
|
+
sessionId: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
22
41
|
/**
|
|
23
42
|
* How the default handlers deliver an in-progress reply. Methods write live
|
|
24
43
|
* delivery state (`streamTs`, `streamChannelId`, `lastPostedText`,
|
|
25
44
|
* `streamingUnavailable`) on `channel.state` directly.
|
|
26
45
|
*/
|
|
27
46
|
export interface LiveDeliveryStrategy {
|
|
28
|
-
/** True when tool-call thinking steps can be appended to the live message. */
|
|
29
47
|
readonly inlineToolSteps: boolean;
|
|
30
|
-
/** Open the live message
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}): Promise<void>;
|
|
37
|
-
/** Push the latest cumulative text to the live message (throttled). */
|
|
38
|
-
append(args: {
|
|
39
|
-
channel: SlackChannel;
|
|
40
|
-
channelId: string;
|
|
41
|
-
streamTs: string;
|
|
42
|
-
text: string;
|
|
43
|
-
sessionId: string;
|
|
44
|
-
}): Promise<void>;
|
|
48
|
+
/** Open the live message with the first real markdown or task chunks. */
|
|
49
|
+
open(args: OpenArgs): Promise<boolean>;
|
|
50
|
+
append(args: StreamArgs & { text: string }): Promise<void>;
|
|
51
|
+
appendChunks(
|
|
52
|
+
args: StreamArgs & { chunks: StreamTaskChunk[] }
|
|
53
|
+
): Promise<boolean>;
|
|
45
54
|
/**
|
|
46
55
|
* Flush the final reply text. `delivered` is false only when the caller must
|
|
47
56
|
* post the full reply as a fresh message (finalize failed on partial text).
|
|
48
57
|
*/
|
|
49
|
-
finalize(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
text: string;
|
|
54
|
-
sessionId: string;
|
|
55
|
-
}): Promise<{ delivered: boolean }>;
|
|
56
|
-
/** Close the live message when the turn produced no final text. */
|
|
57
|
-
finalizeEmpty(args: {
|
|
58
|
-
channel: SlackChannel;
|
|
59
|
-
channelId: string;
|
|
60
|
-
streamTs: string;
|
|
61
|
-
}): Promise<void>;
|
|
62
|
-
/** Best-effort remove a live message left open after the turn ended. */
|
|
58
|
+
finalize(
|
|
59
|
+
args: StreamArgs & { text: string }
|
|
60
|
+
): Promise<{ delivered: boolean }>;
|
|
61
|
+
finalizeEmpty(args: { channel: SlackChannel }): Promise<void>;
|
|
63
62
|
cleanupOrphan(args: { channel: SlackChannel }): Promise<void>;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
fail(
|
|
64
|
+
args: StreamArgs & { errorText: string }
|
|
65
|
+
): Promise<{ delivered: boolean }>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function streamRecipients(channel: SlackChannel): {
|
|
69
|
+
recipient_user_id: string | undefined;
|
|
70
|
+
recipient_team_id: string | undefined;
|
|
71
|
+
} {
|
|
72
|
+
const user = channel.state.triggeringUserId;
|
|
73
|
+
const team = channel.state.teamId;
|
|
74
|
+
return {
|
|
75
|
+
recipient_user_id: user === null || user === "" ? undefined : user,
|
|
76
|
+
recipient_team_id: team === null || team === "" ? undefined : team,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function activeStreamTs(channel: SlackChannel): string | null {
|
|
81
|
+
const ts = channel.state.streamTs;
|
|
82
|
+
return ts === null || ts === "" ? null : ts;
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
export function createStreamDeliveryStrategy(
|
|
75
86
|
deps: LiveDeliveryDeps
|
|
76
87
|
): LiveDeliveryStrategy {
|
|
77
88
|
const { botToken, getLog } = deps;
|
|
78
|
-
return {
|
|
79
|
-
inlineToolSteps: true,
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
const open: LiveDeliveryStrategy["open"] = async ({
|
|
91
|
+
channel,
|
|
92
|
+
channelId,
|
|
93
|
+
threadTs,
|
|
94
|
+
sessionId,
|
|
95
|
+
markdown_text,
|
|
96
|
+
chunks,
|
|
97
|
+
}) => {
|
|
98
|
+
if (activeStreamTs(channel) !== null) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
const hasMarkdown = markdown_text !== undefined && markdown_text !== "";
|
|
102
|
+
const hasChunks = chunks !== undefined && chunks.length > 0;
|
|
103
|
+
if (!hasMarkdown && !hasChunks) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const log = getLog();
|
|
107
|
+
const started = await startChatStream({
|
|
108
|
+
botToken,
|
|
109
|
+
channel: channelId,
|
|
110
|
+
thread_ts: threadTs,
|
|
111
|
+
markdown_text: hasMarkdown ? markdown_text : undefined,
|
|
112
|
+
chunks: hasChunks ? chunks : undefined,
|
|
113
|
+
...streamRecipients(channel),
|
|
114
|
+
});
|
|
115
|
+
if (!started.ok) {
|
|
116
|
+
log.warn("chat.startStream unavailable", {
|
|
117
|
+
error: started.error,
|
|
85
118
|
channel: channelId,
|
|
86
119
|
thread_ts: threadTs,
|
|
87
|
-
markdown_text: "",
|
|
88
|
-
});
|
|
89
|
-
if (!started.ok) {
|
|
90
|
-
log.warn("chat.startStream unavailable", {
|
|
91
|
-
error: started.error,
|
|
92
|
-
channel: channelId,
|
|
93
|
-
thread_ts: threadTs,
|
|
94
|
-
session: sessionId,
|
|
95
|
-
});
|
|
96
|
-
if (started.unsupported === true) {
|
|
97
|
-
channel.state.streamingUnavailable = true;
|
|
98
|
-
}
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
channel.state.streamTs = started.ts;
|
|
102
|
-
channel.state.streamChannelId = started.channel;
|
|
103
|
-
channel.state.lastPostedText = "";
|
|
104
|
-
log.info("chat.startStream ok", {
|
|
105
|
-
channel: started.channel,
|
|
106
|
-
stream_ts: started.ts,
|
|
107
120
|
session: sessionId,
|
|
108
121
|
});
|
|
109
|
-
|
|
122
|
+
if (started.unsupported === true) {
|
|
123
|
+
channel.state.streamingUnavailable = true;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
channel.state.streamTs = started.ts;
|
|
128
|
+
channel.state.streamChannelId = started.channel;
|
|
129
|
+
channel.state.lastPostedText = hasMarkdown ? (markdown_text ?? "") : "";
|
|
130
|
+
log.info("chat.startStream ok", {
|
|
131
|
+
channel: started.channel,
|
|
132
|
+
stream_ts: started.ts,
|
|
133
|
+
session: sessionId,
|
|
134
|
+
});
|
|
135
|
+
return true;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const ensureOpen = async (
|
|
139
|
+
args: StreamArgs & {
|
|
140
|
+
markdown_text?: string;
|
|
141
|
+
chunks?: StreamTaskChunk[];
|
|
142
|
+
}
|
|
143
|
+
): Promise<string | null> => {
|
|
144
|
+
const existing = activeStreamTs(args.channel);
|
|
145
|
+
if (existing !== null) {
|
|
146
|
+
return existing;
|
|
147
|
+
}
|
|
148
|
+
const threadTs = args.channel.state.threadTs;
|
|
149
|
+
if (threadTs === null || threadTs === "") {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const opened = await open({
|
|
153
|
+
channel: args.channel,
|
|
154
|
+
channelId: args.channelId,
|
|
155
|
+
threadTs,
|
|
156
|
+
sessionId: args.sessionId,
|
|
157
|
+
markdown_text: args.markdown_text,
|
|
158
|
+
chunks: args.chunks,
|
|
159
|
+
});
|
|
160
|
+
return opened ? activeStreamTs(args.channel) : null;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const stopWithSuffix = async (args: {
|
|
164
|
+
channel: SlackChannel;
|
|
165
|
+
channelId: string;
|
|
166
|
+
ts: string;
|
|
167
|
+
text: string;
|
|
168
|
+
}): Promise<{ ok: boolean; error?: string }> => {
|
|
169
|
+
const appendText = computeStreamAppend(
|
|
170
|
+
args.channel.state.lastPostedText,
|
|
171
|
+
args.text
|
|
172
|
+
);
|
|
173
|
+
const stopped = await stopChatStream({
|
|
174
|
+
botToken,
|
|
175
|
+
channel: args.channelId,
|
|
176
|
+
ts: args.ts,
|
|
177
|
+
markdown_text: appendText === "" ? undefined : appendText,
|
|
178
|
+
});
|
|
179
|
+
args.channel.state.streamTs = null;
|
|
180
|
+
if (stopped.ok) {
|
|
181
|
+
args.channel.state.lastPostedText = args.text;
|
|
182
|
+
args.channel.state.lastBotMessageTs = args.ts;
|
|
183
|
+
return { ok: true };
|
|
184
|
+
}
|
|
185
|
+
if (stopped.unsupported === true) {
|
|
186
|
+
args.channel.state.streamingUnavailable = true;
|
|
187
|
+
}
|
|
188
|
+
return { ok: false, error: stopped.error };
|
|
189
|
+
};
|
|
110
190
|
|
|
111
|
-
|
|
191
|
+
const closeOrphan = async (channel: SlackChannel): Promise<void> => {
|
|
192
|
+
const orphanTs = activeStreamTs(channel);
|
|
193
|
+
const channelId = channel.state.streamChannelId ?? channel.state.channelId;
|
|
194
|
+
if (orphanTs === null || channelId === null || channelId === "") {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
await stopChatStream({ botToken, channel: channelId, ts: orphanTs });
|
|
198
|
+
channel.state.streamTs = null;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
inlineToolSteps: true,
|
|
203
|
+
open,
|
|
204
|
+
|
|
205
|
+
async append({ channel, channelId, text, sessionId }) {
|
|
206
|
+
const ts = await ensureOpen({
|
|
207
|
+
channel,
|
|
208
|
+
channelId,
|
|
209
|
+
sessionId,
|
|
210
|
+
markdown_text: text,
|
|
211
|
+
});
|
|
212
|
+
if (ts === null) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
112
215
|
const appendText = computeStreamAppend(
|
|
113
216
|
channel.state.lastPostedText,
|
|
114
217
|
text
|
|
@@ -119,14 +222,14 @@ export function createStreamDeliveryStrategy(
|
|
|
119
222
|
const result = await appendChatStream({
|
|
120
223
|
botToken,
|
|
121
224
|
channel: channelId,
|
|
122
|
-
ts
|
|
225
|
+
ts,
|
|
123
226
|
markdown_text: appendText,
|
|
124
227
|
});
|
|
125
228
|
if (!result.ok) {
|
|
126
229
|
getLog().warn("appendStream failed", {
|
|
127
230
|
error: result.error,
|
|
128
231
|
channel: channelId,
|
|
129
|
-
stream_ts:
|
|
232
|
+
stream_ts: ts,
|
|
130
233
|
session: sessionId,
|
|
131
234
|
});
|
|
132
235
|
if (result.unsupported === true) {
|
|
@@ -137,26 +240,50 @@ export function createStreamDeliveryStrategy(
|
|
|
137
240
|
channel.state.lastPostedText = text;
|
|
138
241
|
},
|
|
139
242
|
|
|
140
|
-
async
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
243
|
+
async appendChunks({ channel, channelId, chunks, sessionId }) {
|
|
244
|
+
const hadStream = activeStreamTs(channel) !== null;
|
|
245
|
+
const ts = await ensureOpen({
|
|
246
|
+
channel,
|
|
247
|
+
channelId,
|
|
248
|
+
sessionId,
|
|
249
|
+
chunks,
|
|
250
|
+
});
|
|
251
|
+
if (ts === null) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
if (!hadStream) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
const result = await appendChatStream({
|
|
148
258
|
botToken,
|
|
149
259
|
channel: channelId,
|
|
150
|
-
ts
|
|
151
|
-
|
|
260
|
+
ts,
|
|
261
|
+
chunks,
|
|
262
|
+
});
|
|
263
|
+
return result.ok;
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
async finalize({ channel, channelId, text, sessionId }) {
|
|
267
|
+
const log = getLog();
|
|
268
|
+
const ts = await ensureOpen({
|
|
269
|
+
channel,
|
|
270
|
+
channelId,
|
|
271
|
+
sessionId,
|
|
272
|
+
markdown_text: text,
|
|
273
|
+
});
|
|
274
|
+
if (ts === null) {
|
|
275
|
+
return { delivered: false };
|
|
276
|
+
}
|
|
277
|
+
const stopped = await stopWithSuffix({
|
|
278
|
+
channel,
|
|
279
|
+
channelId,
|
|
280
|
+
ts,
|
|
281
|
+
text,
|
|
152
282
|
});
|
|
153
283
|
if (stopped.ok) {
|
|
154
|
-
channel.state.streamTs = null;
|
|
155
|
-
channel.state.lastPostedText = text;
|
|
156
|
-
channel.state.lastBotMessageTs = streamTs;
|
|
157
284
|
log.info("reply delivered via stream", {
|
|
158
285
|
channel: channelId,
|
|
159
|
-
stream_ts:
|
|
286
|
+
stream_ts: ts,
|
|
160
287
|
session: sessionId,
|
|
161
288
|
chars: text.length,
|
|
162
289
|
});
|
|
@@ -165,52 +292,46 @@ export function createStreamDeliveryStrategy(
|
|
|
165
292
|
log.warn("chat.stopStream failed; falling back to postMessage", {
|
|
166
293
|
error: stopped.error,
|
|
167
294
|
channel: channelId,
|
|
168
|
-
stream_ts:
|
|
295
|
+
stream_ts: ts,
|
|
169
296
|
session: sessionId,
|
|
170
297
|
});
|
|
171
|
-
if (stopped.unsupported === true) {
|
|
172
|
-
channel.state.streamingUnavailable = true;
|
|
173
|
-
}
|
|
174
|
-
channel.state.streamTs = null;
|
|
175
|
-
// If we already streamed content, do not post the full reply again.
|
|
176
298
|
const alreadyStreamed =
|
|
177
299
|
typeof channel.state.lastPostedText === "string" &&
|
|
178
300
|
channel.state.lastPostedText.length > 0;
|
|
179
301
|
return { delivered: alreadyStreamed };
|
|
180
302
|
},
|
|
181
303
|
|
|
182
|
-
async finalizeEmpty({
|
|
183
|
-
await
|
|
304
|
+
async finalizeEmpty({ channel }) {
|
|
305
|
+
await closeOrphan(channel);
|
|
184
306
|
},
|
|
185
307
|
|
|
186
308
|
async cleanupOrphan({ channel }) {
|
|
187
|
-
|
|
188
|
-
// turn ended without a final assistant message, close it here so
|
|
189
|
-
// Slack does not leave the live reply in a streaming state.
|
|
190
|
-
const streamTs = channel.state.streamTs;
|
|
191
|
-
const channelId =
|
|
192
|
-
channel.state.streamChannelId ?? channel.state.channelId;
|
|
193
|
-
if (
|
|
194
|
-
streamTs === null ||
|
|
195
|
-
streamTs === "" ||
|
|
196
|
-
channelId === null ||
|
|
197
|
-
channelId === ""
|
|
198
|
-
) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
await stopChatStream({ botToken, channel: channelId, ts: streamTs });
|
|
202
|
-
channel.state.streamTs = null;
|
|
309
|
+
await closeOrphan(channel);
|
|
203
310
|
},
|
|
204
311
|
|
|
205
|
-
async fail({ channel, channelId,
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
312
|
+
async fail({ channel, channelId, errorText, sessionId }) {
|
|
313
|
+
const ts = await ensureOpen({
|
|
314
|
+
channel,
|
|
315
|
+
channelId,
|
|
316
|
+
sessionId,
|
|
210
317
|
markdown_text: errorText,
|
|
211
318
|
});
|
|
212
|
-
|
|
213
|
-
|
|
319
|
+
if (ts === null) {
|
|
320
|
+
return { delivered: false };
|
|
321
|
+
}
|
|
322
|
+
const stopped = await stopWithSuffix({
|
|
323
|
+
channel,
|
|
324
|
+
channelId,
|
|
325
|
+
ts,
|
|
326
|
+
text: errorText,
|
|
327
|
+
});
|
|
328
|
+
if (stopped.ok) {
|
|
329
|
+
return { delivered: true };
|
|
330
|
+
}
|
|
331
|
+
const alreadyStreamed =
|
|
332
|
+
typeof channel.state.lastPostedText === "string" &&
|
|
333
|
+
channel.state.lastPostedText.length > 0;
|
|
334
|
+
return { delivered: alreadyStreamed };
|
|
214
335
|
},
|
|
215
336
|
};
|
|
216
337
|
}
|
|
@@ -81,7 +81,11 @@ const BOT_SCOPES = [
|
|
|
81
81
|
"users:read",
|
|
82
82
|
] as const;
|
|
83
83
|
|
|
84
|
-
const BOT_EVENTS = [
|
|
84
|
+
const BOT_EVENTS = [
|
|
85
|
+
"app_mention",
|
|
86
|
+
"message.im",
|
|
87
|
+
"assistant_thread_started",
|
|
88
|
+
] as const;
|
|
85
89
|
|
|
86
90
|
/** Slack's display_information.description bound. */
|
|
87
91
|
const MAX_DESCRIPTION_LENGTH = 140;
|
|
@@ -218,7 +222,7 @@ export function buildSlackManifestPair(
|
|
|
218
222
|
};
|
|
219
223
|
}
|
|
220
224
|
|
|
221
|
-
/**
|
|
225
|
+
/** Manifest filenames written under `.slack/`. */
|
|
222
226
|
export function slackManifestFileEntries(
|
|
223
227
|
pair: { dev: SlackAppManifest; prod: SlackAppManifest },
|
|
224
228
|
env: "dev" | "prod" | "both" = "both"
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
* the durable Slack nudge store at tool boundaries (MCP / builtin tools).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
|
|
9
9
|
export const SLACK_NUDGE_ROOT_REL = ".agent-serve/slack-nudge-root";
|
|
10
10
|
export const SLACK_NUDGE_CONTINUATION_REL =
|
|
11
11
|
".agent-serve/slack-nudge-continuation";
|
|
12
12
|
export const SLACK_NUDGE_CARRIER_REL = ".agent-serve/slack-nudge-carrier.mjs";
|
|
13
|
+
/** Conversation allowed to claim nudges; subagents share the cwd and would otherwise take the parent's. */
|
|
14
|
+
export const SLACK_NUDGE_OWNER_REL = ".agent-serve/slack-nudge-owner";
|
|
13
15
|
|
|
14
16
|
/** Carrier script body — reads nudge-root + continuation, drains pending. */
|
|
15
17
|
export const SLACK_NUDGE_CARRIER_SCRIPT: string = `#!/usr/bin/env node
|
|
@@ -40,7 +42,46 @@ async function readText(rel) {
|
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
async function readStdin() {
|
|
46
|
+
const chunks = [];
|
|
47
|
+
const read = (async () => {
|
|
48
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
49
|
+
})().catch(() => {});
|
|
50
|
+
await Promise.race([
|
|
51
|
+
read,
|
|
52
|
+
new Promise((resolve) => setTimeout(resolve, 250).unref?.()),
|
|
53
|
+
]);
|
|
54
|
+
process.stdin.destroy();
|
|
55
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** First caller pins ownership; a subagent cannot call a tool before its parent's Task call. */
|
|
59
|
+
async function ownsStore(caller) {
|
|
60
|
+
if (caller === "") return true;
|
|
61
|
+
const ownerPath = join(workspace, ${JSON.stringify(SLACK_NUDGE_OWNER_REL)});
|
|
62
|
+
try {
|
|
63
|
+
// wx is O_CREAT|O_EXCL, so creating the file is the claim: concurrent hooks cannot both win.
|
|
64
|
+
await writeFile(ownerPath, caller + "\\n", { encoding: "utf8", flag: "wx" });
|
|
65
|
+
return true;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error && error.code !== "EEXIST") return false;
|
|
68
|
+
}
|
|
69
|
+
// Claimed already — the only question left is whether we are the claimant.
|
|
70
|
+
const owner = await readText(${JSON.stringify(SLACK_NUDGE_OWNER_REL)});
|
|
71
|
+
return owner === "" || owner === caller;
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
async function main() {
|
|
75
|
+
const raw = await readStdin();
|
|
76
|
+
let caller = "";
|
|
77
|
+
try {
|
|
78
|
+
const parsed = JSON.parse(raw);
|
|
79
|
+
if (parsed && typeof parsed.conversation_id === "string") {
|
|
80
|
+
caller = parsed.conversation_id.trim();
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
// Fail open: an unparseable payload must not strand the follow-up.
|
|
84
|
+
}
|
|
44
85
|
const root = await readText(${JSON.stringify(SLACK_NUDGE_ROOT_REL)});
|
|
45
86
|
const continuation = await readText(
|
|
46
87
|
${JSON.stringify(SLACK_NUDGE_CONTINUATION_REL)}
|
|
@@ -49,6 +90,11 @@ async function main() {
|
|
|
49
90
|
process.stdout.write("{}\\n");
|
|
50
91
|
return;
|
|
51
92
|
}
|
|
93
|
+
// Not ours: leave it pending for the parent or the turn-boundary drain.
|
|
94
|
+
if (!(await ownsStore(caller))) {
|
|
95
|
+
process.stdout.write("{}\\n");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
52
98
|
const pendingDir = join(root, safeKey(continuation), "pending");
|
|
53
99
|
const deliveredDir = join(root, safeKey(continuation), "delivered");
|
|
54
100
|
let names = [];
|
|
@@ -157,6 +203,7 @@ export async function materializeSlackNudgeCarrier(args: {
|
|
|
157
203
|
SLACK_NUDGE_CARRIER_SCRIPT,
|
|
158
204
|
"utf8"
|
|
159
205
|
);
|
|
206
|
+
await rm(join(args.harnessCwd, SLACK_NUDGE_OWNER_REL), { force: true });
|
|
160
207
|
|
|
161
208
|
const hooksPath = join(args.harnessCwd, ".cursor", "hooks.json");
|
|
162
209
|
let existing: HooksConfig = { version: 1, hooks: {} };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Slack setup guide printed by `agent-serve slack setup`.
|
|
3
3
|
*
|
|
4
4
|
* Dedicated Socket Mode app via `slack create` (dashboard wizard).
|
|
5
|
-
* `slack init --manual` is the unmanaged paste
|
|
5
|
+
* `slack init --manual` is the unmanaged Slack CLI / paste path.
|
|
6
6
|
* {@link SLACK_SETUP_PHASES} is that checklist; its ids key
|
|
7
7
|
* `.agent-serve/slack/setup-status.json`.
|
|
8
8
|
*/
|
|
@@ -21,6 +21,7 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
21
21
|
title: "Generate channel + manifests",
|
|
22
22
|
steps: [
|
|
23
23
|
"agent-serve slack init --manual --dir . --name My Agent",
|
|
24
|
+
"Installs the Slack app when Slack CLI is logged in. Otherwise next asks the user to install it.",
|
|
24
25
|
"Manifests default to Socket Mode (no public Request URL).",
|
|
25
26
|
],
|
|
26
27
|
},
|
|
@@ -29,9 +30,11 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
29
30
|
actor: "human",
|
|
30
31
|
title: "Create two Slack apps from manifests",
|
|
31
32
|
steps: [
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"Preferred: Slack CLI at ~/.slack/bin/slack. slack login --no-prompt, then slack app install --environment local --team <T> --force",
|
|
34
|
+
"Prod: SLACK_ENV=deployed slack app install --environment deployed --team <T> --force",
|
|
35
|
+
"Do not slack deploy; Agent SDK serve owns Socket Mode",
|
|
36
|
+
"Fallback: https://api.slack.com/apps -> Create New App from a manifest",
|
|
37
|
+
"Paste .slack/manifest.dev.json, then manifest.prod.json",
|
|
35
38
|
],
|
|
36
39
|
},
|
|
37
40
|
{
|
|
@@ -39,8 +42,9 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
39
42
|
actor: "human",
|
|
40
43
|
title: "Install + mint App-Level Token",
|
|
41
44
|
steps: [
|
|
42
|
-
"
|
|
45
|
+
"Slack CLI install leaves tokens in that process only. Copy xoxb from OAuth & Permissions at https://api.slack.com/apps/<appId>",
|
|
43
46
|
"App-Level Tokens: create token with connections:write; copy xapp-...",
|
|
47
|
+
"If Slack CLI wrote SLACK_* to .env, copy them into .env.local using env.example names",
|
|
44
48
|
],
|
|
45
49
|
},
|
|
46
50
|
{
|
|
@@ -106,7 +110,7 @@ export function formatSlackSetupGuide(): string {
|
|
|
106
110
|
" Finish Slack consent and the bot name there. The CLI writes",
|
|
107
111
|
" tokens into .env.local.",
|
|
108
112
|
"",
|
|
109
|
-
"Manual Slack app: `slack init --manual
|
|
113
|
+
"Manual Slack app: `slack init --manual` (Slack CLI, or paste at api.slack.com).",
|
|
110
114
|
"Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
|
|
111
115
|
"App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
|
|
112
116
|
"",
|
|
@@ -238,6 +238,8 @@ export function slackChannel(
|
|
|
238
238
|
: { interruptContinuation: args.interruptContinuation }),
|
|
239
239
|
...(channelWatch === undefined ? {} : { channelWatch }),
|
|
240
240
|
...(botMentionGate === undefined ? {} : { botMentionGate }),
|
|
241
|
+
suggestedPrompts: options.suggestedPrompts,
|
|
242
|
+
suggestedPromptsTitle: options.suggestedPromptsTitle,
|
|
241
243
|
};
|
|
242
244
|
}
|
|
243
245
|
|
|
@@ -485,6 +487,7 @@ export function slackChannel(
|
|
|
485
487
|
credentials,
|
|
486
488
|
getSession: args.getSession,
|
|
487
489
|
resolveApproval: args.resolveApproval,
|
|
490
|
+
resolveAuth: args.resolveAuth,
|
|
488
491
|
waitUntil: args.waitUntil,
|
|
489
492
|
log: getLog(),
|
|
490
493
|
blockExternals,
|