@cursor/july 0.1.1 → 0.1.3
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 +40 -7
- package/README.md +33 -24
- package/dist/bin/agent-serve.d.ts +3 -1
- package/dist/bin/agent-serve.d.ts.map +1 -1
- package/dist/bin/agent-serve.js +466 -140
- package/dist/channels/github/api.d.ts.map +1 -1
- package/dist/channels/github/api.js +31 -14
- package/dist/channels/github/cursor-account.d.ts +43 -0
- package/dist/channels/github/cursor-account.d.ts.map +1 -0
- package/dist/channels/github/cursor-account.js +95 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +46 -9
- package/dist/channels/github/index.d.ts +2 -2
- package/dist/channels/github/index.js +2 -2
- package/dist/channels/github/types.d.ts +17 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.d.ts +8 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +8 -0
- package/dist/channels/slack/types.d.ts +24 -3
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/types.js +15 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +8 -8
- package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
- package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
- package/dist/docs/assets/{app.DqfFEmJd.js → app.BR0RbIdx.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.2Kg8jIp_.js} +2 -2
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
- package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
- package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
- package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
- package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
- package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
- package/dist/docs/assets/quickstart.md.BU6Iwi_9.js +204 -0
- package/dist/docs/assets/quickstart.md.BU6Iwi_9.lean.js +1 -0
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
- package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
- package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
- package/dist/docs/assets/storage.md.CVnInNiN.lean.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/evals.html +7 -7
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/cloud-runtime.html +5 -5
- package/dist/docs/guides/github.html +14 -7
- package/dist/docs/guides/human-in-the-loop.html +6 -6
- package/dist/docs/guides/slack.html +8 -8
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +5 -5
- package/dist/docs/index.html +7 -7
- package/dist/docs/quickstart.html +195 -26
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +8 -8
- package/dist/docs/reference/cli.html +14 -9
- package/dist/docs/reference/connections.html +5 -5
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/instructions.html +13 -11
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/subagents.html +6 -6
- package/dist/docs/reference/tools.html +7 -7
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +41 -0
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/chat-client.d.ts +29 -3
- package/dist/internal/chat-client.d.ts.map +1 -1
- package/dist/internal/chat-client.js +180 -27
- package/dist/internal/cli-ax.d.ts +75 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +600 -52
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +8 -36
- package/dist/internal/cli-deploy.d.ts +108 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -0
- package/dist/internal/cli-deploy.js +1009 -0
- package/dist/internal/cursor/backend-client.d.ts +10 -1
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +79 -1
- package/dist/internal/cursor/credentials.d.ts +9 -0
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +12 -0
- package/dist/internal/cursor/github-credentials.d.ts +44 -0
- package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
- package/dist/internal/cursor/github-credentials.js +195 -0
- package/dist/internal/deploy-client.d.ts +184 -0
- package/dist/internal/deploy-client.d.ts.map +1 -0
- package/dist/internal/deploy-client.js +395 -0
- package/dist/internal/deploy-source.d.ts +35 -0
- package/dist/internal/deploy-source.d.ts.map +1 -0
- package/dist/internal/deploy-source.js +118 -0
- package/dist/internal/discovery.d.ts +11 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +116 -19
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/eval-run-store.d.ts +22 -3
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +39 -20
- package/dist/internal/eval-runner.d.ts +2 -0
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +2 -0
- package/dist/internal/event-mapper.d.ts +54 -1
- package/dist/internal/event-mapper.d.ts.map +1 -1
- package/dist/internal/event-mapper.js +151 -41
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
- package/dist/internal/handleAgentServeTrigger.js +10 -12
- package/dist/internal/host-platforms.d.ts +7 -2
- package/dist/internal/host-platforms.d.ts.map +1 -1
- package/dist/internal/host-platforms.js +15 -10
- package/dist/internal/hosting.d.ts +37 -0
- package/dist/internal/hosting.d.ts.map +1 -0
- package/dist/internal/hosting.js +67 -0
- package/dist/internal/init-project.d.ts +88 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +221 -31
- package/dist/internal/install-cursor-skills.d.ts +64 -0
- package/dist/internal/install-cursor-skills.d.ts.map +1 -0
- package/dist/internal/install-cursor-skills.js +274 -0
- package/dist/internal/logs-client.d.ts +60 -0
- package/dist/internal/logs-client.d.ts.map +1 -0
- package/dist/internal/logs-client.js +311 -0
- package/dist/internal/open-browser.d.ts +5 -0
- package/dist/internal/open-browser.d.ts.map +1 -0
- package/dist/internal/open-browser.js +34 -0
- package/dist/internal/playground/toolchain.d.ts.map +1 -1
- package/dist/internal/playground/toolchain.js +16 -11
- package/dist/internal/playground-proxy.d.ts +69 -0
- package/dist/internal/playground-proxy.d.ts.map +1 -0
- package/dist/internal/playground-proxy.js +468 -0
- package/dist/internal/prompt-context.d.ts +35 -0
- package/dist/internal/prompt-context.d.ts.map +1 -0
- package/dist/internal/prompt-context.js +71 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +50 -6
- package/dist/internal/reminder-store.d.ts +2 -0
- package/dist/internal/reminder-store.d.ts.map +1 -1
- package/dist/internal/reminder-store.js +18 -0
- package/dist/internal/request-headers.d.ts +11 -0
- package/dist/internal/request-headers.d.ts.map +1 -0
- package/dist/internal/request-headers.js +14 -0
- package/dist/internal/resolve-prod-target.d.ts +42 -0
- package/dist/internal/resolve-prod-target.d.ts.map +1 -0
- package/dist/internal/resolve-prod-target.js +111 -0
- package/dist/internal/run-client.d.ts +2 -2
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +38 -23
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +182 -45
- package/dist/internal/session-engine.d.ts +50 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +267 -23
- package/dist/internal/sessions-client.d.ts +21 -0
- package/dist/internal/sessions-client.d.ts.map +1 -0
- package/dist/internal/sessions-client.js +168 -0
- package/dist/internal/storage-coordinator.d.ts +139 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -0
- package/dist/internal/storage-coordinator.js +499 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +31 -3
- package/dist/internal/terminal-style.d.ts +22 -0
- package/dist/internal/terminal-style.d.ts.map +1 -0
- package/dist/internal/terminal-style.js +49 -0
- package/dist/internal/trajectory.d.ts +10 -5
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +82 -10
- package/dist/internal/workspace.d.ts +11 -0
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +38 -4
- package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
- package/dist/playground/assets/index-D-vo2lV_.css +1 -0
- package/dist/playground/assets/index-x60b9q2j.js +312 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +204 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +153 -0
- package/dist/types.d.ts +70 -4
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +3 -2
- package/docs/guides/github.md +43 -8
- package/docs/guides/slack.md +1 -1
- package/docs/quickstart.md +350 -57
- package/docs/reference/cli.md +51 -3
- package/docs/reference/instructions.md +8 -6
- package/docs/scaffolding-agents.md +1 -1
- package/docs/storage.md +98 -0
- package/package.json +10 -1
- package/skills/ab/SKILL.md +8 -8
- package/skills/create-agent/SKILL.md +28 -22
- package/skills/debug/SKILL.md +11 -11
- package/skills/evals/SKILL.md +16 -16
- package/skills/framework-map/SKILL.md +6 -6
- package/skills/github/SKILL.md +22 -14
- package/skills/hillclimb/SKILL.md +10 -10
- package/skills/setup-slack/SKILL.md +13 -13
- package/src/bin/agent-serve.ts +552 -179
- package/src/channels/github/api.ts +42 -23
- package/src/channels/github/cursor-account.ts +165 -0
- package/src/channels/github/github-channel.ts +66 -6
- package/src/channels/github/index.ts +2 -2
- package/src/channels/github/types.ts +19 -0
- package/src/channels/slack/slack-channel.ts +17 -3
- package/src/channels/slack/types.ts +44 -3
- package/src/index.ts +13 -0
- package/src/internal/chat-client.ts +252 -37
- package/src/internal/cli-ax.ts +722 -72
- package/src/internal/cli-cursor.ts +14 -42
- package/src/internal/cli-deploy.ts +1319 -0
- package/src/internal/cursor/backend-client.ts +103 -1
- package/src/internal/cursor/credentials.ts +14 -0
- package/src/internal/cursor/github-credentials.ts +248 -0
- package/src/internal/deploy-client.ts +632 -0
- package/src/internal/deploy-source.ts +133 -0
- package/src/internal/discovery.ts +141 -17
- package/src/internal/distribution.ts +1 -0
- package/src/internal/eval-run-store.ts +50 -20
- package/src/internal/eval-runner.ts +5 -0
- package/src/internal/event-mapper.ts +222 -42
- package/src/internal/handleAgentServeTrigger.ts +10 -12
- package/src/internal/host-platforms.ts +28 -11
- package/src/internal/hosting.ts +77 -0
- package/src/internal/init-project.ts +333 -51
- package/src/internal/install-cursor-skills.ts +327 -0
- package/src/internal/logs-client.ts +442 -0
- package/src/internal/open-browser.ts +41 -0
- package/src/internal/playground/toolchain.ts +15 -13
- package/src/internal/playground-proxy.ts +576 -0
- package/src/internal/prompt-context.ts +95 -0
- package/src/internal/reminder-runner.ts +50 -6
- package/src/internal/reminder-store.ts +21 -0
- package/src/internal/request-headers.ts +23 -0
- package/src/internal/resolve-prod-target.ts +150 -0
- package/src/internal/run-client.ts +39 -36
- package/src/internal/server.ts +223 -28
- package/src/internal/session-engine.ts +307 -10
- package/src/internal/sessions-client.ts +182 -0
- package/src/internal/storage-coordinator.ts +615 -0
- package/src/internal/stream-progress.ts +36 -2
- package/src/internal/terminal-style.ts +74 -0
- package/src/internal/trajectory.ts +91 -13
- package/src/internal/workspace.ts +42 -4
- package/src/storage.ts +325 -0
- package/src/types.ts +82 -8
- package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
- package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
- package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
- package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
- package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
- package/dist/playground/assets/index-1K-hG-7p.css +0 -1
- package/dist/playground/assets/index-FlWjhg3x.js +0 -79
- /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
|
@@ -17,6 +17,10 @@ import {
|
|
|
17
17
|
resolveGitHubInstallationId,
|
|
18
18
|
resolveGitHubPrivateKey,
|
|
19
19
|
} from "./auth.js";
|
|
20
|
+
import {
|
|
21
|
+
type CursorAccountGithubTokenResolver,
|
|
22
|
+
isCursorAccountGithubTokenResolver,
|
|
23
|
+
} from "./cursor-account.js";
|
|
20
24
|
import type { GitHubChannelCredentials } from "./types.js";
|
|
21
25
|
|
|
22
26
|
export type GitHubJsonObject = Record<string, unknown>;
|
|
@@ -91,19 +95,31 @@ export async function createGitHubOctokit(input: {
|
|
|
91
95
|
credentials?: GitHubChannelCredentials;
|
|
92
96
|
installationId?: number;
|
|
93
97
|
}): Promise<Octokit> {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const
|
|
98
|
+
const transport = githubOctokitTransport(input.api);
|
|
99
|
+
|
|
100
|
+
const dynamicToken: CursorAccountGithubTokenResolver | undefined =
|
|
101
|
+
isCursorAccountGithubTokenResolver(input.credentials?.token)
|
|
102
|
+
? input.credentials.token
|
|
103
|
+
: isCursorAccountGithubTokenResolver(input.credentials?.installationToken)
|
|
104
|
+
? input.credentials.installationToken
|
|
105
|
+
: undefined;
|
|
106
|
+
if (dynamicToken !== undefined) {
|
|
107
|
+
const octokit = new Octokit(transport);
|
|
108
|
+
octokit.hook.before("request", async (request) => {
|
|
109
|
+
const token = await resolveCredentialValue(dynamicToken);
|
|
110
|
+
if (token === undefined) {
|
|
111
|
+
throw new Error("githubChannel: dynamic GitHub token is unavailable.");
|
|
112
|
+
}
|
|
113
|
+
request.headers.authorization = `Bearer ${token}`;
|
|
114
|
+
});
|
|
115
|
+
return octokit;
|
|
116
|
+
}
|
|
97
117
|
|
|
98
118
|
const explicit =
|
|
99
119
|
(await resolveCredentialValue(input.credentials?.token)) ??
|
|
100
120
|
(await resolveCredentialValue(input.credentials?.installationToken));
|
|
101
121
|
if (explicit !== undefined) {
|
|
102
|
-
return new Octokit({
|
|
103
|
-
auth: explicit,
|
|
104
|
-
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
105
|
-
...(requestOptions === undefined ? {} : { request: requestOptions }),
|
|
106
|
-
});
|
|
122
|
+
return new Octokit({ ...transport, auth: explicit });
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
const installationId = await resolveGitHubInstallationId(
|
|
@@ -118,26 +134,34 @@ export async function createGitHubOctokit(input: {
|
|
|
118
134
|
input.credentials?.privateKey
|
|
119
135
|
);
|
|
120
136
|
return new Octokit({
|
|
137
|
+
...transport,
|
|
121
138
|
authStrategy: createAppAuth,
|
|
122
139
|
auth: {
|
|
123
140
|
appId,
|
|
124
141
|
privateKey,
|
|
125
142
|
installationId,
|
|
126
143
|
},
|
|
127
|
-
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
128
|
-
...(requestOptions === undefined ? {} : { request: requestOptions }),
|
|
129
144
|
});
|
|
130
145
|
}
|
|
131
146
|
|
|
132
147
|
// Local testing: ambient PAT / `gh auth token` when App creds are unset.
|
|
133
|
-
const token = await resolveGitHubAccessToken(input);
|
|
134
148
|
return new Octokit({
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
...(requestOptions === undefined ? {} : { request: requestOptions }),
|
|
149
|
+
...transport,
|
|
150
|
+
auth: await resolveGitHubAccessToken(input),
|
|
138
151
|
});
|
|
139
152
|
}
|
|
140
153
|
|
|
154
|
+
/** Shared `baseUrl` / custom `fetch` for every Octokit constructed here. */
|
|
155
|
+
function githubOctokitTransport(api: GitHubApiOptions | undefined): {
|
|
156
|
+
baseUrl?: string;
|
|
157
|
+
request?: { fetch: typeof fetch };
|
|
158
|
+
} {
|
|
159
|
+
return {
|
|
160
|
+
baseUrl: api?.apiBaseUrl,
|
|
161
|
+
request: api?.fetch === undefined ? undefined : { fetch: api.fetch },
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
141
165
|
/**
|
|
142
166
|
* Call a GitHub REST path with channel auth. Prefer typed Octokit methods via
|
|
143
167
|
* {@link createGitHubOctokit} / `ctx.github.getOctokit()` when possible.
|
|
@@ -152,15 +176,10 @@ export async function callGitHubApi<T = unknown>(input: {
|
|
|
152
176
|
options?: { auth?: boolean; headers?: Readonly<Record<string, string>> };
|
|
153
177
|
}): Promise<GitHubApiResponse<T>> {
|
|
154
178
|
if (input.options?.auth === false) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
...(input.api?.fetch === undefined
|
|
160
|
-
? {}
|
|
161
|
-
: { request: { fetch: input.api.fetch } }),
|
|
162
|
-
});
|
|
163
|
-
return requestWithOctokit(octokit, input);
|
|
179
|
+
return requestWithOctokit(
|
|
180
|
+
new Octokit(githubOctokitTransport(input.api)),
|
|
181
|
+
input
|
|
182
|
+
);
|
|
164
183
|
}
|
|
165
184
|
|
|
166
185
|
const octokit = await createGitHubOctokit({
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor-account mode for GitHub channels.
|
|
3
|
+
*
|
|
4
|
+
* The channel declares the intent at definition time. The serve host binds
|
|
5
|
+
* this placeholder to its signed-in Cursor account after it resolves the
|
|
6
|
+
* repository scope into private runtime metadata (never by rewriting the
|
|
7
|
+
* authored `cursorAccount` options object).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { GitHubChannelOptions } from "./types.js";
|
|
11
|
+
|
|
12
|
+
export const CURSOR_GITHUB_MAX_REPOS = 20;
|
|
13
|
+
const CURSOR_GITHUB_REPO_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
14
|
+
const cursorAccountTokenResolvers = new WeakSet<object>();
|
|
15
|
+
|
|
16
|
+
/** Least → most privilege. Host mints one lease at the max requested tier. */
|
|
17
|
+
export const CURSOR_GITHUB_PERMISSIONS = [
|
|
18
|
+
"read",
|
|
19
|
+
"pr-write",
|
|
20
|
+
"contents-write",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export type CursorGithubPermissions =
|
|
24
|
+
(typeof CURSOR_GITHUB_PERMISSIONS)[number];
|
|
25
|
+
|
|
26
|
+
export interface CursorGithubRepoScope {
|
|
27
|
+
owner: string;
|
|
28
|
+
repos: readonly string[];
|
|
29
|
+
permissions: CursorGithubPermissions;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type CursorAccountGithubTokenResolver = () => Promise<string>;
|
|
33
|
+
|
|
34
|
+
export interface PendingCursorGithubCredentials {
|
|
35
|
+
bind(getToken: () => Promise<string>): void;
|
|
36
|
+
getToken(): Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface GithubCursorAccountRuntime {
|
|
40
|
+
/** Authored channel options (not rewritten). */
|
|
41
|
+
options: GitHubChannelOptions;
|
|
42
|
+
credentials: PendingCursorGithubCredentials;
|
|
43
|
+
/**
|
|
44
|
+
* Normalized repo + permissions scope when `cursorAccount` is an object.
|
|
45
|
+
* Absent for `cursorAccount: true` (scope comes from serve `--repo`).
|
|
46
|
+
*/
|
|
47
|
+
scope: CursorGithubRepoScope | undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const runtimeByDefinition = new WeakMap<object, GithubCursorAccountRuntime>();
|
|
51
|
+
|
|
52
|
+
export function parseCursorGithubPermissions(
|
|
53
|
+
value: unknown,
|
|
54
|
+
fallback: CursorGithubPermissions = "pr-write"
|
|
55
|
+
): CursorGithubPermissions {
|
|
56
|
+
if (value === undefined) {
|
|
57
|
+
return fallback;
|
|
58
|
+
}
|
|
59
|
+
if (value === "read" || value === "pr-write" || value === "contents-write") {
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(
|
|
63
|
+
'Cursor account GitHub permissions must be "read", "pr-write", or "contents-write".'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function parseCursorGithubRepoScope(
|
|
68
|
+
values: readonly string[],
|
|
69
|
+
permissions: CursorGithubPermissions = "pr-write"
|
|
70
|
+
): CursorGithubRepoScope {
|
|
71
|
+
const repos = [
|
|
72
|
+
...new Set(values.map((repo) => repo.trim().toLowerCase()).filter(Boolean)),
|
|
73
|
+
];
|
|
74
|
+
if (repos.length === 0) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
"Cursor account GitHub credentials require at least one repository."
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (repos.length > CURSOR_GITHUB_MAX_REPOS) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Cursor account GitHub credentials support at most ${CURSOR_GITHUB_MAX_REPOS} repositories.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
for (const repo of repos) {
|
|
85
|
+
if (!CURSOR_GITHUB_REPO_PATTERN.test(repo) || repo.includes("..")) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Invalid Cursor account GitHub repository "${repo}"; expected owner/repo.`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const owner = repos[0]?.split("/", 1)[0];
|
|
92
|
+
if (owner === undefined) {
|
|
93
|
+
throw new Error("Cursor account GitHub repository owner is missing.");
|
|
94
|
+
}
|
|
95
|
+
if (repos.some((repo) => repo.split("/", 1)[0] !== owner)) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
"Cursor account GitHub repositories must share one owner for a single installation token."
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
owner,
|
|
102
|
+
repos,
|
|
103
|
+
permissions: parseCursorGithubPermissions(permissions),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** One host credential: the most privileged requested tier wins. */
|
|
108
|
+
export function resolveCursorGithubPermissions(
|
|
109
|
+
values: readonly CursorGithubPermissions[]
|
|
110
|
+
): CursorGithubPermissions {
|
|
111
|
+
let max: CursorGithubPermissions = "read";
|
|
112
|
+
for (const value of values) {
|
|
113
|
+
if (
|
|
114
|
+
CURSOR_GITHUB_PERMISSIONS.indexOf(value) >
|
|
115
|
+
CURSOR_GITHUB_PERMISSIONS.indexOf(max)
|
|
116
|
+
) {
|
|
117
|
+
max = value;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return values.length === 0 ? "pr-write" : max;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function createCursorAccountGithubTokenResolver(
|
|
124
|
+
getToken: () => Promise<string>
|
|
125
|
+
): CursorAccountGithubTokenResolver {
|
|
126
|
+
const resolver = () => getToken();
|
|
127
|
+
cursorAccountTokenResolvers.add(resolver);
|
|
128
|
+
return resolver;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function isCursorAccountGithubTokenResolver(
|
|
132
|
+
value: unknown
|
|
133
|
+
): value is CursorAccountGithubTokenResolver {
|
|
134
|
+
return typeof value === "function" && cursorAccountTokenResolvers.has(value);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function createPendingCursorGithubCredentials(): PendingCursorGithubCredentials {
|
|
138
|
+
let getBoundToken: (() => Promise<string>) | undefined;
|
|
139
|
+
return {
|
|
140
|
+
bind(getToken) {
|
|
141
|
+
getBoundToken = getToken;
|
|
142
|
+
},
|
|
143
|
+
getToken() {
|
|
144
|
+
if (getBoundToken === undefined) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
"githubChannel({ cursorAccount: true }) has not been bound to a signed-in Cursor host."
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return getBoundToken();
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function registerGithubCursorAccountRuntime(
|
|
155
|
+
definition: object,
|
|
156
|
+
runtime: GithubCursorAccountRuntime
|
|
157
|
+
): void {
|
|
158
|
+
runtimeByDefinition.set(definition, runtime);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function getGithubCursorAccountRuntime(
|
|
162
|
+
definition: object
|
|
163
|
+
): GithubCursorAccountRuntime | undefined {
|
|
164
|
+
return runtimeByDefinition.get(definition);
|
|
165
|
+
}
|
|
@@ -23,6 +23,13 @@ import {
|
|
|
23
23
|
type GitHubBindingConfig,
|
|
24
24
|
type GitHubBindingState,
|
|
25
25
|
} from "./binding.js";
|
|
26
|
+
import {
|
|
27
|
+
createCursorAccountGithubTokenResolver,
|
|
28
|
+
createPendingCursorGithubCredentials,
|
|
29
|
+
type PendingCursorGithubCredentials,
|
|
30
|
+
parseCursorGithubRepoScope,
|
|
31
|
+
registerGithubCursorAccountRuntime,
|
|
32
|
+
} from "./cursor-account.js";
|
|
26
33
|
import { buildDefaultGitHubEvents } from "./defaults.js";
|
|
27
34
|
import { deriveGitHubWebhookEvents, GITHUB_CHANNEL_KIND } from "./events.js";
|
|
28
35
|
import {
|
|
@@ -581,9 +588,36 @@ export function getGitHubChannelOptions(
|
|
|
581
588
|
export function githubChannel(
|
|
582
589
|
options: GitHubChannelOptions = {}
|
|
583
590
|
): ChannelDefinition<GitHubChannelState> {
|
|
591
|
+
const usesCursorAccount =
|
|
592
|
+
options.cursorAccount === true || typeof options.cursorAccount === "object";
|
|
593
|
+
// Normalized scope lives on the private runtime — never rewrite authored
|
|
594
|
+
// `cursorAccount` on the options object the author passed in.
|
|
595
|
+
const cursorScope =
|
|
596
|
+
typeof options.cursorAccount === "object"
|
|
597
|
+
? parseCursorGithubRepoScope(
|
|
598
|
+
options.cursorAccount.repos,
|
|
599
|
+
options.cursorAccount.permissions
|
|
600
|
+
)
|
|
601
|
+
: undefined;
|
|
602
|
+
|
|
603
|
+
let cursorCredentials: PendingCursorGithubCredentials | undefined;
|
|
604
|
+
let credentials = options.credentials;
|
|
605
|
+
if (usesCursorAccount) {
|
|
606
|
+
if (hasDedicatedGitHubApiCredentials(options)) {
|
|
607
|
+
throw new Error(
|
|
608
|
+
"githubChannel({ cursorAccount: true }) cannot be combined with token or GitHub App credentials."
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
const pending = createPendingCursorGithubCredentials();
|
|
612
|
+
cursorCredentials = pending;
|
|
613
|
+
credentials = {
|
|
614
|
+
...options.credentials,
|
|
615
|
+
token: createCursorAccountGithubTokenResolver(() => pending.getToken()),
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
|
|
584
619
|
const routePath = options.path ?? "/";
|
|
585
|
-
const webhookSecret =
|
|
586
|
-
options.credentials?.webhookSecret ?? envWebhookSecret();
|
|
620
|
+
const webhookSecret = credentials?.webhookSecret ?? envWebhookSecret();
|
|
587
621
|
// With a secret the HMAC is the request auth (allowAll). Without one, prod
|
|
588
622
|
// stays loopback-strict; dev admits unsigned deliveries from a loopback peer
|
|
589
623
|
// only (loopbackGitHubDev) — not the LAN. Admits `gh webhook forward`
|
|
@@ -607,8 +641,12 @@ export function githubChannel(
|
|
|
607
641
|
),
|
|
608
642
|
]);
|
|
609
643
|
|
|
644
|
+
const channelOptions: GitHubChannelOptions = {
|
|
645
|
+
...options,
|
|
646
|
+
credentials,
|
|
647
|
+
};
|
|
610
648
|
const events: ChannelEventHandlers<GitHubChannelState> = {
|
|
611
|
-
...buildDefaultGitHubEvents({ ...
|
|
649
|
+
...buildDefaultGitHubEvents({ ...channelOptions }),
|
|
612
650
|
...options.events,
|
|
613
651
|
};
|
|
614
652
|
|
|
@@ -618,7 +656,7 @@ export function githubChannel(
|
|
|
618
656
|
events,
|
|
619
657
|
meta: {
|
|
620
658
|
kind: GITHUB_CHANNEL_KIND,
|
|
621
|
-
githubWebhookEvents: deriveGitHubWebhookEvents(
|
|
659
|
+
githubWebhookEvents: deriveGitHubWebhookEvents(channelOptions),
|
|
622
660
|
},
|
|
623
661
|
onStart: options.onStart,
|
|
624
662
|
onStop: options.onStop,
|
|
@@ -630,14 +668,36 @@ export function githubChannel(
|
|
|
630
668
|
bodySchema: z.unknown(),
|
|
631
669
|
description: "GitHub webhook ingress",
|
|
632
670
|
handler: async (request, args) =>
|
|
633
|
-
handleGitHubWebhookRequest({
|
|
671
|
+
handleGitHubWebhookRequest({
|
|
672
|
+
options: channelOptions,
|
|
673
|
+
request,
|
|
674
|
+
args,
|
|
675
|
+
}),
|
|
634
676
|
}),
|
|
635
677
|
],
|
|
636
678
|
});
|
|
637
|
-
githubChannelOptionsByDefinition.set(definition,
|
|
679
|
+
githubChannelOptionsByDefinition.set(definition, channelOptions);
|
|
680
|
+
if (cursorCredentials !== undefined) {
|
|
681
|
+
registerGithubCursorAccountRuntime(definition, {
|
|
682
|
+
options,
|
|
683
|
+
credentials: cursorCredentials,
|
|
684
|
+
scope: cursorScope,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
638
687
|
return definition;
|
|
639
688
|
}
|
|
640
689
|
|
|
690
|
+
function hasDedicatedGitHubApiCredentials(
|
|
691
|
+
options: GitHubChannelOptions
|
|
692
|
+
): boolean {
|
|
693
|
+
return (
|
|
694
|
+
options.credentials?.token !== undefined ||
|
|
695
|
+
options.credentials?.installationToken !== undefined ||
|
|
696
|
+
options.credentials?.appId !== undefined ||
|
|
697
|
+
options.credentials?.privateKey !== undefined
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
641
701
|
async function handlePullRequest(input: {
|
|
642
702
|
options: GitHubChannelOptions;
|
|
643
703
|
bindingConfig: GitHubBindingConfig;
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* export default githubChannel({
|
|
8
8
|
* botName: "my-agent",
|
|
9
|
-
* //
|
|
10
|
-
*
|
|
9
|
+
* // Reuses `agentkit login` for events, ctx.github, ctx.host.github, and gh.
|
|
10
|
+
* cursorAccount: { repos: ["owner/repo"] },
|
|
11
11
|
* onComment: (ctx, comment) => ({ auth: defaultGitHubAuth(ctx) }),
|
|
12
12
|
* onPullRequest: (ctx, pr) =>
|
|
13
13
|
* pr.action === "opened" ? { auth: defaultGitHubAuth(ctx) } : null,
|
|
@@ -421,6 +421,25 @@ export interface GitHubChannelOptions {
|
|
|
421
421
|
* API calls prefer App installation tokens, then local PAT / `gh auth`.
|
|
422
422
|
*/
|
|
423
423
|
credentials?: GitHubChannelCredentials;
|
|
424
|
+
/**
|
|
425
|
+
* Use the signed-in Cursor account's GitHub connection for inbound events
|
|
426
|
+
* and outbound API calls. `true` takes repository scope from
|
|
427
|
+
* `serve --cursor-events --repo`; `{ repos }` makes the channel self-contained.
|
|
428
|
+
* `permissions` chooses the minted token tier (`"pr-write"` default).
|
|
429
|
+
* Cannot be combined with explicit token or GitHub App credentials.
|
|
430
|
+
*/
|
|
431
|
+
cursorAccount?:
|
|
432
|
+
| boolean
|
|
433
|
+
| {
|
|
434
|
+
repos: readonly string[];
|
|
435
|
+
/**
|
|
436
|
+
* Token capability tier:
|
|
437
|
+
* - `"read"` — PR/issue/status read
|
|
438
|
+
* - `"pr-write"` (default) — comments / PR+issue write, no `contents:write`
|
|
439
|
+
* - `"contents-write"` — also push code (host-held; prefer only when needed)
|
|
440
|
+
*/
|
|
441
|
+
permissions?: "read" | "pr-write" | "contents-write";
|
|
442
|
+
};
|
|
424
443
|
/** Optional GitHub API transport overrides (`apiBaseUrl`, `fetch`). */
|
|
425
444
|
api?: GitHubApiOptions;
|
|
426
445
|
/**
|
|
@@ -54,13 +54,24 @@ import {
|
|
|
54
54
|
startSlackSocketMode,
|
|
55
55
|
} from "./socket-mode.js";
|
|
56
56
|
import { buildToolApprovalEvents } from "./tool-approval-events.js";
|
|
57
|
-
import
|
|
57
|
+
import {
|
|
58
|
+
assertSlackCursorAgentName,
|
|
59
|
+
type SlackChannelOptions,
|
|
60
|
+
type SlackChannelState,
|
|
61
|
+
type SlackCursorAgentName,
|
|
62
|
+
} from "./types.js";
|
|
58
63
|
|
|
59
64
|
/**
|
|
60
65
|
* Create a Slack channel. Author as `agent/channels/slack.ts` default export.
|
|
66
|
+
*
|
|
67
|
+
* When `cursorAccount` is on, `agentName` must be a single token (no
|
|
68
|
+
* whitespace) — string literals with spaces fail at the type level;
|
|
69
|
+
* runtime values are still checked by {@link assertSlackCursorAgentName}.
|
|
61
70
|
*/
|
|
62
|
-
export function slackChannel(
|
|
63
|
-
options: SlackChannelOptions
|
|
71
|
+
export function slackChannel<const Name extends string = string>(
|
|
72
|
+
options: Omit<SlackChannelOptions, "agentName"> & {
|
|
73
|
+
agentName?: SlackCursorAgentName<Name>;
|
|
74
|
+
} = {}
|
|
64
75
|
): ChannelDefinition<SlackChannelState> {
|
|
65
76
|
const cursorAccount = options.cursorAccount === true;
|
|
66
77
|
if (cursorAccount) {
|
|
@@ -71,6 +82,9 @@ export function slackChannel(
|
|
|
71
82
|
"slackChannel({ cursorAccount: true }) uses the Cursor account's Slack connection — do not also set credentials/envPrefix. Author a second slack channel file for a dedicated Slack app."
|
|
72
83
|
);
|
|
73
84
|
}
|
|
85
|
+
if (options.agentName !== undefined) {
|
|
86
|
+
assertSlackCursorAgentName(options.agentName);
|
|
87
|
+
}
|
|
74
88
|
// Channel watching is Socket Mode only — cursorAccount agents must be
|
|
75
89
|
// explicitly addressed (@mention, DM, or claimed-thread reply).
|
|
76
90
|
if (options.engagement?.channelPosts !== undefined) {
|
|
@@ -210,6 +210,46 @@ export interface SlackEngagementOptions {
|
|
|
210
210
|
channelPosts?: SlackChannelPostsOptions;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Whitespace forbidden in {@link SlackChannelOptions.agentName}. The Cursor
|
|
215
|
+
* Slack router matches on leading words; multi-word names collide with Named
|
|
216
|
+
* Agent shortened-prefix matching (`Approval …` stealing `ApprovalBuddy`).
|
|
217
|
+
*/
|
|
218
|
+
type SlackAgentNameWhitespace = " " | "\t" | "\n" | "\r" | "\f" | "\v";
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Single-token Cursor Slack handle for `cursorAccount` routing
|
|
222
|
+
* (`@Cursor <name> …`). String literals that contain whitespace become
|
|
223
|
+
* `never` (type error at the call site); plain `string` stays `string` and
|
|
224
|
+
* is still rejected at runtime by {@link assertSlackCursorAgentName}.
|
|
225
|
+
*/
|
|
226
|
+
export type SlackCursorAgentName<S extends string = string> = string extends S
|
|
227
|
+
? string
|
|
228
|
+
: S extends `${string}${SlackAgentNameWhitespace}${string}`
|
|
229
|
+
? never
|
|
230
|
+
: S;
|
|
231
|
+
|
|
232
|
+
const SLACK_CURSOR_AGENT_NAME_WHITESPACE = /\s/;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Runtime guard for {@link SlackChannelOptions.agentName}. Call from
|
|
236
|
+
* `slackChannel({ cursorAccount: true })` construction and serve-time
|
|
237
|
+
* name resolution so derived defaults cannot sneak spaces in.
|
|
238
|
+
*/
|
|
239
|
+
export function assertSlackCursorAgentName(name: string): void {
|
|
240
|
+
const trimmed = name.trim();
|
|
241
|
+
if (trimmed.length === 0) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
'slackChannel({ cursorAccount: true }) agentName must be a non-empty single token (no whitespace), e.g. "ApprovalBuddy".'
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
if (SLACK_CURSOR_AGENT_NAME_WHITESPACE.test(trimmed)) {
|
|
247
|
+
throw new Error(
|
|
248
|
+
`slackChannel({ cursorAccount: true }) agentName must be a single token with no whitespace (got ${JSON.stringify(name)}). Use PascalCase like "ApprovalBuddy" — multi-word names break @Cursor routing.`
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
213
253
|
export interface SlackChannelOptions {
|
|
214
254
|
credentials?: SlackCredentials;
|
|
215
255
|
/**
|
|
@@ -242,12 +282,13 @@ export interface SlackChannelOptions {
|
|
|
242
282
|
*/
|
|
243
283
|
cursorAccount?: boolean;
|
|
244
284
|
/**
|
|
245
|
-
*
|
|
285
|
+
* Single-token display name registered with the Cursor backend when
|
|
246
286
|
* {@link cursorAccount} is on: `@Cursor <agentName> …` routes here, and
|
|
247
|
-
* replies post under this username.
|
|
287
|
+
* replies post under this username. **No whitespace** — prefer PascalCase
|
|
288
|
+
* (`ApprovalBuddy`). Defaults to a PascalCase name derived from the
|
|
248
289
|
* agent's mount slug (or project name).
|
|
249
290
|
*/
|
|
250
|
-
agentName?:
|
|
291
|
+
agentName?: SlackCursorAgentName;
|
|
251
292
|
/** Avatar for posts when {@link cursorAccount} is on. */
|
|
252
293
|
agentIcon?: { url?: string; emoji?: string };
|
|
253
294
|
/**
|
package/src/index.ts
CHANGED
|
@@ -104,6 +104,19 @@ export type {
|
|
|
104
104
|
} from "./reminders.js";
|
|
105
105
|
export { defineSchedule } from "./schedules.js";
|
|
106
106
|
export { defineSkill } from "./skills.js";
|
|
107
|
+
export type {
|
|
108
|
+
StorageConfig,
|
|
109
|
+
StorageContext,
|
|
110
|
+
StorageDefinition,
|
|
111
|
+
StorageEntry,
|
|
112
|
+
StoragePolicy,
|
|
113
|
+
StorageRestorePolicy,
|
|
114
|
+
} from "./storage.js";
|
|
115
|
+
export {
|
|
116
|
+
defineStorage,
|
|
117
|
+
STORAGE_KEY_ROOT,
|
|
118
|
+
storageKeys,
|
|
119
|
+
} from "./storage.js";
|
|
107
120
|
export { defineTool } from "./tools.js";
|
|
108
121
|
export type * from "./types.js";
|
|
109
122
|
export {
|