@cursor/july 0.1.73 → 0.1.75

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.
Files changed (159) hide show
  1. package/AGENTS.md +13 -8
  2. package/dist/bin/agent-serve.js +7 -5
  3. package/dist/channels/checks.d.ts +111 -0
  4. package/dist/channels/checks.d.ts.map +1 -0
  5. package/dist/channels/checks.js +86 -0
  6. package/dist/channels/deployments/deployments-channel.d.ts +44 -0
  7. package/dist/channels/deployments/deployments-channel.d.ts.map +1 -0
  8. package/dist/channels/deployments/deployments-channel.js +92 -0
  9. package/dist/channels/deployments/index.d.ts +26 -0
  10. package/dist/channels/deployments/index.d.ts.map +1 -0
  11. package/dist/channels/deployments/index.js +25 -0
  12. package/dist/channels/deployments/types.d.ts +69 -0
  13. package/dist/channels/deployments/types.d.ts.map +1 -0
  14. package/dist/channels/deployments/types.js +6 -0
  15. package/dist/channels/github/checks.d.ts +13 -48
  16. package/dist/channels/github/checks.d.ts.map +1 -1
  17. package/dist/channels/github/checks.js +56 -64
  18. package/dist/channels/origin/api.d.ts +100 -0
  19. package/dist/channels/origin/api.d.ts.map +1 -0
  20. package/dist/channels/origin/api.js +225 -0
  21. package/dist/channels/origin/binding.d.ts +44 -0
  22. package/dist/channels/origin/binding.d.ts.map +1 -0
  23. package/dist/channels/origin/binding.js +45 -0
  24. package/dist/channels/origin/checks.d.ts +107 -0
  25. package/dist/channels/origin/checks.d.ts.map +1 -0
  26. package/dist/channels/origin/checks.js +145 -0
  27. package/dist/channels/origin/index.d.ts +3 -0
  28. package/dist/channels/origin/index.d.ts.map +1 -1
  29. package/dist/channels/origin/index.js +3 -0
  30. package/dist/channels/origin/origin-channel.d.ts +4 -4
  31. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  32. package/dist/channels/origin/origin-channel.js +12 -2
  33. package/dist/channels/origin/types.d.ts +36 -0
  34. package/dist/channels/origin/types.d.ts.map +1 -1
  35. package/dist/channels.d.ts +1 -0
  36. package/dist/channels.d.ts.map +1 -1
  37. package/dist/channels.js +1 -0
  38. package/dist/docs/404.html +2 -2
  39. package/dist/docs/ab.html +3 -3
  40. package/dist/docs/assets/{app.CdbcFD8T.js → app.b8bhB2SV.js} +1 -1
  41. package/dist/docs/assets/chunks/@localSearchIndexroot.DGZeXVqn.js +1 -0
  42. package/dist/docs/assets/chunks/{VPLocalSearchBox.D_NKImM7.js → VPLocalSearchBox.lLSeIyWw.js} +1 -1
  43. package/dist/docs/assets/chunks/{theme.CMvz7cu9.js → theme.C_owesa-.js} +2 -2
  44. package/dist/docs/assets/{reference_channels.md.MN8iDy8V.js → reference_channels.md.G5GysZ7e.js} +2 -2
  45. package/dist/docs/assets/{reference_channels.md.MN8iDy8V.lean.js → reference_channels.md.G5GysZ7e.lean.js} +1 -1
  46. package/dist/docs/assets/{reference_cli.md.Cl14Jfo3.js → reference_cli.md.TAaYU8br.js} +3 -3
  47. package/dist/docs/assets/{reference_cli.md.Cl14Jfo3.lean.js → reference_cli.md.TAaYU8br.lean.js} +1 -1
  48. package/dist/docs/assets/scaffolding-agents.md.CiGsJ1aw.js +1 -0
  49. package/dist/docs/assets/{scaffolding-agents.md.CrWSA0Ko.lean.js → scaffolding-agents.md.CiGsJ1aw.lean.js} +1 -1
  50. package/dist/docs/building-with-agents.html +3 -3
  51. package/dist/docs/concepts.html +3 -3
  52. package/dist/docs/deployment.html +3 -3
  53. package/dist/docs/evals.html +3 -3
  54. package/dist/docs/example-agents/approval-buddy.html +3 -3
  55. package/dist/docs/example-agents/benny.html +3 -3
  56. package/dist/docs/example-agents/bugbot.html +3 -3
  57. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  58. package/dist/docs/example-agents/codeowners-review.html +3 -3
  59. package/dist/docs/example-agents/concierge.html +3 -3
  60. package/dist/docs/example-agents/fsd.html +3 -3
  61. package/dist/docs/example-agents/index.html +3 -3
  62. package/dist/docs/example-agents/knowledge-base.html +3 -3
  63. package/dist/docs/example-agents/oncall.html +3 -3
  64. package/dist/docs/example-agents/security-reviewer.html +3 -3
  65. package/dist/docs/example-agents/slack-agent.html +3 -3
  66. package/dist/docs/example-agents/weather-agent.html +3 -3
  67. package/dist/docs/guides/agent-to-agent.html +3 -3
  68. package/dist/docs/guides/cloud-runtime.html +3 -3
  69. package/dist/docs/guides/convert-automation.html +3 -3
  70. package/dist/docs/guides/github.html +3 -3
  71. package/dist/docs/guides/human-in-the-loop.html +3 -3
  72. package/dist/docs/guides/mcp-oauth.html +3 -3
  73. package/dist/docs/guides/opentelemetry.html +3 -3
  74. package/dist/docs/guides/slack.html +3 -3
  75. package/dist/docs/guides/webhooks.html +3 -3
  76. package/dist/docs/hashmap.json +1 -1
  77. package/dist/docs/hillclimbing.html +3 -3
  78. package/dist/docs/index.html +3 -3
  79. package/dist/docs/quickstart.html +3 -3
  80. package/dist/docs/reference/agent-config.html +3 -3
  81. package/dist/docs/reference/artifacts.html +3 -3
  82. package/dist/docs/reference/channels.html +5 -5
  83. package/dist/docs/reference/cli.html +6 -6
  84. package/dist/docs/reference/connections.html +3 -3
  85. package/dist/docs/reference/hooks.html +3 -3
  86. package/dist/docs/reference/http-api.html +3 -3
  87. package/dist/docs/reference/instructions.html +3 -3
  88. package/dist/docs/reference/playground.html +3 -3
  89. package/dist/docs/reference/project-layout.html +3 -3
  90. package/dist/docs/reference/prompt.html +3 -3
  91. package/dist/docs/reference/schedules.html +3 -3
  92. package/dist/docs/reference/sessions.html +3 -3
  93. package/dist/docs/reference/skills.html +3 -3
  94. package/dist/docs/reference/subagents.html +3 -3
  95. package/dist/docs/reference/tools.html +3 -3
  96. package/dist/docs/scaffolding-agents.html +5 -5
  97. package/dist/docs/storage.html +3 -3
  98. package/dist/docs/templates/agentic-owners.html +3 -3
  99. package/dist/docs/templates/demo.html +3 -3
  100. package/dist/docs/templates/pr-autofixer.html +3 -3
  101. package/dist/docs/templates/security-reviewer.html +3 -3
  102. package/dist/docs/templates/triage.html +3 -3
  103. package/dist/docs/troubleshooting.html +3 -3
  104. package/dist/internal/cli-skills.d.ts +4 -2
  105. package/dist/internal/cli-skills.d.ts.map +1 -1
  106. package/dist/internal/cli-skills.js +8 -3
  107. package/dist/internal/cursor-deployment-relay.d.ts +77 -0
  108. package/dist/internal/cursor-deployment-relay.d.ts.map +1 -0
  109. package/dist/internal/cursor-deployment-relay.js +201 -0
  110. package/dist/internal/distribution.d.ts.map +1 -1
  111. package/dist/internal/distribution.js +1 -0
  112. package/dist/internal/install-cursor-skills.d.ts +71 -16
  113. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  114. package/dist/internal/install-cursor-skills.js +160 -48
  115. package/dist/internal/sdk-runner.d.ts.map +1 -1
  116. package/dist/internal/sdk-runner.js +6 -2
  117. package/dist/internal/server.d.ts.map +1 -1
  118. package/dist/internal/server.js +114 -5
  119. package/dist/playground/assets/index-BJy9UJrF.js +85 -0
  120. package/dist/playground/assets/index-BrSd5vff.css +1 -0
  121. package/dist/playground/index.html +2 -2
  122. package/docs/reference/channels.md +15 -0
  123. package/docs/reference/cli.md +16 -8
  124. package/docs/scaffolding-agents.md +14 -6
  125. package/package.json +9 -1
  126. package/scripts/install-cursor-skills.mjs +36 -0
  127. package/skills/ab/SKILL.md +1 -1
  128. package/skills/create-agent/SKILL.md +1 -1
  129. package/skills/debug/SKILL.md +1 -1
  130. package/skills/evals/SKILL.md +1 -1
  131. package/skills/framework-map/SKILL.md +1 -1
  132. package/skills/github/SKILL.md +1 -1
  133. package/skills/hillclimb/SKILL.md +1 -1
  134. package/skills/mcp-auth/SKILL.md +1 -1
  135. package/skills/otel/SKILL.md +1 -1
  136. package/skills/setup-slack/SKILL.md +1 -1
  137. package/src/bin/agent-serve.ts +7 -5
  138. package/src/channels/checks.ts +185 -0
  139. package/src/channels/deployments/deployments-channel.ts +109 -0
  140. package/src/channels/deployments/index.ts +26 -0
  141. package/src/channels/deployments/types.ts +80 -0
  142. package/src/channels/github/checks.ts +90 -115
  143. package/src/channels/origin/api.ts +318 -0
  144. package/src/channels/origin/binding.ts +96 -0
  145. package/src/channels/origin/checks.ts +250 -0
  146. package/src/channels/origin/index.ts +3 -0
  147. package/src/channels/origin/origin-channel.ts +18 -6
  148. package/src/channels/origin/types.ts +37 -0
  149. package/src/channels.ts +16 -0
  150. package/src/internal/cli-skills.ts +10 -2
  151. package/src/internal/cursor-deployment-relay.ts +274 -0
  152. package/src/internal/distribution.ts +1 -0
  153. package/src/internal/install-cursor-skills.ts +204 -49
  154. package/src/internal/sdk-runner.ts +6 -3
  155. package/src/internal/server.ts +149 -0
  156. package/dist/docs/assets/chunks/@localSearchIndexroot.DQad--_z.js +0 -1
  157. package/dist/docs/assets/scaffolding-agents.md.CrWSA0Ko.js +0 -1
  158. package/dist/playground/assets/index-77uhu5Kr.css +0 -1
  159. package/dist/playground/assets/index-D4buox4m.js +0 -85
package/AGENTS.md CHANGED
@@ -22,8 +22,8 @@ Any PR that changes this package's **source** (`src/`, `playground/`,
22
22
  CLI, shipped `skills/` / `templates/` — runtime behavior that goes out
23
23
  in `@cursor/july`) **must bump** `version` in `package.json` in the
24
24
  **same PR**. On 0.x, bump the patch (`0.1.N` → `0.1.N+1`). Do not
25
- publish from the PR; merging the bump is what lets the `july-release`
26
- pipeline cut. Docs-only, tests-only, and edits to this file do not
25
+ publish from the PR; merging the bump to `main` auto-triggers
26
+ `july-release`. Docs-only, tests-only, and edits to this file do not
27
27
  need a bump.
28
28
 
29
29
  ## Skills
@@ -31,7 +31,9 @@ need a bump.
31
31
  Before scaffolding, wiring channels, writing evals, or deploying, **read the
32
32
  matching skill under `skills/<task>/SKILL.md`** (paths
33
33
  below are relative to this package). Those files ship with `@cursor/july`.
34
- Open them directly there are no `.cursor/skills/` stubs for authoring.
34
+ Cloud agents get the same published skills (except `operate`) via
35
+ `GetManagedSkills`, which reads these files. Open them directly — there
36
+ are no `.cursor/skills/` stubs for authoring.
35
37
 
36
38
  | Skill | Read it when |
37
39
  | --- | --- |
@@ -155,11 +157,14 @@ export default defineEvalConfig({
155
157
  - `init` with no directory prints this setup guide (does not scaffold).
156
158
  `init <dir>` scaffolds (skipping existing files), runs `npm install`,
157
159
  offers to install/update package skills into
158
- `~/.cursor/skills/agentkit/` (TTY only; always overwrites with the
159
- package copy), links `agent-sdk` onto the npm global bin (so bare
160
- `agent-sdk` works on PATH), runs `login` and waits when unsigned, then
161
- prints `cd` (when needed) and `agent-sdk dev`. `--json` still installs but never blocks
162
- on login or skill install; it prints
160
+ `~/.cursor/skills/agentsdk/` (TTY only; always overwrites with the
161
+ package copy, with `alwaysApply: true` so Cursor injects them).
162
+ Consumer installs already copy those skills in postinstall; the
163
+ source checkout does not. Links `agent-sdk` onto the
164
+ npm global bin (so bare `agent-sdk` works on PATH), runs `login` and
165
+ waits when unsigned, then prints `cd` (when needed) and `agent-sdk dev`.
166
+ `--json` still installs but never blocks on login or skill install; it
167
+ prints
163
168
  `{ ok, directory, created, skipped, installed, installError, cliOnPath, cliLinkError, next }`.
164
169
  - `chat --json --message "..."` talks to a running server and prints a trajectory.
165
170
 
@@ -181,11 +181,13 @@ Commands:
181
181
  -> MCP). Review the project, then run \`validate\` / \`dev\`.
182
182
  Warnings never fail the command.
183
183
  install-skills
184
- Install (or refresh) the Agent SDK skills for coding agents in
185
- ~/.cursor/skills/agentkit and print where they landed. \`init\`
186
- offers this once, interactively, and skips it when the prompt
187
- goes unanswered; this command never asks. --print previews
188
- without writing.
184
+ Refresh the Agent SDK skills for coding agents in
185
+ ~/.cursor/skills/agentsdk and print where they landed.
186
+ Installed copies set alwaysApply so Cursor injects them
187
+ into context. \`npm install\` / \`npx\` already copies them
188
+ (postinstall); this command overwrites with the package
189
+ version without asking. \`init\` also offers a TTY refresh.
190
+ --print previews without writing.
189
191
  mcp Serve this agent's MCP endpoint over stdio for MCP clients
190
192
  that spawn local servers (e.g. Cursor). Proxies
191
193
  newline-delimited JSON-RPC to <target>/v1/mcp. --prod resolves
@@ -0,0 +1,111 @@
1
+ /**
2
+ * CI checks, shared across SCMs.
3
+ *
4
+ * The check lifecycle lives here once: `openCiCheck` opens a run (defaults
5
+ * `in_progress`, stamps `startedAt`), the returned {@link CiCheck} handle
6
+ * patches it (`update`) and completes it (`conclude`, stamps `completedAt`),
7
+ * and `resumeCiCheck` rebuilds a handle after a restart. Each SCM plugs in
8
+ * with one {@link CiCheckWriter} — a function that persists a single desired
9
+ * check state on its API (GitHub Checks API create/patch, Origin's keyed
10
+ * upsert, …) and owns any transport state such as a server-assigned run id.
11
+ *
12
+ * Agent code should usually stay one level higher, on {@link CiChecksClient}:
13
+ * both `ctx.github` and `ctx.origin` satisfy it, so a check reporter written
14
+ * once works on either forge:
15
+ *
16
+ * ```ts
17
+ * async function reportCheck(checks: CiChecksClient, sha: string) {
18
+ * const check = await checks.createCheck({ name: "My Agent", sha });
19
+ * // …do the work…
20
+ * await check.conclude({
21
+ * conclusion: "success",
22
+ * output: { title: "Done", summary: "All good." },
23
+ * });
24
+ * }
25
+ * ```
26
+ *
27
+ * {@link CiCheckConclusion} is the common subset every SCM accepts; an SCM
28
+ * with extras widens it through the generic parameter (e.g. Origin's
29
+ * `CiCheck<CiCheckConclusion | "stale">`).
30
+ */
31
+ /** Output shown on the check page. */
32
+ export interface CiCheckOutput {
33
+ /** Heading on the check page. */
34
+ title: string;
35
+ /** Markdown body (supports links, e.g. `[View session](…)`). */
36
+ summary: string;
37
+ /** Optional detailed markdown body. */
38
+ text?: string;
39
+ }
40
+ export type CiCheckStatus = "queued" | "in_progress" | "completed";
41
+ /** Final results accepted by every SCM. */
42
+ export type CiCheckConclusion = "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "success" | "timed_out";
43
+ export interface CiCheckUpdateInput<TConclusion extends string = CiCheckConclusion> {
44
+ status?: CiCheckStatus;
45
+ conclusion?: TConclusion;
46
+ detailsUrl?: string;
47
+ output?: CiCheckOutput;
48
+ }
49
+ export interface CiCheckConcludeInput<TConclusion extends string = CiCheckConclusion> {
50
+ /** Final result shown in the merge box. */
51
+ conclusion: TConclusion;
52
+ detailsUrl?: string;
53
+ output?: CiCheckOutput;
54
+ }
55
+ /** SCM-side reference to a check run, when the SCM reports one. */
56
+ export interface CiCheckRef {
57
+ /** Server-assigned run id (GitHub check-run number, Origin `cr_…`). */
58
+ id?: number | string;
59
+ /** Web URL of the check run page. */
60
+ url?: string;
61
+ }
62
+ /** A created check run, whichever SCM it lives on. */
63
+ export interface CiCheck<TConclusion extends string = CiCheckConclusion> {
64
+ /** Patch status / output / details link while the check is running. */
65
+ update(input: CiCheckUpdateInput<TConclusion>): Promise<void>;
66
+ /** Complete the check with a conclusion (stamps `completedAt`). */
67
+ conclude(input: CiCheckConcludeInput<TConclusion>): Promise<void>;
68
+ }
69
+ export interface CiCheckCreateInput {
70
+ /** Check name shown in the PR merge box, e.g. `"Cursor Security Review"`. */
71
+ name: string;
72
+ /** Commit the check attaches to (usually the PR head SHA). */
73
+ sha: string;
74
+ /** Initial status. Defaults to `"in_progress"`. */
75
+ status?: "queued" | "in_progress";
76
+ /** "Details" link on the check, e.g. the agent session run URL. */
77
+ detailsUrl?: string;
78
+ /** Title + markdown summary shown on the check page. */
79
+ output?: CiCheckOutput;
80
+ }
81
+ /**
82
+ * Anything that can open a CI check on its bound repository — `ctx.github`,
83
+ * `ctx.origin`, or the `bindOriginChecks` adapter.
84
+ */
85
+ export interface CiChecksClient<TConclusion extends string = CiCheckConclusion> {
86
+ createCheck(input: CiCheckCreateInput): Promise<CiCheck<TConclusion>>;
87
+ }
88
+ /** One desired check state for a writer to persist. */
89
+ export interface CiCheckWrite<TConclusion extends string = CiCheckConclusion> extends CiCheckUpdateInput<TConclusion> {
90
+ startedAt?: string;
91
+ completedAt?: string;
92
+ }
93
+ /**
94
+ * The per-SCM extension point: persist one {@link CiCheckWrite} on the SCM
95
+ * (create-then-patch, keyed upsert, …). Bound to a repo + check identity at
96
+ * construction; owns transport state (e.g. the created run id) across calls.
97
+ * May return a {@link CiCheckRef} to expose on the handle.
98
+ */
99
+ export type CiCheckWriter<TConclusion extends string = CiCheckConclusion> = (write: CiCheckWrite<TConclusion>) => Promise<CiCheckRef | undefined>;
100
+ /**
101
+ * Open a check run through `writer` and return a handle for later updates.
102
+ * SCM modules wrap this (`createGitHubCheck`, `createOriginCheck`); channels
103
+ * expose it repo-bound as `ctx.github.createCheck` / `ctx.origin.createCheck`.
104
+ */
105
+ export declare function openCiCheck<TConclusion extends string = CiCheckConclusion>(writer: CiCheckWriter<TConclusion>, input?: Pick<CiCheckCreateInput, "status" | "detailsUrl" | "output">): Promise<CiCheck<TConclusion> & CiCheckRef>;
106
+ /**
107
+ * Rebuild a {@link CiCheck} handle around an existing run (e.g. after a
108
+ * process restart). No write happens until the first update.
109
+ */
110
+ export declare function resumeCiCheck<TConclusion extends string = CiCheckConclusion>(writer: CiCheckWriter<TConclusion>, ref?: CiCheckRef): CiCheck<TConclusion> & CiCheckRef;
111
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/channels/checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * CI checks, shared across SCMs.
3
+ *
4
+ * The check lifecycle lives here once: `openCiCheck` opens a run (defaults
5
+ * `in_progress`, stamps `startedAt`), the returned {@link CiCheck} handle
6
+ * patches it (`update`) and completes it (`conclude`, stamps `completedAt`),
7
+ * and `resumeCiCheck` rebuilds a handle after a restart. Each SCM plugs in
8
+ * with one {@link CiCheckWriter} — a function that persists a single desired
9
+ * check state on its API (GitHub Checks API create/patch, Origin's keyed
10
+ * upsert, …) and owns any transport state such as a server-assigned run id.
11
+ *
12
+ * Agent code should usually stay one level higher, on {@link CiChecksClient}:
13
+ * both `ctx.github` and `ctx.origin` satisfy it, so a check reporter written
14
+ * once works on either forge:
15
+ *
16
+ * ```ts
17
+ * async function reportCheck(checks: CiChecksClient, sha: string) {
18
+ * const check = await checks.createCheck({ name: "My Agent", sha });
19
+ * // …do the work…
20
+ * await check.conclude({
21
+ * conclusion: "success",
22
+ * output: { title: "Done", summary: "All good." },
23
+ * });
24
+ * }
25
+ * ```
26
+ *
27
+ * {@link CiCheckConclusion} is the common subset every SCM accepts; an SCM
28
+ * with extras widens it through the generic parameter (e.g. Origin's
29
+ * `CiCheck<CiCheckConclusion | "stale">`).
30
+ */
31
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
32
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
33
+ return new (P || (P = Promise))(function (resolve, reject) {
34
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
35
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
36
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
37
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
38
+ });
39
+ };
40
+ /**
41
+ * Open a check run through `writer` and return a handle for later updates.
42
+ * SCM modules wrap this (`createGitHubCheck`, `createOriginCheck`); channels
43
+ * expose it repo-bound as `ctx.github.createCheck` / `ctx.origin.createCheck`.
44
+ */
45
+ export function openCiCheck(writer, input) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ var _a;
48
+ const ref = yield writer({
49
+ status: (_a = input === null || input === void 0 ? void 0 : input.status) !== null && _a !== void 0 ? _a : "in_progress",
50
+ startedAt: new Date().toISOString(),
51
+ detailsUrl: input === null || input === void 0 ? void 0 : input.detailsUrl,
52
+ output: input === null || input === void 0 ? void 0 : input.output,
53
+ });
54
+ return resumeCiCheck(writer, ref);
55
+ });
56
+ }
57
+ /**
58
+ * Rebuild a {@link CiCheck} handle around an existing run (e.g. after a
59
+ * process restart). No write happens until the first update.
60
+ */
61
+ export function resumeCiCheck(writer, ref) {
62
+ let id = ref === null || ref === void 0 ? void 0 : ref.id;
63
+ let url = ref === null || ref === void 0 ? void 0 : ref.url;
64
+ const write = (write) => __awaiter(this, void 0, void 0, function* () {
65
+ var _a, _b;
66
+ const next = yield writer(write);
67
+ id = (_a = next === null || next === void 0 ? void 0 : next.id) !== null && _a !== void 0 ? _a : id;
68
+ url = (_b = next === null || next === void 0 ? void 0 : next.url) !== null && _b !== void 0 ? _b : url;
69
+ });
70
+ return {
71
+ get id() {
72
+ return id;
73
+ },
74
+ get url() {
75
+ return url;
76
+ },
77
+ update: (update) => write(Object.assign(Object.assign({}, update), { completedAt: update.status === "completed" ? new Date().toISOString() : undefined })),
78
+ conclude: (conclude) => write({
79
+ status: "completed",
80
+ conclusion: conclude.conclusion,
81
+ completedAt: new Date().toISOString(),
82
+ detailsUrl: conclude.detailsUrl,
83
+ output: conclude.output,
84
+ }),
85
+ };
86
+ }
@@ -0,0 +1,44 @@
1
+ import type { ChannelDefinition, ChannelHandlerArgs } from "../../types.js";
2
+ import { type DeploymentEvent, type DeploymentsChannelOptions } from "./types.js";
3
+ /**
4
+ * Recover the {@link DeploymentsChannelOptions} used to build a channel
5
+ * definition, if it was created via {@link deploymentsChannel}.
6
+ */
7
+ export declare function getDeploymentsChannelOptions(definition: object): DeploymentsChannelOptions | undefined;
8
+ /**
9
+ * Core deployment-event dispatch, used by the channel's replay route and by
10
+ * the serve host's relay fan-out. Whether the event matches this channel's
11
+ * subscriptions is the caller's decision.
12
+ */
13
+ export declare function dispatchDeploymentEvent(input: {
14
+ options: DeploymentsChannelOptions;
15
+ event: DeploymentEvent;
16
+ args: ChannelHandlerArgs;
17
+ }): Promise<Response>;
18
+ /**
19
+ * Deployment events channel.
20
+ *
21
+ * ```ts
22
+ * import { deploymentsChannel } from "@cursor/july/channels/deployments";
23
+ *
24
+ * export default deploymentsChannel({
25
+ * repos: ["repos/anysphere/everysphere"], // as your writer records it
26
+ * environments: ["prod"],
27
+ * onEvent: async (event, { send }) => {
28
+ * await send(`${event.repo}@${event.sha} shipped to ${event.environment}`);
29
+ * },
30
+ * });
31
+ * ```
32
+ *
33
+ * Declarative: the channel names what it wants and handles what arrives. The
34
+ * serve host discovers every mounted deployments channel, opens one
35
+ * `/v0/deployment-events` relay for the process, and routes each event to the
36
+ * channels subscribed to it — the same ownership the Slack and SCM relays
37
+ * have. Nothing is pushed to this deployment and no shared secret exists on
38
+ * either side.
39
+ *
40
+ * The route on this channel exists for local replay (`agent-sdk` and tests):
41
+ * POST an event body and it runs the same `onEvent`.
42
+ */
43
+ export declare function deploymentsChannel(options: DeploymentsChannelOptions): ChannelDefinition;
44
+ //# sourceMappingURL=deployments-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployments-channel.d.ts","sourceRoot":"","sources":["../../../src/channels/deployments/deployments-channel.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC/B,MAAM,YAAY,CAAC;AAqBpB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,GACjB,yBAAyB,GAAG,SAAS,CAEvC;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,OAAO,EAAE,yBAAyB,CAAC;IACnC,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,kBAAkB,CAAC;CAC1B,GAAG,OAAO,CAAC,QAAQ,CAAC,CAGpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,iBAAiB,CA0BnB"}
@@ -0,0 +1,92 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { z } from "zod";
11
+ import { defineChannel, localDevStrict, POST } from "../../channels.js";
12
+ import { resolveDeploymentSubscriptions } from "../../internal/cursor-deployment-relay.js";
13
+ import { DEPLOYMENT_EVENT_TYPES, DEPLOYMENTS_CHANNEL_KIND, } from "./types.js";
14
+ const deploymentEventSchema = z.object({
15
+ eventType: z.enum(DEPLOYMENT_EVENT_TYPES),
16
+ eventId: z.string().min(1),
17
+ teamId: z.number(),
18
+ repo: z.string().min(1),
19
+ deploymentId: z.string().min(1),
20
+ environment: z.string().min(1),
21
+ service: z.string().min(1).optional(),
22
+ sha: z.string().min(1),
23
+ status: z.enum(["pending", "in_progress", "success", "failed"]),
24
+ occurredAtMs: z.number(),
25
+ });
26
+ /** Options used to construct a deployments channel — for host-level fan-out. */
27
+ const deploymentsChannelOptionsByDefinition = new WeakMap();
28
+ /**
29
+ * Recover the {@link DeploymentsChannelOptions} used to build a channel
30
+ * definition, if it was created via {@link deploymentsChannel}.
31
+ */
32
+ export function getDeploymentsChannelOptions(definition) {
33
+ return deploymentsChannelOptionsByDefinition.get(definition);
34
+ }
35
+ /**
36
+ * Core deployment-event dispatch, used by the channel's replay route and by
37
+ * the serve host's relay fan-out. Whether the event matches this channel's
38
+ * subscriptions is the caller's decision.
39
+ */
40
+ export function dispatchDeploymentEvent(input) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ yield input.options.onEvent(input.event, input.args);
43
+ return Response.json({ ok: true });
44
+ });
45
+ }
46
+ /**
47
+ * Deployment events channel.
48
+ *
49
+ * ```ts
50
+ * import { deploymentsChannel } from "@cursor/july/channels/deployments";
51
+ *
52
+ * export default deploymentsChannel({
53
+ * repos: ["repos/anysphere/everysphere"], // as your writer records it
54
+ * environments: ["prod"],
55
+ * onEvent: async (event, { send }) => {
56
+ * await send(`${event.repo}@${event.sha} shipped to ${event.environment}`);
57
+ * },
58
+ * });
59
+ * ```
60
+ *
61
+ * Declarative: the channel names what it wants and handles what arrives. The
62
+ * serve host discovers every mounted deployments channel, opens one
63
+ * `/v0/deployment-events` relay for the process, and routes each event to the
64
+ * channels subscribed to it — the same ownership the Slack and SCM relays
65
+ * have. Nothing is pushed to this deployment and no shared secret exists on
66
+ * either side.
67
+ *
68
+ * The route on this channel exists for local replay (`agent-sdk` and tests):
69
+ * POST an event body and it runs the same `onEvent`.
70
+ */
71
+ export function deploymentsChannel(options) {
72
+ var _a, _b;
73
+ // Throws here rather than at startup, so a malformed `repos` entry fails
74
+ // when the channel module is authored instead of when the host mounts it.
75
+ resolveDeploymentSubscriptions(options);
76
+ const routePath = (_a = options.path) !== null && _a !== void 0 ? _a : "/";
77
+ const definition = defineChannel(Object.assign(Object.assign(Object.assign({ auth: (_b = options.auth) !== null && _b !== void 0 ? _b : [localDevStrict()], meta: { kind: DEPLOYMENTS_CHANNEL_KIND } }, (options.onStart === undefined ? {} : { onStart: options.onStart })), (options.onStop === undefined ? {} : { onStop: options.onStop })), { routes: [
78
+ POST(routePath, {
79
+ description: "Replay one deployment event onto this channel",
80
+ bodySchema: deploymentEventSchema,
81
+ handler: (_request, args) => __awaiter(this, void 0, void 0, function* () {
82
+ return dispatchDeploymentEvent({
83
+ options,
84
+ event: args.body,
85
+ args,
86
+ });
87
+ }),
88
+ }),
89
+ ] }));
90
+ deploymentsChannelOptionsByDefinition.set(definition, options);
91
+ return definition;
92
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Deployment events channel pack for agent-serve.
3
+ *
4
+ * ```ts
5
+ * import { deploymentsChannel } from "@cursor/july/channels/deployments";
6
+ *
7
+ * export default deploymentsChannel({
8
+ * repos: ["repos/anysphere/everysphere"], // as your writer records it
9
+ * environments: ["prod"],
10
+ * onEvent: (event, { send }) => send(`${event.sha} shipped`),
11
+ * });
12
+ * ```
13
+ *
14
+ * The serve host owns the transport, as it does for Slack and SCM events: it
15
+ * discovers every mounted deployments channel, opens one `/v0/deployment-events`
16
+ * relay for the process with the host's Cursor credential, and routes each
17
+ * event to the channels subscribed to it. The relay long-polls with a durable
18
+ * client-owned offset, so a restart resumes rather than dropping events.
19
+ *
20
+ * An agent whose sessions live on another channel forwards from `onEvent`
21
+ * into that channel rather than starting sessions here, the way a GitHub
22
+ * relay channel dispatches into an origin channel.
23
+ */
24
+ export * from "./deployments-channel.js";
25
+ export * from "./types.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/deployments/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Deployment events channel pack for agent-serve.
3
+ *
4
+ * ```ts
5
+ * import { deploymentsChannel } from "@cursor/july/channels/deployments";
6
+ *
7
+ * export default deploymentsChannel({
8
+ * repos: ["repos/anysphere/everysphere"], // as your writer records it
9
+ * environments: ["prod"],
10
+ * onEvent: (event, { send }) => send(`${event.sha} shipped`),
11
+ * });
12
+ * ```
13
+ *
14
+ * The serve host owns the transport, as it does for Slack and SCM events: it
15
+ * discovers every mounted deployments channel, opens one `/v0/deployment-events`
16
+ * relay for the process with the host's Cursor credential, and routes each
17
+ * event to the channels subscribed to it. The relay long-polls with a durable
18
+ * client-owned offset, so a restart resumes rather than dropping events.
19
+ *
20
+ * An agent whose sessions live on another channel forwards from `onEvent`
21
+ * into that channel rather than starting sessions here, the way a GitHub
22
+ * relay channel dispatches into an origin channel.
23
+ */
24
+ export * from "./deployments-channel.js";
25
+ export * from "./types.js";
@@ -0,0 +1,69 @@
1
+ import type { ChannelDefinition, ChannelHandlerArgs } from "../../types.js";
2
+ /** {@link ChannelMeta.kind} value used by {@link deploymentsChannel}. */
3
+ export declare const DEPLOYMENTS_CHANNEL_KIND = "deployments";
4
+ export declare const DEPLOYMENT_EVENT_TYPES: readonly ["deployment.created", "deployment.succeeded"];
5
+ export type DeploymentEventType = (typeof DEPLOYMENT_EVENT_TYPES)[number];
6
+ export type DeploymentStatus = "pending" | "in_progress" | "success" | "failed";
7
+ /** One deployment event, as the control plane records it. */
8
+ export interface DeploymentEvent {
9
+ eventType: DeploymentEventType;
10
+ /** Stable id; dedupe on it if you act more than once per event. */
11
+ eventId: string;
12
+ /** Owning Cursor team. */
13
+ teamId: number;
14
+ /** The Deployment's repository string, case-folded. */
15
+ repo: string;
16
+ deploymentId: string;
17
+ /** Environment slug, e.g. `prod`. */
18
+ environment: string;
19
+ /** Absent when the deployment records no service. */
20
+ service?: string;
21
+ sha: string;
22
+ status: DeploymentStatus;
23
+ occurredAtMs: number;
24
+ }
25
+ /** What a repository subscription asks for. */
26
+ export interface DeploymentSubscription {
27
+ /**
28
+ * The repository string as the factory records it on a Deployment. Opaque:
29
+ * whatever your deployment writer puts there, matched case-insensitively.
30
+ */
31
+ repo: string;
32
+ /** Omit or leave empty for every environment. */
33
+ environments?: readonly string[];
34
+ /** Defaults to `deployment.succeeded`. */
35
+ events?: readonly DeploymentEventType[];
36
+ }
37
+ export interface DeploymentsChannelOptions {
38
+ /**
39
+ * Repositories to watch, spelled exactly as your deployment writer records
40
+ * `Deployment.repository`. The field has no format — whatever the writer
41
+ * puts there is the key — and matching is case-insensitive but otherwise
42
+ * literal, so a value that does not match subscribes successfully and then
43
+ * receives nothing. A bare string takes the default environment and event
44
+ * filters.
45
+ *
46
+ * There is no team-wide subscription: every repository is named. At least
47
+ * one is required — an empty list is how a consumer *deregisters*, so it
48
+ * cannot also mean "everything".
49
+ */
50
+ repos: readonly (string | DeploymentSubscription)[];
51
+ /**
52
+ * Applied to every subscription that does not set its own. Omit or leave
53
+ * empty for every environment.
54
+ */
55
+ environments?: readonly string[];
56
+ /**
57
+ * Applied to every subscription that does not set its own. Defaults to
58
+ * `deployment.succeeded`.
59
+ */
60
+ events?: readonly DeploymentEventType[];
61
+ /** Called for each matching event. Failures retry a few times, then skip. */
62
+ onEvent: (event: DeploymentEvent, args: ChannelHandlerArgs) => Promise<unknown> | unknown;
63
+ /** Route path for the local replay POST. Defaults to `/`. */
64
+ path?: string;
65
+ auth?: ChannelDefinition["auth"];
66
+ onStart?: ChannelDefinition["onStart"];
67
+ onStop?: ChannelDefinition["onStop"];
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/channels/deployments/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AAEtD,eAAO,MAAM,sBAAsB,YACjC,oBAAoB,EACpB,sBAAsB,CACd,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhF,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;;;;;;;;OAWG;IACH,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,sBAAsB,CAAC,EAAE,CAAC;IACpD;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,6EAA6E;IAC7E,OAAO,EAAE,CACP,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,kBAAkB,KACrB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAChC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;CACtC"}
@@ -0,0 +1,6 @@
1
+ /** {@link ChannelMeta.kind} value used by {@link deploymentsChannel}. */
2
+ export const DEPLOYMENTS_CHANNEL_KIND = "deployments";
3
+ export const DEPLOYMENT_EVENT_TYPES = [
4
+ "deployment.created",
5
+ "deployment.succeeded",
6
+ ];
@@ -1,70 +1,35 @@
1
1
  /**
2
- * Generic CI checks (GitHub Checks API) for agent authors.
2
+ * GitHub CI checks (Checks API) the GitHub {@link CiCheckWriter} behind the
3
+ * shared check lifecycle in `../checks.js`.
3
4
  *
4
- * `createGitHubCheck` opens a merge-box check run on a commit and returns a
5
- * handle for updating and concluding it, so an agent can report its own CI
6
- * result (name, summary, and a "Details" link e.g. the agent session run).
7
- * Works with any client exposing `getOctokit()` (`ctx.github`,
5
+ * `createGitHubCheck` opens a merge-box check run on a commit and returns the
6
+ * shared `CiCheck` handle; `resumeGitHubCheck` rebuilds one from a stored
7
+ * check-run id. Works with any client exposing `getOctokit()` (`ctx.github`,
8
8
  * `ctx.host.github`), and is also reachable as `ctx.github.createCheck(...)`.
9
9
  *
10
10
  * Posting checks needs `checks:write`. With `cursorAccount`, declare
11
11
  * `githubChannel({ checks: true })` so the hosted lease is minted on the
12
12
  * `contents-write` tier; GitHub App / PAT credentials need the equivalent
13
- * permission.
13
+ * permission. API failures are normalized into `GitHubApiError`.
14
14
  */
15
15
  import type { Octokit } from "@octokit/rest";
16
- import { type GitHubCheckRunConclusion, type GitHubCheckRunStatus } from "./api.js";
16
+ import { type CiCheck, type CiCheckConcludeInput, type CiCheckCreateInput, type CiCheckOutput, type CiCheckRef, type CiCheckUpdateInput } from "../checks.js";
17
17
  /** Any client that can hand out an authenticated Octokit. */
18
18
  export interface GitHubCheckClient {
19
19
  getOctokit(): Promise<Octokit>;
20
20
  }
21
- /** Output shown on the check page (both fields required by GitHub). */
22
- export interface GitHubCheckOutput {
23
- /** Heading on the check page. */
24
- title: string;
25
- /** Markdown body (supports links, e.g. `[View session](…)`). */
26
- summary: string;
27
- }
28
- export interface GitHubCheckCreateInput {
21
+ export type GitHubCheckOutput = CiCheckOutput;
22
+ export type GitHubCheckUpdateInput = CiCheckUpdateInput;
23
+ export type GitHubCheckConcludeInput = CiCheckConcludeInput;
24
+ /** A created check run. All methods throw `GitHubApiError` on API failure. */
25
+ export type GitHubCheck = CiCheck & CiCheckRef;
26
+ export interface GitHubCheckCreateInput extends CiCheckCreateInput {
29
27
  /** Client used for every API call on the returned handle. */
30
28
  github: GitHubCheckClient;
31
29
  /** Repository owner login, e.g. `"acme"`. */
32
30
  owner: string;
33
31
  /** Repository name, e.g. `"widgets"`. */
34
32
  repo: string;
35
- /** Check name shown in the PR merge box, e.g. `"Cursor Security Review"`. */
36
- name: string;
37
- /** Commit the check attaches to (usually the PR head SHA). */
38
- sha: string;
39
- /** Initial status. Defaults to `"in_progress"`. */
40
- status?: "queued" | "in_progress";
41
- /** "Details" link on the check, e.g. the agent session run URL. */
42
- detailsUrl?: string;
43
- /** Title + markdown summary shown on the check page. */
44
- output?: GitHubCheckOutput;
45
- }
46
- export interface GitHubCheckUpdateInput {
47
- status?: GitHubCheckRunStatus;
48
- conclusion?: GitHubCheckRunConclusion;
49
- detailsUrl?: string;
50
- output?: GitHubCheckOutput;
51
- }
52
- export interface GitHubCheckConcludeInput {
53
- /** Final result shown in the merge box. */
54
- conclusion: GitHubCheckRunConclusion;
55
- detailsUrl?: string;
56
- output?: GitHubCheckOutput;
57
- }
58
- /** A created check run. All methods throw `GitHubApiError` on API failure. */
59
- export interface GitHubCheck {
60
- /** Check run id (for reuse across process restarts). */
61
- readonly id: number;
62
- /** GitHub web URL of the check run page, when returned by the API. */
63
- readonly url: string | undefined;
64
- /** Patch status / output / details link while the check is running. */
65
- update(input: GitHubCheckUpdateInput): Promise<void>;
66
- /** Complete the check with a conclusion (sets `completed_at`). */
67
- conclude(input: GitHubCheckConcludeInput): Promise<void>;
68
33
  }
69
34
  /**
70
35
  * Create a CI check run on a commit and return a handle for later updates.
@@ -1 +1 @@
1
- {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/channels/github/checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EAE1B,MAAM,UAAU,CAAC;AAElB,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,MAAM,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IAClC,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,2CAA2C;IAC3C,UAAU,EAAE,wBAAwB,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,WAAW,CAAC,CA8BtB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,WAAW,CAoCd"}
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/channels/github/checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,kBAAkB,EAIxB,MAAM,cAAc,CAAC;AAGtB,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAC9C,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AACxD,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAE5D,8EAA8E;AAC9E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB;IAChE,6DAA6D;IAC7D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;CACd;AAkED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,WAAW,CAKd"}