@shipeasy/openapi 1.6.0 → 2.1.0

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 (151) hide show
  1. package/README.md +37 -0
  2. package/dist/chunk-EPLLHLZN.js +1616 -0
  3. package/dist/chunk-EPLLHLZN.js.map +1 -0
  4. package/dist/chunk-SPH5HWCD.js +3326 -0
  5. package/dist/chunk-SPH5HWCD.js.map +1 -0
  6. package/dist/client-pVkoo3Bf.d.ts +11186 -0
  7. package/dist/client.d.ts +1 -0
  8. package/dist/client.js +215 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/custom.d.ts +64 -0
  11. package/dist/custom.js +292 -0
  12. package/dist/custom.js.map +1 -0
  13. package/dist/index.d.ts +29 -41
  14. package/dist/index.js +258 -4375
  15. package/dist/index.js.map +1 -0
  16. package/dist/node-context.d.ts +81 -33
  17. package/dist/node-context.js +98 -44
  18. package/dist/node-context.js.map +1 -0
  19. package/dist/schemas.d.ts +7920 -0
  20. package/dist/schemas.js +1083 -0
  21. package/dist/schemas.js.map +1 -0
  22. package/openapi.json +15297 -3044
  23. package/openapi.yaml +13979 -0
  24. package/package.json +33 -26
  25. package/spec/components/errors.yaml +53 -0
  26. package/spec/components/parameters.yaml +24 -0
  27. package/spec/components/responses.yaml +107 -0
  28. package/spec/components/schemas/alert-rules.yaml +175 -0
  29. package/spec/components/schemas/attributes.yaml +157 -0
  30. package/spec/components/schemas/common.yaml +87 -0
  31. package/spec/components/schemas/configs.yaml +371 -0
  32. package/spec/components/schemas/connectors.yaml +593 -0
  33. package/spec/components/schemas/errors-api.yaml +209 -0
  34. package/spec/components/schemas/events.yaml +321 -0
  35. package/spec/components/schemas/experiments.yaml +865 -0
  36. package/spec/components/schemas/gate-templates.yaml +198 -0
  37. package/spec/components/schemas/gates.yaml +890 -0
  38. package/spec/components/schemas/i18n.yaml +478 -0
  39. package/spec/components/schemas/keys.yaml +186 -0
  40. package/spec/components/schemas/killswitches.yaml +309 -0
  41. package/spec/components/schemas/metrics.yaml +547 -0
  42. package/spec/components/schemas/ops.yaml +1011 -0
  43. package/spec/components/schemas/projects.yaml +222 -0
  44. package/spec/components/schemas/search.yaml +46 -0
  45. package/spec/components/schemas/universes.yaml +127 -0
  46. package/spec/openapi.yaml +348 -0
  47. package/spec/paths/alert-rules.yaml +250 -0
  48. package/spec/paths/attributes.yaml +261 -0
  49. package/spec/paths/configs.yaml +744 -0
  50. package/spec/paths/connectors.yaml +748 -0
  51. package/spec/paths/errors.yaml +382 -0
  52. package/spec/paths/events.yaml +366 -0
  53. package/spec/paths/experiments.yaml +777 -0
  54. package/spec/paths/gate-templates.yaml +263 -0
  55. package/spec/paths/gates.yaml +451 -0
  56. package/spec/paths/i18n.yaml +544 -0
  57. package/spec/paths/keys.yaml +181 -0
  58. package/spec/paths/killswitches.yaml +557 -0
  59. package/spec/paths/metrics.yaml +302 -0
  60. package/spec/paths/ops.yaml +446 -0
  61. package/spec/paths/projects.yaml +210 -0
  62. package/spec/paths/search.yaml +62 -0
  63. package/spec/paths/universes.yaml +247 -0
  64. package/dist/operations/attributes.d.ts +0 -33
  65. package/dist/operations/attributes.js +0 -16
  66. package/dist/operations/cli-adapter.d.ts +0 -35
  67. package/dist/operations/cli-adapter.js +0 -91
  68. package/dist/operations/coerce.d.ts +0 -32
  69. package/dist/operations/coerce.js +0 -53
  70. package/dist/operations/configs.d.ts +0 -28
  71. package/dist/operations/configs.js +0 -119
  72. package/dist/operations/docs.d.ts +0 -37
  73. package/dist/operations/docs.js +0 -39
  74. package/dist/operations/events.d.ts +0 -28
  75. package/dist/operations/events.js +0 -121
  76. package/dist/operations/experiments.d.ts +0 -28
  77. package/dist/operations/experiments.js +0 -280
  78. package/dist/operations/gates.d.ts +0 -28
  79. package/dist/operations/gates.js +0 -132
  80. package/dist/operations/i18n.d.ts +0 -28
  81. package/dist/operations/i18n.js +0 -121
  82. package/dist/operations/index.d.ts +0 -63
  83. package/dist/operations/index.js +0 -1751
  84. package/dist/operations/killswitches.d.ts +0 -28
  85. package/dist/operations/killswitches.js +0 -126
  86. package/dist/operations/mcp-adapter.d.ts +0 -35
  87. package/dist/operations/mcp-adapter.js +0 -94
  88. package/dist/operations/metrics.d.ts +0 -30
  89. package/dist/operations/metrics.js +0 -114
  90. package/dist/operations/ops.d.ts +0 -28
  91. package/dist/operations/ops.js +0 -313
  92. package/dist/operations/projects.d.ts +0 -28
  93. package/dist/operations/projects.js +0 -36
  94. package/dist/operations/sdk-docs.d.ts +0 -28
  95. package/dist/operations/sdk-docs.js +0 -160
  96. package/dist/operations/types.d.ts +0 -138
  97. package/dist/operations/types.js +0 -9
  98. package/dist/operations/universes.d.ts +0 -28
  99. package/dist/operations/universes.js +0 -93
  100. package/dist/operations/util.d.ts +0 -33
  101. package/dist/operations/util.js +0 -9
  102. package/dist/resources/alert-rules.d.ts +0 -50
  103. package/dist/resources/alert-rules.js +0 -75
  104. package/dist/resources/attributes.d.ts +0 -19
  105. package/dist/resources/attributes.js +0 -10
  106. package/dist/resources/configs.d.ts +0 -681
  107. package/dist/resources/configs.js +0 -509
  108. package/dist/resources/events.d.ts +0 -61
  109. package/dist/resources/events.js +0 -42
  110. package/dist/resources/experiments.d.ts +0 -849
  111. package/dist/resources/experiments.js +0 -707
  112. package/dist/resources/gates.d.ts +0 -808
  113. package/dist/resources/gates.js +0 -522
  114. package/dist/resources/i18n.d.ts +0 -84
  115. package/dist/resources/i18n.js +0 -60
  116. package/dist/resources/index.d.ts +0 -2767
  117. package/dist/resources/index.js +0 -2563
  118. package/dist/resources/killswitches.d.ts +0 -436
  119. package/dist/resources/killswitches.js +0 -514
  120. package/dist/resources/metrics.d.ts +0 -54
  121. package/dist/resources/metrics.js +0 -40
  122. package/dist/resources/ops.d.ts +0 -88
  123. package/dist/resources/ops.js +0 -36
  124. package/dist/resources/projects.d.ts +0 -54
  125. package/dist/resources/projects.js +0 -14
  126. package/dist/resources/universes.d.ts +0 -185
  127. package/dist/resources/universes.js +0 -234
  128. package/dist/schemas/alert-rules.d.ts +0 -65
  129. package/dist/schemas/alert-rules.js +0 -37
  130. package/dist/schemas/configs.d.ts +0 -154
  131. package/dist/schemas/configs.js +0 -134
  132. package/dist/schemas/constants.d.ts +0 -6
  133. package/dist/schemas/constants.js +0 -7
  134. package/dist/schemas/experiments.d.ts +0 -229
  135. package/dist/schemas/experiments.js +0 -221
  136. package/dist/schemas/folder.d.ts +0 -10
  137. package/dist/schemas/folder.js +0 -8
  138. package/dist/schemas/gates.d.ts +0 -386
  139. package/dist/schemas/gates.js +0 -190
  140. package/dist/schemas/index.d.ts +0 -11
  141. package/dist/schemas/index.js +0 -762
  142. package/dist/schemas/killswitches.d.ts +0 -110
  143. package/dist/schemas/killswitches.js +0 -226
  144. package/dist/schemas/metric-name.d.ts +0 -5
  145. package/dist/schemas/metric-name.js +0 -6
  146. package/dist/schemas/pagination.d.ts +0 -37
  147. package/dist/schemas/pagination.js +0 -44
  148. package/dist/schemas/universes.d.ts +0 -35
  149. package/dist/schemas/universes.js +0 -55
  150. package/dist/transport.d.ts +0 -30
  151. package/dist/transport.js +0 -44
@@ -0,0 +1,748 @@
1
+ /api/admin/connectors:
2
+ get:
3
+ operationId: listConnectors
4
+ summary: List connectors
5
+ description: |-
6
+ Returns every connector in the project as a bare array (no pagination envelope).
7
+
8
+ The encrypted credentials backing each connector are never serialised — only the connector's non-secret `config`, `accountLabel`, and last-attempt health (`lastError`, `lastAttemptAt`, `lastSuccessAt`) are returned.
9
+
10
+ **Use case:** Render the integrations/triggers settings page, or drive a CI check that asserts every `github` connector is `enabled` and last dispatched without error.
11
+ tags:
12
+ - Connectors
13
+ parameters:
14
+ - $ref: ../components/parameters.yaml#/ProjectId
15
+ responses:
16
+ "200":
17
+ description: List connectors
18
+ content:
19
+ application/json:
20
+ schema:
21
+ $ref: ../components/schemas/connectors.yaml#/ListConnectorsResponse
22
+ example:
23
+ - id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
24
+ projectId: prj_01j7w7m9q4hxbf6npe6s9zr3vc
25
+ provider: github
26
+ name: Bugs → acme/app issues
27
+ enabled: true
28
+ events:
29
+ - bug.created
30
+ config:
31
+ owner: acme
32
+ repo: app
33
+ accountLabel: acme/app
34
+ lastError: null
35
+ lastAttemptAt: 2026-06-27T18:04:11.000Z
36
+ lastSuccessAt: 2026-06-27T18:04:11.000Z
37
+ createdAt: 2026-06-01T09:12:00.000Z
38
+ updatedAt: 2026-06-27T18:04:11.000Z
39
+ - id: 2d44f0aa-9c81-4e6b-8a17-7b3e0f9c1a22
40
+ projectId: prj_01j7w7m9q4hxbf6npe6s9zr3vc
41
+ provider: claude_trigger
42
+ name: Nightly ops sweep
43
+ enabled: true
44
+ events: []
45
+ config:
46
+ routineId: rtn_8fk20
47
+ accountLabel: rtn_8fk20
48
+ lastError: null
49
+ lastAttemptAt: null
50
+ lastSuccessAt: null
51
+ createdAt: 2026-06-20T22:00:00.000Z
52
+ updatedAt: 2026-06-20T22:00:00.000Z
53
+ "400":
54
+ $ref: ../components/responses.yaml#/BadRequest
55
+ "401":
56
+ $ref: ../components/responses.yaml#/Unauthorized
57
+ "403":
58
+ $ref: ../components/responses.yaml#/Forbidden
59
+ "404":
60
+ $ref: ../components/responses.yaml#/NotFound
61
+ "409":
62
+ $ref: ../components/responses.yaml#/Conflict
63
+ "422":
64
+ $ref: ../components/responses.yaml#/UnprocessableEntity
65
+ x-error-codes:
66
+ - UNAUTHORIZED
67
+ - FORBIDDEN
68
+ x-cli:
69
+ name: list
70
+ post:
71
+ operationId: createConnector
72
+ summary: Create a connector
73
+ description: |-
74
+ Creates a connector. The request body is discriminated on `provider`.
75
+
76
+ - **OAuth/app providers** (`google_sheets`, `github`, `slack`) — supply `{ provider, name, events }`. The connector is created `enabled: false` with empty `config` and no credentials; the provider's OAuth flow then attaches credentials and enables it.
77
+ - **Trigger providers** (`claude_trigger`, `cursor_trigger`, `copilot_trigger`, `jules_trigger`) — supply `config` plus the provider's credential field(s) and the connector is fireable immediately. Trigger creates are **idempotent** by their natural key (`config.routineId` / `config.repoUrl` / `config.owner`+`config.repo` / `config.source`): re-creating updates the existing row rather than duplicating it.
78
+
79
+ **Use cases**
80
+
81
+ - **File bugs as GitHub Issues** — `{ "provider": "github", "name": "Bugs → acme/app", "events": ["bug.created"] }`, then finish the GitHub App install.
82
+ - **Nightly ops sweep** — register a `claude_trigger` with its `routineId` and (optionally) a fire `token`; subscribe `events` later to auto-fire on new bugs.
83
+ - **Cold cloud-agent run** — register a `cursor_trigger`/`jules_trigger` with the repo coordinates plus both keys, or a `copilot_trigger` with the repo + user PAT.
84
+ tags:
85
+ - Connectors
86
+ parameters:
87
+ - $ref: ../components/parameters.yaml#/ProjectId
88
+ requestBody:
89
+ required: true
90
+ content:
91
+ application/json:
92
+ schema:
93
+ $ref: ../components/schemas/connectors.yaml#/CreateConnectorRequest
94
+ examples:
95
+ githubStub:
96
+ summary: GitHub — OAuth/app stub
97
+ description: "Creates a disabled `github` connector subscribed to `bug.created`. Finish the GitHub App install to attach credentials and enable it."
98
+ value:
99
+ provider: github
100
+ name: Bugs → acme/app issues
101
+ events:
102
+ - bug.created
103
+ claudeTrigger:
104
+ summary: Claude trigger — tokened
105
+ description: "Registers a Claude Code routine trigger with its fire token. Idempotent by `config.routineId`. `events` left empty so it does not auto-fire paid runs yet."
106
+ value:
107
+ provider: claude_trigger
108
+ name: Nightly ops sweep
109
+ config:
110
+ routineId: rtn_8fk20
111
+ fireText: Burn down the open bug + feature-request queue.
112
+ token: rtk_live_3f9a…
113
+ cursorTrigger:
114
+ summary: Cursor trigger — cold cloud agent
115
+ description: "Both keys required up front: the Cursor `apiKey` launches the run, the `opsKey` is injected as SHIPEASY_CLI_TOKEN. Idempotent by `config.repoUrl`."
116
+ value:
117
+ provider: cursor_trigger
118
+ name: Cursor ops agent
119
+ config:
120
+ repoUrl: https://github.com/acme/app
121
+ projectId: prj_01j7w7m9q4hxbf6npe6s9zr3vc
122
+ apiKey: cur_live_…
123
+ opsKey: ops_…
124
+ responses:
125
+ "201":
126
+ description: Create a connector
127
+ content:
128
+ application/json:
129
+ schema:
130
+ $ref: ../components/schemas/connectors.yaml#/CreateConnectorResponse
131
+ example:
132
+ id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
133
+ "400":
134
+ $ref: ../components/responses.yaml#/BadRequest
135
+ "401":
136
+ $ref: ../components/responses.yaml#/Unauthorized
137
+ "403":
138
+ $ref: ../components/responses.yaml#/Forbidden
139
+ "404":
140
+ $ref: ../components/responses.yaml#/NotFound
141
+ "409":
142
+ $ref: ../components/responses.yaml#/Conflict
143
+ "422":
144
+ $ref: ../components/responses.yaml#/UnprocessableEntity
145
+ x-error-codes:
146
+ - UNAUTHORIZED
147
+ - FORBIDDEN
148
+ - VALIDATION
149
+ x-cli:
150
+ name: create
151
+ /api/admin/connectors/{id}:
152
+ get:
153
+ operationId: getConnector
154
+ summary: Get a connector
155
+ description: |-
156
+ Returns a single connector by id. The encrypted credentials are never serialised.
157
+
158
+ **Use case:** Inspect one connector's health — its `enabled` state, subscribed `events`, and last-attempt outcome (`lastError`/`lastSuccessAt`).
159
+ tags:
160
+ - Connectors
161
+ parameters:
162
+ - $ref: ../components/parameters.yaml#/ProjectId
163
+ - name: id
164
+ in: path
165
+ required: true
166
+ description: Stable opaque connector id.
167
+ schema:
168
+ type: string
169
+ responses:
170
+ "200":
171
+ description: Get a connector
172
+ content:
173
+ application/json:
174
+ schema:
175
+ $ref: ../components/schemas/connectors.yaml#/GetConnectorResponse
176
+ example:
177
+ id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
178
+ projectId: prj_01j7w7m9q4hxbf6npe6s9zr3vc
179
+ provider: github
180
+ name: Bugs → acme/app issues
181
+ enabled: true
182
+ events:
183
+ - bug.created
184
+ config:
185
+ owner: acme
186
+ repo: app
187
+ accountLabel: acme/app
188
+ lastError: null
189
+ lastAttemptAt: 2026-06-27T18:04:11.000Z
190
+ lastSuccessAt: 2026-06-27T18:04:11.000Z
191
+ createdAt: 2026-06-01T09:12:00.000Z
192
+ updatedAt: 2026-06-27T18:04:11.000Z
193
+ "400":
194
+ $ref: ../components/responses.yaml#/BadRequest
195
+ "401":
196
+ $ref: ../components/responses.yaml#/Unauthorized
197
+ "403":
198
+ $ref: ../components/responses.yaml#/Forbidden
199
+ "404":
200
+ $ref: ../components/responses.yaml#/NotFound
201
+ "409":
202
+ $ref: ../components/responses.yaml#/Conflict
203
+ "422":
204
+ $ref: ../components/responses.yaml#/UnprocessableEntity
205
+ x-error-codes:
206
+ - UNAUTHORIZED
207
+ - FORBIDDEN
208
+ - NOT_FOUND
209
+ x-cli:
210
+ name: get
211
+ positional:
212
+ - id
213
+ patch:
214
+ operationId: updateConnector
215
+ summary: Update a connector
216
+ description: |-
217
+ Partial update — only supplied fields change. `events` and `config` **replace** wholesale; there is no merge or append. Secrets cannot be set through this endpoint (credential rotation goes through the provider-specific re-register flow).
218
+
219
+ The response carries only `{ id }` — re-fetch via `GET /api/admin/connectors/{id}` for the new row.
220
+
221
+ **Use cases**
222
+
223
+ - **Pause a connector** — `{ "enabled": false }`. Stops all dispatch / auto-fire without deleting it.
224
+ - **Change subscribed events** — send the full new `events` array. An empty array unsubscribes the connector from every event.
225
+ - **Rename** — `{ "name": "Bugs → acme/app issues" }`.
226
+ - **Retarget** — send a new `config` (e.g. a different Sheets `sheetTitle`); it replaces the stored config wholesale.
227
+ tags:
228
+ - Connectors
229
+ parameters:
230
+ - $ref: ../components/parameters.yaml#/ProjectId
231
+ - name: id
232
+ in: path
233
+ required: true
234
+ description: Stable opaque connector id.
235
+ schema:
236
+ type: string
237
+ requestBody:
238
+ required: true
239
+ content:
240
+ application/json:
241
+ schema:
242
+ $ref: ../components/schemas/connectors.yaml#/UpdateConnectorRequest
243
+ examples:
244
+ pause:
245
+ summary: Pause — disable the connector
246
+ description: 'Stops all dispatch / auto-fire. Re-enable with `{ "enabled": true }`.'
247
+ value:
248
+ enabled: false
249
+ resubscribe:
250
+ summary: Replace subscribed events
251
+ description: "Array fields replace wholesale. Send the full new list; an empty array unsubscribes from everything."
252
+ value:
253
+ events:
254
+ - bug.created
255
+ - feature_request.created
256
+ retarget:
257
+ summary: Retarget config
258
+ description: Replaces the stored non-secret config wholesale.
259
+ value:
260
+ config:
261
+ spreadsheetId: 1AbC…
262
+ sheetTitle: Bugs Q3
263
+ responses:
264
+ "200":
265
+ description: Update a connector
266
+ content:
267
+ application/json:
268
+ schema:
269
+ $ref: ../components/schemas/connectors.yaml#/UpdateConnectorResponse
270
+ example:
271
+ id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
272
+ "400":
273
+ $ref: ../components/responses.yaml#/BadRequest
274
+ "401":
275
+ $ref: ../components/responses.yaml#/Unauthorized
276
+ "403":
277
+ $ref: ../components/responses.yaml#/Forbidden
278
+ "404":
279
+ $ref: ../components/responses.yaml#/NotFound
280
+ "409":
281
+ $ref: ../components/responses.yaml#/Conflict
282
+ "422":
283
+ $ref: ../components/responses.yaml#/UnprocessableEntity
284
+ x-error-codes:
285
+ - UNAUTHORIZED
286
+ - FORBIDDEN
287
+ - NOT_FOUND
288
+ - VALIDATION
289
+ x-cli:
290
+ name: update
291
+ positional:
292
+ - id
293
+ delete:
294
+ operationId: deleteConnector
295
+ summary: Delete a connector
296
+ description: |-
297
+ Permanently removes the connector and its stored credentials.
298
+
299
+ **Use case:** Disconnect an integration for good — e.g. tear down a `github` connector after migrating bug routing elsewhere.
300
+ tags:
301
+ - Connectors
302
+ parameters:
303
+ - $ref: ../components/parameters.yaml#/ProjectId
304
+ - name: id
305
+ in: path
306
+ required: true
307
+ description: Stable opaque connector id.
308
+ schema:
309
+ type: string
310
+ responses:
311
+ "200":
312
+ description: Delete a connector
313
+ content:
314
+ application/json:
315
+ schema:
316
+ $ref: ../components/schemas/connectors.yaml#/DeleteConnectorResponse
317
+ example:
318
+ ok: true
319
+ "400":
320
+ $ref: ../components/responses.yaml#/BadRequest
321
+ "401":
322
+ $ref: ../components/responses.yaml#/Unauthorized
323
+ "403":
324
+ $ref: ../components/responses.yaml#/Forbidden
325
+ "404":
326
+ $ref: ../components/responses.yaml#/NotFound
327
+ "409":
328
+ $ref: ../components/responses.yaml#/Conflict
329
+ "422":
330
+ $ref: ../components/responses.yaml#/UnprocessableEntity
331
+ x-error-codes:
332
+ - UNAUTHORIZED
333
+ - FORBIDDEN
334
+ - NOT_FOUND
335
+ x-cli:
336
+ name: archive
337
+ positional:
338
+ - id
339
+ /api/admin/connectors/{id}/fire:
340
+ post:
341
+ operationId: fireConnector
342
+ summary: Fire a trigger connector
343
+ description: |-
344
+ Manually kicks a trigger connector's run — Claude (kicks its preconfigured routine) or Cursor / Copilot / Jules (launches a cold cloud-agent run). Firing is event-less: it kicks the run with an optional caller-supplied prompt override rather than dispatching a single lifecycle payload.
345
+
346
+ Only trigger providers can be fired, and only once authenticated (a tokenless trigger cannot fire). The attempt's outcome is recorded on the connector's `lastAttemptAt` / `lastError` / `lastSuccessAt`.
347
+
348
+ **Use case:** Kick a one-off ops sweep on demand from the dashboard's "Fire now" button, optionally overriding the routine's default prompt.
349
+ tags:
350
+ - Connectors
351
+ parameters:
352
+ - $ref: ../components/parameters.yaml#/ProjectId
353
+ - name: id
354
+ in: path
355
+ required: true
356
+ description: Stable opaque connector id.
357
+ schema:
358
+ type: string
359
+ requestBody:
360
+ required: false
361
+ content:
362
+ application/json:
363
+ schema:
364
+ $ref: ../components/schemas/connectors.yaml#/FireConnectorRequest
365
+ examples:
366
+ default:
367
+ summary: Fire with the provider default prompt
368
+ description: Empty body — kicks the run with the provider's own default (Claude → configured `fireText`, others → built cold-start prompt).
369
+ value: {}
370
+ override:
371
+ summary: Fire with a prompt override
372
+ value:
373
+ text: Triage only the P0 bugs reported in the last 24h.
374
+ responses:
375
+ "200":
376
+ description: Fire a trigger connector
377
+ content:
378
+ application/json:
379
+ schema:
380
+ $ref: ../components/schemas/connectors.yaml#/FireConnectorResponse
381
+ example:
382
+ ok: true
383
+ "400":
384
+ $ref: ../components/responses.yaml#/BadRequest
385
+ "401":
386
+ $ref: ../components/responses.yaml#/Unauthorized
387
+ "403":
388
+ $ref: ../components/responses.yaml#/Forbidden
389
+ "404":
390
+ $ref: ../components/responses.yaml#/NotFound
391
+ "409":
392
+ $ref: ../components/responses.yaml#/Conflict
393
+ "422":
394
+ $ref: ../components/responses.yaml#/UnprocessableEntity
395
+ x-error-codes:
396
+ - UNAUTHORIZED
397
+ - FORBIDDEN
398
+ - NOT_FOUND
399
+ x-cli:
400
+ name: fire
401
+ positional:
402
+ - id
403
+ /api/admin/connectors/{id}/test:
404
+ post:
405
+ operationId: testConnector
406
+ summary: Test a connector
407
+ description: |-
408
+ Dispatches a single synthetic `bug.created` payload to the connector's destination so you can verify the integration end-to-end. Unlike `fire`, this runs the real dispatch path (posts a Slack message / appends a Sheets row / files a GitHub Issue) with throwaway test content. The attempt's outcome is recorded on the connector's `lastAttemptAt` / `lastError` / `lastSuccessAt`.
409
+
410
+ When the provider produces a linkable artifact (e.g. a GitHub Issue), its URL is returned as `issueUrl`; otherwise `issueUrl` is `null`.
411
+
412
+ **Use case:** Click "Send test" after wiring up a connector to confirm credentials and config are correct before relying on it for real events.
413
+ tags:
414
+ - Connectors
415
+ parameters:
416
+ - $ref: ../components/parameters.yaml#/ProjectId
417
+ - name: id
418
+ in: path
419
+ required: true
420
+ description: Stable opaque connector id.
421
+ schema:
422
+ type: string
423
+ responses:
424
+ "200":
425
+ description: Test a connector
426
+ content:
427
+ application/json:
428
+ schema:
429
+ $ref: ../components/schemas/connectors.yaml#/TestConnectorResponse
430
+ example:
431
+ ok: true
432
+ issueUrl: https://github.com/acme/app/issues/4217
433
+ "400":
434
+ $ref: ../components/responses.yaml#/BadRequest
435
+ "401":
436
+ $ref: ../components/responses.yaml#/Unauthorized
437
+ "403":
438
+ $ref: ../components/responses.yaml#/Forbidden
439
+ "404":
440
+ $ref: ../components/responses.yaml#/NotFound
441
+ "409":
442
+ $ref: ../components/responses.yaml#/Conflict
443
+ "422":
444
+ $ref: ../components/responses.yaml#/UnprocessableEntity
445
+ x-error-codes:
446
+ - UNAUTHORIZED
447
+ - FORBIDDEN
448
+ - NOT_FOUND
449
+ x-cli:
450
+ name: test
451
+ positional:
452
+ - id
453
+ /api/admin/connectors/{id}/trigger:
454
+ patch:
455
+ operationId: updateTriggerConnector
456
+ summary: Update a trigger connector
457
+ description: |-
458
+ Edit an existing coding-agent **trigger** connector (`claude_trigger` / `cursor_trigger` / `copilot_trigger` / `jules_trigger`) — replace its non-secret `config` and, optionally, rotate its credential secret(s). Discriminated on `provider`; the id in the path selects the connector and its `provider` must match the body.
459
+
460
+ Unlike the generic `PATCH /api/admin/connectors/{id}` (which cannot touch secrets), this endpoint always replaces the non-secret `config` wholesale and merges any supplied secret over the stored credential cipher — so a single half of a two-key pair (e.g. just the ops key) can be rotated on its own. A blank/omitted secret leaves the stored cipher untouched.
461
+
462
+ The response carries only `{ id }` — re-fetch via `GET /api/admin/connectors/{id}` for the new row.
463
+
464
+ **Use case:** Re-point a Cursor trigger at a new repo ref, or rotate a Claude trigger's fire token, without deleting and re-creating the connector.
465
+ tags:
466
+ - Connectors
467
+ parameters:
468
+ - $ref: ../components/parameters.yaml#/ProjectId
469
+ - name: id
470
+ in: path
471
+ required: true
472
+ description: Stable opaque connector id. Its stored `provider` must match the body's `provider`.
473
+ schema:
474
+ type: string
475
+ requestBody:
476
+ required: true
477
+ content:
478
+ application/json:
479
+ schema:
480
+ $ref: ../components/schemas/connectors.yaml#/UpdateTriggerConnectorRequest
481
+ examples:
482
+ claude:
483
+ summary: Claude — repoint routine, rotate token
484
+ description: Replaces the routine config and rotates the fire token.
485
+ value:
486
+ provider: claude_trigger
487
+ config:
488
+ routineId: rtn_9f2c
489
+ token: fire_live_a1b2c3
490
+ cursor:
491
+ summary: Cursor — rotate just the ops key
492
+ description: Leaves the launch key untouched, rotates only the restricted ops key.
493
+ value:
494
+ provider: cursor_trigger
495
+ config:
496
+ repoUrl: https://github.com/acme/app
497
+ projectId: f81d4fae-7dec-11d0-a765-00a0c91e6bf6
498
+ opsKey: sdk_ops_live_x9y8z7
499
+ responses:
500
+ "200":
501
+ description: Update a trigger connector
502
+ content:
503
+ application/json:
504
+ schema:
505
+ $ref: ../components/schemas/connectors.yaml#/UpdateConnectorResponse
506
+ example:
507
+ id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
508
+ "400":
509
+ $ref: ../components/responses.yaml#/BadRequest
510
+ "401":
511
+ $ref: ../components/responses.yaml#/Unauthorized
512
+ "403":
513
+ $ref: ../components/responses.yaml#/Forbidden
514
+ "404":
515
+ $ref: ../components/responses.yaml#/NotFound
516
+ "409":
517
+ $ref: ../components/responses.yaml#/Conflict
518
+ "422":
519
+ $ref: ../components/responses.yaml#/UnprocessableEntity
520
+ x-error-codes:
521
+ - UNAUTHORIZED
522
+ - FORBIDDEN
523
+ - NOT_FOUND
524
+ - VALIDATION
525
+ x-cli:
526
+ name: trigger
527
+ positional:
528
+ - id
529
+ /api/admin/connectors/trigger:
530
+ post:
531
+ operationId: createTriggerConnector
532
+ summary: Create a recurring coding-agent trigger
533
+ description: |-
534
+ Creates (or idempotently updates) a coding-agent **trigger** connector — the recurring, unattended run that burns down the ops queue in `--pr` mode. Discriminated on `provider`; only the four Shipeasy-fireable providers are accepted (`claude_trigger`, `cursor_trigger`, `copilot_trigger`, `jules_trigger`). Config + credential(s) arrive together; creates are idempotent by the provider's natural key, so re-creating updates the existing row.
535
+
536
+ Platforms without a fire endpoint (Codex, Windsurf, Cline, OpenClaw, OpenCode, Continue) cannot be created here — they are scheduled on their own platform (typically a GitHub Actions `schedule:` cron running the platform's headless CLI with the trigger prompt).
537
+
538
+ **Use cases**
539
+
540
+ - **Register a Claude routine** — after `RemoteTrigger {action:"create"}` returns `trig_…`, `{ "provider": "claude_trigger", "config": { "routineId": "trig_…" } }` (tokenless is fine; add the fire token later).
541
+ - **Cold Cursor/Jules run** — repo coordinates + both keys; Shipeasy launches the run and the PR opens via the provider's GitHub App.
542
+ - **Copilot cloud agent** — repo + a Copilot-licensed user PAT with the "Agent tasks" permission.
543
+ tags:
544
+ - Trigger
545
+ parameters:
546
+ - $ref: ../components/parameters.yaml#/ProjectId
547
+ requestBody:
548
+ required: true
549
+ content:
550
+ application/json:
551
+ schema:
552
+ $ref: ../components/schemas/connectors.yaml#/CreateTriggerConnectorRequest
553
+ examples:
554
+ claude:
555
+ summary: Claude routine (tokenless)
556
+ value:
557
+ provider: claude_trigger
558
+ name: Nightly ops sweep
559
+ config:
560
+ routineId: trig_8fk20
561
+ cursor:
562
+ summary: Cursor cold cloud agent
563
+ value:
564
+ provider: cursor_trigger
565
+ name: Cursor ops agent
566
+ config:
567
+ repoUrl: https://github.com/acme/app
568
+ projectId: prj_01j7w7m9q4hxbf6npe6s9zr3vc
569
+ apiKey: cur_live_…
570
+ opsKey: ops_…
571
+ responses:
572
+ "201":
573
+ description: Trigger connector created (or idempotently updated)
574
+ content:
575
+ application/json:
576
+ schema:
577
+ $ref: ../components/schemas/connectors.yaml#/CreateConnectorResponse
578
+ example:
579
+ id: 9b0e7c2a-1f3d-4a8e-bf21-0c6a2e5d7f10
580
+ "400":
581
+ $ref: ../components/responses.yaml#/BadRequest
582
+ "401":
583
+ $ref: ../components/responses.yaml#/Unauthorized
584
+ "403":
585
+ $ref: ../components/responses.yaml#/Forbidden
586
+ "422":
587
+ $ref: ../components/responses.yaml#/UnprocessableEntity
588
+ x-error-codes:
589
+ - UNAUTHORIZED
590
+ - FORBIDDEN
591
+ - VALIDATION
592
+ x-cli:
593
+ helpPreamble: |-
594
+ A trigger is an unattended, scheduled agent run: on a cron cadence it runs the
595
+ shipeasy-ops-work loop in --pr mode against your project — one atomic diff and
596
+ ONE pull request per fixed item, nothing auto-merges.
597
+
598
+ Whatever the provider, the scheduled run executes this trigger prompt (headless
599
+ CLIs take it as the prompt; cloud agents as the task body):
600
+
601
+ You are an unattended Shipeasy maintenance run. Authenticate every `shipeasy`
602
+ call with these env vars (the CLI reads them directly — do NOT run
603
+ `shipeasy login`, never echo the token). Put them at the top of EVERY shell
604
+ invocation that calls `shipeasy`; each command runs in a fresh shell:
605
+
606
+ export SHIPEASY_CLI_TOKEN="<OPS_KEY>"
607
+ export SHIPEASY_PROJECT_ID="<PROJECT_ID>"
608
+
609
+ Ensure the repo is bound: test -f .shipeasy || printf '{"project_id":"<PROJECT_ID>"}\n' > .shipeasy
610
+ (never commit .shipeasy).
611
+
612
+ Refresh to the latest plugin + CLI, then run the ops work loop in --pr mode:
613
+ <PLUGIN-INSTALL-FOR-THIS-HOST> # plugin install for claude/copilot, or `npx -y skills add …`
614
+ npm install -g @shipeasy/cli@latest
615
+ Then follow the installed shipeasy-ops-work (--pr) workflow verbatim: burn down
616
+ the queue, one atomic diff per item, open ONE PR per item from a safe branch
617
+ prefix, flip each to ready_for_qa, add "Closes #<issue>" where an item has a
618
+ connected GitHub issue. If the queue is empty, exit cleanly. Never merge.
619
+
620
+ <OPS_KEY> is a restricted `ops` key — mint with
621
+ `npx -y @shipeasy/cli@latest keys create --type ops`. It reads the queue, flips
622
+ status, links the PR it opens, and creates resources only; it can never edit or
623
+ delete existing resources, and auto-extends its 7-day expiry on each run.
624
+ <PROJECT_ID> comes from the bound .shipeasy. Never print either value.
625
+
626
+ Safety: auto-approve flags (--approval-mode=yolo, --dangerously-skip-permissions,
627
+ …) remove the human gate — run only in an isolated env. Unattended loops spend
628
+ tokens/credits on a cadence: start weekly/daily and watch the first runs.
629
+ commands:
630
+ - name: create claude
631
+ summary: Register a Claude Code scheduled routine as the trigger connector
632
+ preset: { provider: claude_trigger }
633
+ help: |-
634
+ The reference implementation — a routine in Anthropic's cloud, no GitHub
635
+ Actions. The routines API is reachable only by the agent's in-process
636
+ RemoteTrigger tool, so provisioning is a hybrid split:
637
+
638
+ 1. `shipeasy ops trigger prep --frequency <4h|6h|daily|weekdays|weekly|cron>`
639
+ mints the restricted ops key, resolves repo + cron, and writes the exact
640
+ RemoteTrigger create body to a 0600 temp file (the key is never printed).
641
+ 2. The agent picks an environment_id from its RemoteTrigger env list — the
642
+ environment's network access must allow shipeasy.ai + api.shipeasy.ai
643
+ (Custom network; new envs default to Trusted, which fails every shipeasy
644
+ call) — then calls RemoteTrigger {action:"create"} and captures trig_….
645
+ Verify with {action:"run"} (confirm first — it spends tokens and may open
646
+ a real PR).
647
+ 3. Register the connector (idempotent by routineId; tokenless is fine):
648
+
649
+ shipeasy ops trigger create claude --config '{"routineId":"trig_…"}'
650
+
651
+ The fire token ("Fire now" + event auto-fire) is web-UI-only: open
652
+ https://claude.ai/code/routines → the routine → add an API trigger →
653
+ Generate token, then re-run the create with --token <token> and optionally
654
+ --events '["bug.created","feature_request.created"]' — the same row is
655
+ upgraded in place. GitHub access is connected once via /web-setup or the
656
+ Claude GitHub App. Manage/pause the routine at claude.ai/code/routines.
657
+ - name: create cursor
658
+ summary: Register a Cursor cloud-agent trigger (cold-fire; Shipeasy launches the run)
659
+ preset: { provider: cursor_trigger }
660
+ help: |-
661
+ Cursor cloud agents are cold-fireable: one authenticated POST to
662
+ https://api.cursor.com/v1/agents starts a run from nothing, and
663
+ autoCreatePR opens the PR via Cursor's GitHub App. Registering the
664
+ connector stores both credentials, so Shipeasy can fire it on demand and
665
+ on subscribed events; the ops key rides the launch envVars (never the
666
+ prompt):
667
+
668
+ shipeasy ops trigger create cursor \
669
+ --config '{"repoUrl":"https://github.com/<owner>/<repo>","projectId":"<prj_…>"}' \
670
+ --api-key <CURSOR_API_KEY> --ops-key <ops_…>
671
+
672
+ For a fixed cadence (nightly runs without new feedback) add a Cursor
673
+ Automation (cursor.com/automations) with the same trigger prompt — cron +
674
+ "Pull request creation" enabled. Note: Automations always run in Max Mode
675
+ (billed on cloud-agent usage).
676
+ - name: create copilot
677
+ summary: Register a GitHub Copilot cloud-agent trigger
678
+ preset: { provider: copilot_trigger }
679
+ help: |-
680
+ Copilot's cloud agent starts from one authenticated POST to
681
+ https://api.github.com/agents/repos/<owner>/<repo>/tasks with
682
+ { prompt, create_pull_request: true }. Auth is a user-to-server token
683
+ ONLY: a fine-grained user PAT with the "Agent tasks" repo permission
684
+ (read+write) for a Copilot-licensed account — the Actions GITHUB_TOKEN and
685
+ GitHub App installation tokens are rejected. The agent reads
686
+ SHIPEASY_CLI_TOKEN from the repo's own Agents secret store, so Shipeasy
687
+ stores only the PAT:
688
+
689
+ shipeasy ops trigger create copilot \
690
+ --config '{"owner":"<owner>","repo":"<repo>"}' --token <fine-grained PAT>
691
+
692
+ Set SHIPEASY_CLI_TOKEN (the restricted ops key) + SHIPEASY_PROJECT_ID in
693
+ the repo's Agents secrets first. For a fixed cadence use Copilot
694
+ automations (repo Agents tab; hourly/daily/weekly, private/internal repos
695
+ only) or a scheduled Actions job running `gh agent-task create`.
696
+ - name: create jules
697
+ aliases: [gemini]
698
+ summary: Register a Google Jules (Gemini) trigger
699
+ preset: { provider: jules_trigger }
700
+ help: |-
701
+ Jules — Google's async coding agent (the fireable Gemini path) — starts a
702
+ session from one POST to https://jules.googleapis.com/v1alpha/sessions
703
+ (header X-Goog-Api-Key) with sourceContext.source =
704
+ sources/github/<owner>/<repo> and automationMode: "AUTO_CREATE_PR". Jules
705
+ exposes no env channel, so the restricted ops key is embedded in the
706
+ session prompt (safe — it is the limited ops key):
707
+
708
+ shipeasy ops trigger create jules \
709
+ --config '{"source":"sources/github/<owner>/<repo>"}' \
710
+ --api-key <JULES_API_KEY> --ops-key <ops_…>
711
+
712
+ Connect the repo to Jules once (jules.google.com → connect GitHub). For a
713
+ fixed cadence use Jules scheduled tasks (UI-only), or fall back to the
714
+ Gemini CLI in a GitHub Actions schedule: job
715
+ (`gemini -p "<TRIGGER PROMPT>" --approval-mode=yolo`; auth GEMINI_API_KEY).
716
+ fallback:
717
+ argument: provider
718
+ platforms: [codex, windsurf, cline, openclaw, opencode, continue]
719
+ help: |-
720
+ Direct (Shipeasy-fired) triggers are not supported for this platform — it
721
+ exposes no HTTP "start a run" endpoint our Worker can call. Supported here:
722
+ claude, cursor, copilot, jules (alias: gemini) — see
723
+ `shipeasy ops trigger create <provider> --help`.
724
+
725
+ Platform-scheduled setup instead (the platform's own scheduler fires the
726
+ run; nothing to register in Shipeasy):
727
+
728
+ 1. Mint the restricted ops key (`shipeasy sdk keys create --type ops --json`)
729
+ and read the project id from .shipeasy. Never print either.
730
+ 2. Build the trigger prompt (run `shipeasy ops trigger create claude --help`
731
+ for the shared template) with the key, project id, and your platform's
732
+ install line substituted.
733
+ 3. Schedule a headless run with it — a GitHub Actions `schedule:` cron
734
+ (always-on; credentials as repo secrets incl. a GH_TOKEN/PAT with
735
+ contents:write + pull-requests:write) or a local cron/daemon (machine
736
+ must stay awake):
737
+
738
+ codex GitHub Actions cron → `codex cloud exec --env <ENV_ID> "<PROMPT>"`
739
+ (submits a Codex Cloud task — machine-off; configure network +
740
+ SHIPEASY_* secrets once at chatgpt.com/codex/cloud/settings/environments)
741
+ windsurf Devin Scheduled Sessions (cloud cron; WINDSURF/DEVIN API key)
742
+ cline `cline schedule create --cron "…" --prompt "<PROMPT>"` (local daemon)
743
+ openclaw `openclaw cron create "…" "<PROMPT>"` (local gateway; static API key)
744
+ opencode `opencode run "<PROMPT>"` + external cron (permission: "allow")
745
+ continue `cn -p --auto "<PROMPT>"` + external cron (CONTINUE_API_KEY)
746
+
747
+ 4. Verify one manual fire (expect a PR or a clean empty-queue exit) and
748
+ manage/pause it on that platform's scheduler.