@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
|
@@ -58,6 +58,11 @@ export interface OriginEventContext {
|
|
|
58
58
|
repository: OriginRepositoryRef;
|
|
59
59
|
pullRequestNumber: number;
|
|
60
60
|
pullRequestUrl: string;
|
|
61
|
+
/**
|
|
62
|
+
* Who opened the pull request, when the payload carries it. Distinct from
|
|
63
|
+
* {@link sender} — on a comment event the sender is the commenter.
|
|
64
|
+
*/
|
|
65
|
+
pullRequestAuthor?: OriginActor;
|
|
61
66
|
/**
|
|
62
67
|
* Raw parsed `event.payload` record (`{}` when absent), for consumers
|
|
63
68
|
* whose normalization needs more than the typed event — the GitHub
|
|
@@ -152,6 +157,12 @@ export interface OriginAppOptions {
|
|
|
152
157
|
token?: string | OriginTokenProvider;
|
|
153
158
|
/** Public Origin REST base, e.g. `https://api.cursor.com`. */
|
|
154
159
|
apiBaseUrl?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Origin ConnectRPC base for operations without a REST binding (comment
|
|
162
|
+
* reactions), e.g. `https://api.origin.cursor.com`. Falls back to
|
|
163
|
+
* `ORIGIN_RPC_BASE_URL`.
|
|
164
|
+
*/
|
|
165
|
+
rpcBaseUrl?: string;
|
|
155
166
|
}
|
|
156
167
|
|
|
157
168
|
export interface OriginChannelOptions {
|
|
@@ -193,6 +193,12 @@ export function truncateTitle(title: string, max?: number): string {
|
|
|
193
193
|
// Assistant / stream helpers
|
|
194
194
|
// ---------------------------------------------------------------------------
|
|
195
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Show or clear the Working chip. Agent UX ignores empty
|
|
198
|
+
* `assistant.threads.setStatus`; `agents.sessions.setStatus` `active` is
|
|
199
|
+
* what actually clears it. The assistant call stays for loading_messages
|
|
200
|
+
* and older workspaces.
|
|
201
|
+
*/
|
|
196
202
|
export async function setThreadStatus(args: {
|
|
197
203
|
botToken: SlackBotToken | undefined;
|
|
198
204
|
channelId: string;
|
|
@@ -204,13 +210,21 @@ export async function setThreadStatus(args: {
|
|
|
204
210
|
return { ok: false, error: "missing_channel_or_thread" };
|
|
205
211
|
}
|
|
206
212
|
const status = truncateTypingStatus(args.status);
|
|
213
|
+
const sessionResult = await callSlackApiSoft({
|
|
214
|
+
botToken: args.botToken,
|
|
215
|
+
operation: "agents.sessions.setStatus",
|
|
216
|
+
body: {
|
|
217
|
+
channel_id: args.channelId,
|
|
218
|
+
thread_ts: args.threadTs,
|
|
219
|
+
status: status.length > 0 ? "processing" : "active",
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
207
223
|
const body: Record<string, unknown> = {
|
|
208
224
|
channel_id: args.channelId,
|
|
209
225
|
thread_ts: args.threadTs,
|
|
210
226
|
status,
|
|
211
227
|
};
|
|
212
|
-
// Empty status clears Slack's assistant chip ("App is working…").
|
|
213
|
-
// Sending loading_messages with it keeps the chip rotating.
|
|
214
228
|
if (status.length > 0) {
|
|
215
229
|
const loadingRaw =
|
|
216
230
|
args.loadingMessages !== undefined && args.loadingMessages.length > 0
|
|
@@ -224,11 +238,19 @@ export async function setThreadStatus(args: {
|
|
|
224
238
|
body.loading_messages = loading_messages;
|
|
225
239
|
}
|
|
226
240
|
}
|
|
227
|
-
|
|
241
|
+
const assistantResult = await callSlackApiSoft({
|
|
228
242
|
botToken: args.botToken,
|
|
229
243
|
operation: "assistant.threads.setStatus",
|
|
230
244
|
body,
|
|
231
245
|
});
|
|
246
|
+
|
|
247
|
+
if (sessionResult.ok) {
|
|
248
|
+
return sessionResult;
|
|
249
|
+
}
|
|
250
|
+
if (sessionResult.unsupported === true || assistantResult.ok) {
|
|
251
|
+
return assistantResult;
|
|
252
|
+
}
|
|
253
|
+
return sessionResult;
|
|
232
254
|
}
|
|
233
255
|
|
|
234
256
|
export async function setThreadTitle(args: {
|
|
@@ -278,16 +300,30 @@ export async function startChatStream(args: {
|
|
|
278
300
|
channel: string;
|
|
279
301
|
thread_ts?: string;
|
|
280
302
|
markdown_text?: string;
|
|
303
|
+
chunks?: StreamTaskChunk[];
|
|
304
|
+
recipient_user_id?: string;
|
|
305
|
+
recipient_team_id?: string;
|
|
281
306
|
}): Promise<SoftSlackResult<{ ts: string; channel: string }>> {
|
|
282
307
|
const body: Record<string, unknown> = {
|
|
283
308
|
channel: args.channel,
|
|
284
309
|
};
|
|
310
|
+
// Empty markdown_text is rejected or opens a stream the assistant pane
|
|
311
|
+
// never attaches. Recipients are required outside DMs.
|
|
285
312
|
if (args.thread_ts !== undefined && args.thread_ts !== "") {
|
|
286
313
|
body.thread_ts = args.thread_ts;
|
|
287
314
|
}
|
|
288
|
-
if (args.markdown_text !== undefined) {
|
|
315
|
+
if (args.markdown_text !== undefined && args.markdown_text !== "") {
|
|
289
316
|
body.markdown_text = args.markdown_text;
|
|
290
317
|
}
|
|
318
|
+
if (args.chunks !== undefined && args.chunks.length > 0) {
|
|
319
|
+
body.chunks = args.chunks;
|
|
320
|
+
}
|
|
321
|
+
if (args.recipient_user_id !== undefined && args.recipient_user_id !== "") {
|
|
322
|
+
body.recipient_user_id = args.recipient_user_id;
|
|
323
|
+
}
|
|
324
|
+
if (args.recipient_team_id !== undefined && args.recipient_team_id !== "") {
|
|
325
|
+
body.recipient_team_id = args.recipient_team_id;
|
|
326
|
+
}
|
|
291
327
|
const result = await callSlackApiSoft({
|
|
292
328
|
botToken: args.botToken,
|
|
293
329
|
operation: "chat.startStream",
|
|
@@ -642,7 +678,7 @@ export function buildSlackBinding(args: {
|
|
|
642
678
|
...(loadingMessages === undefined ? {} : { loadingMessages }),
|
|
643
679
|
});
|
|
644
680
|
if (!result.ok) {
|
|
645
|
-
log.warn("
|
|
681
|
+
log.warn("slack setStatus not-ok", {
|
|
646
682
|
error: result.error,
|
|
647
683
|
channel: args.channelId,
|
|
648
684
|
thread_ts: threadTs,
|
|
@@ -6,6 +6,8 @@ import type { ApprovalDecision } from "../../types.js";
|
|
|
6
6
|
|
|
7
7
|
export const SLACK_APPROVE_ACTION_ID = "agent_serve_approve";
|
|
8
8
|
export const SLACK_DENY_ACTION_ID = "agent_serve_deny";
|
|
9
|
+
export const SLACK_AUTH_CONNECTED_ACTION_ID = "agent_serve_auth_connected";
|
|
10
|
+
export const SLACK_AUTH_CANCEL_ACTION_ID = "agent_serve_auth_cancel";
|
|
9
11
|
|
|
10
12
|
export interface SlackApprovalActionValue {
|
|
11
13
|
sessionId: string;
|
|
@@ -54,6 +56,29 @@ export function decisionFromActionId(
|
|
|
54
56
|
return null;
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
export function decisionFromAuthActionId(
|
|
60
|
+
actionId: string
|
|
61
|
+
): ApprovalDecision | null {
|
|
62
|
+
if (actionId === SLACK_AUTH_CONNECTED_ACTION_ID) {
|
|
63
|
+
return "approve";
|
|
64
|
+
}
|
|
65
|
+
if (actionId === SLACK_AUTH_CANCEL_ACTION_ID) {
|
|
66
|
+
return "deny";
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function authThreadStatus(connection: string): string {
|
|
72
|
+
const prefix = "Waiting for ";
|
|
73
|
+
const suffix = " auth…";
|
|
74
|
+
const budget = 50 - prefix.length - suffix.length;
|
|
75
|
+
const name =
|
|
76
|
+
connection.length <= budget
|
|
77
|
+
? connection
|
|
78
|
+
: `${connection.slice(0, Math.max(0, budget - 1))}…`;
|
|
79
|
+
return `${prefix}${name}${suffix}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
57
82
|
const REDACTED = "[REDACTED]";
|
|
58
83
|
const SENSITIVE_KEY =
|
|
59
84
|
/(?:pass(?:word|wd)?|secret|token|api[_-]?key|authorization|credential|private[_-]?key|access[_-]?key)/i;
|
|
@@ -176,6 +201,86 @@ export function buildApprovalBlocks(args: {
|
|
|
176
201
|
];
|
|
177
202
|
}
|
|
178
203
|
|
|
204
|
+
export function buildAuthBlocks(args: {
|
|
205
|
+
sessionId: string;
|
|
206
|
+
callId: string;
|
|
207
|
+
toolName: string;
|
|
208
|
+
connection: string;
|
|
209
|
+
authUrl: string;
|
|
210
|
+
}): unknown[] {
|
|
211
|
+
const value = encodeApprovalActionValue({
|
|
212
|
+
sessionId: args.sessionId,
|
|
213
|
+
callId: args.callId,
|
|
214
|
+
});
|
|
215
|
+
const label =
|
|
216
|
+
args.connection.length > 20
|
|
217
|
+
? `Authorize ${args.connection.slice(0, 17)}…`
|
|
218
|
+
: `Authorize ${args.connection}`;
|
|
219
|
+
return [
|
|
220
|
+
{
|
|
221
|
+
type: "header",
|
|
222
|
+
text: {
|
|
223
|
+
type: "plain_text",
|
|
224
|
+
text: "MCP authorization needed",
|
|
225
|
+
emoji: true,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
type: "section",
|
|
230
|
+
text: {
|
|
231
|
+
type: "mrkdwn",
|
|
232
|
+
text: `Connect \`${args.connection}\` so \`${args.toolName}\` can continue.`,
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
type: "actions",
|
|
237
|
+
block_id: `auth_${args.callId}`.slice(0, 255),
|
|
238
|
+
elements: [
|
|
239
|
+
{
|
|
240
|
+
type: "button",
|
|
241
|
+
text: { type: "plain_text", text: label, emoji: true },
|
|
242
|
+
url: args.authUrl,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
type: "button",
|
|
246
|
+
action_id: SLACK_AUTH_CONNECTED_ACTION_ID,
|
|
247
|
+
text: { type: "plain_text", text: "Connected", emoji: true },
|
|
248
|
+
style: "primary",
|
|
249
|
+
value,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
type: "button",
|
|
253
|
+
action_id: SLACK_AUTH_CANCEL_ACTION_ID,
|
|
254
|
+
text: { type: "plain_text", text: "Cancel", emoji: true },
|
|
255
|
+
style: "danger",
|
|
256
|
+
value,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
},
|
|
260
|
+
];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function buildResolvedAuthBlocks(args: {
|
|
264
|
+
connection: string;
|
|
265
|
+
decision: ApprovalDecision;
|
|
266
|
+
byUserId?: string;
|
|
267
|
+
}): unknown[] {
|
|
268
|
+
const verb = args.decision === "approve" ? "Connected" : "Cancelled";
|
|
269
|
+
const by =
|
|
270
|
+
args.byUserId === undefined || args.byUserId === ""
|
|
271
|
+
? ""
|
|
272
|
+
: ` by <@${args.byUserId}>`;
|
|
273
|
+
return [
|
|
274
|
+
{
|
|
275
|
+
type: "section",
|
|
276
|
+
text: {
|
|
277
|
+
type: "mrkdwn",
|
|
278
|
+
text: `*${verb}*${by} — \`${args.connection}\``,
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
}
|
|
283
|
+
|
|
179
284
|
export function buildResolvedApprovalBlocks(args: {
|
|
180
285
|
toolName: string;
|
|
181
286
|
decision: ApprovalDecision;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official Slack CLI project files for `slack init --manual`.
|
|
3
|
+
*
|
|
4
|
+
* `.slack/` is the committed Slack CLI project: hook, manifests, hooks.json.
|
|
5
|
+
* Agent SDK serve owns the socket; do not `slack deploy` / `slack run`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
|
|
14
|
+
export const SLACK_CLI_HOME_BIN = ".slack/bin/slack";
|
|
15
|
+
|
|
16
|
+
export const SLACK_CLI_GET_MANIFEST = "node .slack/get-manifest.mjs";
|
|
17
|
+
|
|
18
|
+
export type SlackCliEnvironment = "local" | "deployed";
|
|
19
|
+
|
|
20
|
+
const TEAM_ID_RE = /\(Team ID: ([TE][A-Z0-9]+)\)/g;
|
|
21
|
+
|
|
22
|
+
const GET_MANIFEST_JS = `import { readFileSync } from "node:fs";
|
|
23
|
+
import { dirname, join } from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
|
|
26
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
|
|
28
|
+
function target() {
|
|
29
|
+
const env = process.env.SLACK_ENV ?? process.env.SLACK_APP_ENVIRONMENT;
|
|
30
|
+
if (env === "deployed" || env === "prod") return "manifest.prod.json";
|
|
31
|
+
if (env === "local" || env === "dev") return "manifest.dev.json";
|
|
32
|
+
try {
|
|
33
|
+
const raw = readFileSync(join(here, "cli-environment"), "utf8").trim();
|
|
34
|
+
if (raw === "deployed" || raw === "prod") return "manifest.prod.json";
|
|
35
|
+
} catch {
|
|
36
|
+
// default local
|
|
37
|
+
}
|
|
38
|
+
return "manifest.dev.json";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
process.stdout.write(readFileSync(join(here, target()), "utf8"));
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
function isEnoent(error: unknown): boolean {
|
|
45
|
+
return (
|
|
46
|
+
error instanceof Error &&
|
|
47
|
+
"code" in error &&
|
|
48
|
+
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Official Slack CLI, if present. `SLACK_CLI` overrides. */
|
|
53
|
+
export function detectSlackCli(
|
|
54
|
+
env: NodeJS.ProcessEnv = process.env
|
|
55
|
+
): string | undefined {
|
|
56
|
+
const override = env.SLACK_CLI;
|
|
57
|
+
if (override !== undefined && override !== "") {
|
|
58
|
+
return override;
|
|
59
|
+
}
|
|
60
|
+
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
61
|
+
const homeBin = join(home, SLACK_CLI_HOME_BIN);
|
|
62
|
+
return existsSync(homeBin) ? homeBin : undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Hook + manifests under `.slack/`. Merge hooks.json; keep existing config. */
|
|
66
|
+
export async function writeSlackCliProject(
|
|
67
|
+
rootDir: string,
|
|
68
|
+
manifests: ReadonlyArray<{ name: string; contents: string }>
|
|
69
|
+
): Promise<string[]> {
|
|
70
|
+
const slackDir = join(rootDir, ".slack");
|
|
71
|
+
await mkdir(slackDir, { recursive: true });
|
|
72
|
+
const created: string[] = [];
|
|
73
|
+
|
|
74
|
+
await writeFile(join(slackDir, "get-manifest.mjs"), GET_MANIFEST_JS);
|
|
75
|
+
created.push(".slack/get-manifest.mjs");
|
|
76
|
+
|
|
77
|
+
for (const file of manifests) {
|
|
78
|
+
await writeFile(join(slackDir, file.name), file.contents);
|
|
79
|
+
created.push(`.slack/${file.name}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (await upsertGetManifestHook(slackDir)) {
|
|
83
|
+
created.push(".slack/hooks.json");
|
|
84
|
+
}
|
|
85
|
+
if (
|
|
86
|
+
await writeIfMissing(
|
|
87
|
+
join(slackDir, "config.json"),
|
|
88
|
+
`${JSON.stringify(
|
|
89
|
+
{
|
|
90
|
+
manifest: { source: "local" },
|
|
91
|
+
project_id: randomUUID(),
|
|
92
|
+
},
|
|
93
|
+
null,
|
|
94
|
+
2
|
|
95
|
+
)}\n`
|
|
96
|
+
)
|
|
97
|
+
) {
|
|
98
|
+
created.push(".slack/config.json");
|
|
99
|
+
}
|
|
100
|
+
if (await mergeGitignore(join(slackDir, ".gitignore"))) {
|
|
101
|
+
created.push(".slack/.gitignore");
|
|
102
|
+
}
|
|
103
|
+
return created;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function upsertGetManifestHook(slackDir: string): Promise<boolean> {
|
|
107
|
+
const path = join(slackDir, "hooks.json");
|
|
108
|
+
let existing: { hooks?: Record<string, string> };
|
|
109
|
+
try {
|
|
110
|
+
const parsed: unknown = JSON.parse(await readFile(path, "utf8"));
|
|
111
|
+
if (
|
|
112
|
+
parsed === null ||
|
|
113
|
+
typeof parsed !== "object" ||
|
|
114
|
+
Array.isArray(parsed)
|
|
115
|
+
) {
|
|
116
|
+
throw new Error(".slack/hooks.json is not a JSON object");
|
|
117
|
+
}
|
|
118
|
+
existing = parsed as { hooks?: Record<string, string> };
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (!isEnoent(error)) {
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
await writeFile(
|
|
124
|
+
path,
|
|
125
|
+
`${JSON.stringify({ hooks: { "get-manifest": SLACK_CLI_GET_MANIFEST } }, null, 2)}\n`
|
|
126
|
+
);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
const hooks = existing.hooks ?? {};
|
|
130
|
+
if (hooks["get-manifest"] === SLACK_CLI_GET_MANIFEST) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
hooks["get-manifest"] = SLACK_CLI_GET_MANIFEST;
|
|
134
|
+
existing.hooks = hooks;
|
|
135
|
+
await writeFile(path, `${JSON.stringify(existing, null, 2)}\n`);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function writeIfMissing(
|
|
140
|
+
path: string,
|
|
141
|
+
contents: string
|
|
142
|
+
): Promise<boolean> {
|
|
143
|
+
try {
|
|
144
|
+
await writeFile(path, contents, { flag: "wx" });
|
|
145
|
+
return true;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (
|
|
148
|
+
error instanceof Error &&
|
|
149
|
+
"code" in error &&
|
|
150
|
+
(error as NodeJS.ErrnoException).code === "EEXIST"
|
|
151
|
+
) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function mergeGitignore(path: string): Promise<boolean> {
|
|
159
|
+
const lines = ["apps.dev.json", "cache/", "cli-environment"];
|
|
160
|
+
let existing = "";
|
|
161
|
+
try {
|
|
162
|
+
existing = await readFile(path, "utf8");
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (!isEnoent(error)) {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
await writeFile(path, `${lines.join("\n")}\n`);
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
const have = new Set(
|
|
171
|
+
existing
|
|
172
|
+
.split(/\r?\n/)
|
|
173
|
+
.map((line) => line.trim())
|
|
174
|
+
.filter((line) => line !== "")
|
|
175
|
+
);
|
|
176
|
+
const missing = lines.filter((line) => !have.has(line));
|
|
177
|
+
if (missing.length === 0) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const prefix =
|
|
181
|
+
existing === "" || existing.endsWith("\n") ? existing : `${existing}\n`;
|
|
182
|
+
await writeFile(path, `${prefix}${missing.join("\n")}\n`);
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function parseSlackAuthTeams(text: string): string[] {
|
|
187
|
+
const ids: string[] = [];
|
|
188
|
+
for (const match of text.matchAll(TEAM_ID_RE)) {
|
|
189
|
+
const id = match[1];
|
|
190
|
+
if (id !== undefined && !ids.includes(id)) {
|
|
191
|
+
ids.push(id);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return ids;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export async function readSlackCliAppId(
|
|
198
|
+
dir: string,
|
|
199
|
+
environment: SlackCliEnvironment,
|
|
200
|
+
team?: string
|
|
201
|
+
): Promise<string | undefined> {
|
|
202
|
+
const apps = await loadAppMap(dir, environment);
|
|
203
|
+
if (apps === undefined) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
if (team !== undefined) {
|
|
207
|
+
return appIdOf(apps[team]);
|
|
208
|
+
}
|
|
209
|
+
return firstAppId(apps);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async function loadAppMap(
|
|
213
|
+
dir: string,
|
|
214
|
+
environment: SlackCliEnvironment
|
|
215
|
+
): Promise<Record<string, unknown> | undefined> {
|
|
216
|
+
if (environment === "local") {
|
|
217
|
+
return readJson(join(dir, ".slack/apps.dev.json"));
|
|
218
|
+
}
|
|
219
|
+
const deployed = await readJson(join(dir, ".slack/apps.json"));
|
|
220
|
+
if (deployed === undefined) {
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
const apps = deployed.apps;
|
|
224
|
+
if (apps !== undefined && typeof apps === "object" && apps !== null) {
|
|
225
|
+
return apps as Record<string, unknown>;
|
|
226
|
+
}
|
|
227
|
+
return deployed;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function firstAppId(value: Record<string, unknown>): string | undefined {
|
|
231
|
+
for (const entry of Object.values(value)) {
|
|
232
|
+
const id = appIdOf(entry);
|
|
233
|
+
if (id !== undefined) {
|
|
234
|
+
return id;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function appIdOf(entry: unknown): string | undefined {
|
|
241
|
+
if (entry === undefined || entry === null || typeof entry !== "object") {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
const appId = (entry as { app_id?: unknown }).app_id;
|
|
245
|
+
if (typeof appId === "string" && appId.startsWith("A")) {
|
|
246
|
+
return appId;
|
|
247
|
+
}
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function readJson(
|
|
252
|
+
path: string
|
|
253
|
+
): Promise<Record<string, unknown> | undefined> {
|
|
254
|
+
try {
|
|
255
|
+
const parsed: unknown = JSON.parse(await readFile(path, "utf8"));
|
|
256
|
+
if (
|
|
257
|
+
parsed === null ||
|
|
258
|
+
typeof parsed !== "object" ||
|
|
259
|
+
Array.isArray(parsed)
|
|
260
|
+
) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
return parsed as Record<string, unknown>;
|
|
264
|
+
} catch {
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
}
|