@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.
- package/README.md +37 -0
- package/dist/chunk-EPLLHLZN.js +1616 -0
- package/dist/chunk-EPLLHLZN.js.map +1 -0
- package/dist/chunk-SPH5HWCD.js +3326 -0
- package/dist/chunk-SPH5HWCD.js.map +1 -0
- package/dist/client-pVkoo3Bf.d.ts +11186 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +215 -0
- package/dist/client.js.map +1 -0
- package/dist/custom.d.ts +64 -0
- package/dist/custom.js +292 -0
- package/dist/custom.js.map +1 -0
- package/dist/index.d.ts +29 -41
- package/dist/index.js +258 -4375
- package/dist/index.js.map +1 -0
- package/dist/node-context.d.ts +81 -33
- package/dist/node-context.js +98 -44
- package/dist/node-context.js.map +1 -0
- package/dist/schemas.d.ts +7920 -0
- package/dist/schemas.js +1083 -0
- package/dist/schemas.js.map +1 -0
- package/openapi.json +15297 -3044
- package/openapi.yaml +13979 -0
- package/package.json +33 -26
- package/spec/components/errors.yaml +53 -0
- package/spec/components/parameters.yaml +24 -0
- package/spec/components/responses.yaml +107 -0
- package/spec/components/schemas/alert-rules.yaml +175 -0
- package/spec/components/schemas/attributes.yaml +157 -0
- package/spec/components/schemas/common.yaml +87 -0
- package/spec/components/schemas/configs.yaml +371 -0
- package/spec/components/schemas/connectors.yaml +593 -0
- package/spec/components/schemas/errors-api.yaml +209 -0
- package/spec/components/schemas/events.yaml +321 -0
- package/spec/components/schemas/experiments.yaml +865 -0
- package/spec/components/schemas/gate-templates.yaml +198 -0
- package/spec/components/schemas/gates.yaml +890 -0
- package/spec/components/schemas/i18n.yaml +478 -0
- package/spec/components/schemas/keys.yaml +186 -0
- package/spec/components/schemas/killswitches.yaml +309 -0
- package/spec/components/schemas/metrics.yaml +547 -0
- package/spec/components/schemas/ops.yaml +1011 -0
- package/spec/components/schemas/projects.yaml +222 -0
- package/spec/components/schemas/search.yaml +46 -0
- package/spec/components/schemas/universes.yaml +127 -0
- package/spec/openapi.yaml +348 -0
- package/spec/paths/alert-rules.yaml +250 -0
- package/spec/paths/attributes.yaml +261 -0
- package/spec/paths/configs.yaml +744 -0
- package/spec/paths/connectors.yaml +748 -0
- package/spec/paths/errors.yaml +382 -0
- package/spec/paths/events.yaml +366 -0
- package/spec/paths/experiments.yaml +777 -0
- package/spec/paths/gate-templates.yaml +263 -0
- package/spec/paths/gates.yaml +451 -0
- package/spec/paths/i18n.yaml +544 -0
- package/spec/paths/keys.yaml +181 -0
- package/spec/paths/killswitches.yaml +557 -0
- package/spec/paths/metrics.yaml +302 -0
- package/spec/paths/ops.yaml +446 -0
- package/spec/paths/projects.yaml +210 -0
- package/spec/paths/search.yaml +62 -0
- package/spec/paths/universes.yaml +247 -0
- package/dist/operations/attributes.d.ts +0 -33
- package/dist/operations/attributes.js +0 -16
- package/dist/operations/cli-adapter.d.ts +0 -35
- package/dist/operations/cli-adapter.js +0 -91
- package/dist/operations/coerce.d.ts +0 -32
- package/dist/operations/coerce.js +0 -53
- package/dist/operations/configs.d.ts +0 -28
- package/dist/operations/configs.js +0 -119
- package/dist/operations/docs.d.ts +0 -37
- package/dist/operations/docs.js +0 -39
- package/dist/operations/events.d.ts +0 -28
- package/dist/operations/events.js +0 -121
- package/dist/operations/experiments.d.ts +0 -28
- package/dist/operations/experiments.js +0 -280
- package/dist/operations/gates.d.ts +0 -28
- package/dist/operations/gates.js +0 -132
- package/dist/operations/i18n.d.ts +0 -28
- package/dist/operations/i18n.js +0 -121
- package/dist/operations/index.d.ts +0 -63
- package/dist/operations/index.js +0 -1751
- package/dist/operations/killswitches.d.ts +0 -28
- package/dist/operations/killswitches.js +0 -126
- package/dist/operations/mcp-adapter.d.ts +0 -35
- package/dist/operations/mcp-adapter.js +0 -94
- package/dist/operations/metrics.d.ts +0 -30
- package/dist/operations/metrics.js +0 -114
- package/dist/operations/ops.d.ts +0 -28
- package/dist/operations/ops.js +0 -313
- package/dist/operations/projects.d.ts +0 -28
- package/dist/operations/projects.js +0 -36
- package/dist/operations/sdk-docs.d.ts +0 -28
- package/dist/operations/sdk-docs.js +0 -160
- package/dist/operations/types.d.ts +0 -138
- package/dist/operations/types.js +0 -9
- package/dist/operations/universes.d.ts +0 -28
- package/dist/operations/universes.js +0 -93
- package/dist/operations/util.d.ts +0 -33
- package/dist/operations/util.js +0 -9
- package/dist/resources/alert-rules.d.ts +0 -50
- package/dist/resources/alert-rules.js +0 -75
- package/dist/resources/attributes.d.ts +0 -19
- package/dist/resources/attributes.js +0 -10
- package/dist/resources/configs.d.ts +0 -681
- package/dist/resources/configs.js +0 -509
- package/dist/resources/events.d.ts +0 -61
- package/dist/resources/events.js +0 -42
- package/dist/resources/experiments.d.ts +0 -849
- package/dist/resources/experiments.js +0 -707
- package/dist/resources/gates.d.ts +0 -808
- package/dist/resources/gates.js +0 -522
- package/dist/resources/i18n.d.ts +0 -84
- package/dist/resources/i18n.js +0 -60
- package/dist/resources/index.d.ts +0 -2767
- package/dist/resources/index.js +0 -2563
- package/dist/resources/killswitches.d.ts +0 -436
- package/dist/resources/killswitches.js +0 -514
- package/dist/resources/metrics.d.ts +0 -54
- package/dist/resources/metrics.js +0 -40
- package/dist/resources/ops.d.ts +0 -88
- package/dist/resources/ops.js +0 -36
- package/dist/resources/projects.d.ts +0 -54
- package/dist/resources/projects.js +0 -14
- package/dist/resources/universes.d.ts +0 -185
- package/dist/resources/universes.js +0 -234
- package/dist/schemas/alert-rules.d.ts +0 -65
- package/dist/schemas/alert-rules.js +0 -37
- package/dist/schemas/configs.d.ts +0 -154
- package/dist/schemas/configs.js +0 -134
- package/dist/schemas/constants.d.ts +0 -6
- package/dist/schemas/constants.js +0 -7
- package/dist/schemas/experiments.d.ts +0 -229
- package/dist/schemas/experiments.js +0 -221
- package/dist/schemas/folder.d.ts +0 -10
- package/dist/schemas/folder.js +0 -8
- package/dist/schemas/gates.d.ts +0 -386
- package/dist/schemas/gates.js +0 -190
- package/dist/schemas/index.d.ts +0 -11
- package/dist/schemas/index.js +0 -762
- package/dist/schemas/killswitches.d.ts +0 -110
- package/dist/schemas/killswitches.js +0 -226
- package/dist/schemas/metric-name.d.ts +0 -5
- package/dist/schemas/metric-name.js +0 -6
- package/dist/schemas/pagination.d.ts +0 -37
- package/dist/schemas/pagination.js +0 -44
- package/dist/schemas/universes.d.ts +0 -35
- package/dist/schemas/universes.js +0 -55
- package/dist/transport.d.ts +0 -30
- package/dist/transport.js +0 -44
package/dist/operations/ops.js
DELETED
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
// src/transport.ts
|
|
2
|
-
var ApiError = class extends Error {
|
|
3
|
-
constructor(message, status) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.status = status;
|
|
6
|
-
this.name = "ApiError";
|
|
7
|
-
}
|
|
8
|
-
status;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
// src/operations/util.ts
|
|
12
|
-
var num = (i, k) => i[k] === void 0 ? void 0 : i[k];
|
|
13
|
-
var str = (i, k) => i[k] === void 0 ? void 0 : i[k];
|
|
14
|
-
|
|
15
|
-
// src/operations/ops.ts
|
|
16
|
-
var QUEUE = ["ops"];
|
|
17
|
-
var ALERTS = ["ops", "alerts"];
|
|
18
|
-
var TYPES = ["bug", "feature_request", "error", "alert"];
|
|
19
|
-
var STATUSES = [
|
|
20
|
-
"open",
|
|
21
|
-
"triaged",
|
|
22
|
-
"in_progress",
|
|
23
|
-
"ready_for_qa",
|
|
24
|
-
"resolved",
|
|
25
|
-
"wont_fix"
|
|
26
|
-
];
|
|
27
|
-
var PRIORITIES = ["nice_to_have", "medium", "high", "critical"];
|
|
28
|
-
var COMPARATORS = ["gt", "gte", "lt", "lte"];
|
|
29
|
-
var SEVERITIES = ["danger", "warn", "info"];
|
|
30
|
-
async function resolveSlackChannel(client, idOrName) {
|
|
31
|
-
const res = await client.ops.channels();
|
|
32
|
-
if (!res.connected)
|
|
33
|
-
throw new ApiError("No Slack connector \u2014 connect Slack in Settings \u2192 Notifications first.", 400);
|
|
34
|
-
const stripped = idOrName.replace(/^#/, "");
|
|
35
|
-
const byId = res.channels.find((c) => c.id === idOrName);
|
|
36
|
-
if (byId) return { id: byId.id, name: byId.name };
|
|
37
|
-
const byName = res.channels.filter((c) => c.name === stripped);
|
|
38
|
-
if (byName.length === 1) return { id: byName[0].id, name: byName[0].name };
|
|
39
|
-
if (byName.length > 1)
|
|
40
|
-
throw new ApiError(`Slack channel name '${stripped}' is ambiguous \u2014 pass a channel id`, 400);
|
|
41
|
-
throw new ApiError(`Slack channel '${idOrName}' not found (run 'ops alerts channels')`, 404);
|
|
42
|
-
}
|
|
43
|
-
var opsOperations = [
|
|
44
|
-
// ── unified queue ──────────────────────────────────────────────────────────
|
|
45
|
-
{
|
|
46
|
-
group: QUEUE,
|
|
47
|
-
name: "list",
|
|
48
|
-
mutates: false,
|
|
49
|
-
summary: "List the operational queue",
|
|
50
|
-
description: "List the unified queue \u2014 bugs, feature requests, and auto-filed error/alert tickets. Filter by `type`, `status`, or `priority`.",
|
|
51
|
-
params: [
|
|
52
|
-
{ name: "type", type: "string", description: "Filter by type.", enum: [...TYPES, "all"] },
|
|
53
|
-
{ name: "status", type: "string", description: "Filter by status.", enum: [...STATUSES, "all"] },
|
|
54
|
-
{ name: "priority", type: "string", description: "Filter by priority.", enum: PRIORITIES },
|
|
55
|
-
{ name: "limit", type: "number", description: "Max rows (default 200)." }
|
|
56
|
-
],
|
|
57
|
-
examples: [
|
|
58
|
-
{ note: "Open critical items only", run: "shipeasy ops list --priority critical" },
|
|
59
|
-
{ note: "Just error tickets", run: "shipeasy ops list --type error" }
|
|
60
|
-
],
|
|
61
|
-
run: async (client, i) => {
|
|
62
|
-
let items = await client.ops.list({
|
|
63
|
-
type: str(i, "type") ?? "all",
|
|
64
|
-
status: str(i, "status") ?? "open",
|
|
65
|
-
limit: num(i, "limit") ?? 200
|
|
66
|
-
});
|
|
67
|
-
const priority = str(i, "priority");
|
|
68
|
-
if (priority) items = items.filter((x) => x.priority === priority);
|
|
69
|
-
return items;
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
group: QUEUE,
|
|
74
|
-
name: "get",
|
|
75
|
-
mutates: false,
|
|
76
|
-
summary: "Show one queue item",
|
|
77
|
-
description: "Show one queue item by number (#7 \u2192 7) or id \u2014 any type.",
|
|
78
|
-
params: [{ name: "handle", type: "string", description: "Item number or id.", required: true, positional: true }],
|
|
79
|
-
examples: [{ note: "By queue number", run: "shipeasy ops get 7" }],
|
|
80
|
-
run: (client, i) => client.ops.get(i.handle)
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
group: QUEUE,
|
|
84
|
-
name: "create",
|
|
85
|
-
mutates: true,
|
|
86
|
-
summary: "File a bug or feature request",
|
|
87
|
-
description: "File an operational item \u2014 a bug report or feature request \u2014 against the bound project. Fires the project's connectors (GitHub issue, Slack). error/alert tickets are auto-filed and cannot be created here.",
|
|
88
|
-
params: [
|
|
89
|
-
{ name: "type", type: "string", description: "Item type.", required: true, enum: ["bug", "feature_request"] },
|
|
90
|
-
{ name: "title", type: "string", description: "One-line title.", required: true, positional: true },
|
|
91
|
-
{ name: "body", type: "string", description: "Detailed description." },
|
|
92
|
-
{ name: "priority", type: "string", description: "Priority.", enum: PRIORITIES },
|
|
93
|
-
{ name: "stepsToReproduce", type: "string", description: "Repro steps (bugs)." },
|
|
94
|
-
{ name: "pageUrl", type: "string", description: "Page URL the item relates to." }
|
|
95
|
-
],
|
|
96
|
-
examples: [
|
|
97
|
-
{ note: "File a bug", run: 'shipeasy ops create "Checkout 500s on Safari" --type bug' },
|
|
98
|
-
{ note: "File a feature request", run: 'shipeasy ops create "Dark mode" --type feature_request --priority medium' }
|
|
99
|
-
],
|
|
100
|
-
run: (client, i) => client.ops.create({
|
|
101
|
-
type: i.type,
|
|
102
|
-
title: i.title,
|
|
103
|
-
...i.body ? { body: i.body } : {},
|
|
104
|
-
...i.priority ? { priority: i.priority } : {},
|
|
105
|
-
...i.stepsToReproduce ? { stepsToReproduce: i.stepsToReproduce } : {},
|
|
106
|
-
...i.pageUrl ? { pageUrl: i.pageUrl } : {}
|
|
107
|
-
})
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
group: QUEUE,
|
|
111
|
-
name: "update",
|
|
112
|
-
mutates: true,
|
|
113
|
-
summary: "Update a queue item's status/priority",
|
|
114
|
-
description: "Flip a queue item's status (any type) and optionally its priority.",
|
|
115
|
-
params: [
|
|
116
|
-
{ name: "handle", type: "string", description: "Item number or id.", required: true, positional: true },
|
|
117
|
-
{ name: "status", type: "string", description: "New status.", enum: STATUSES },
|
|
118
|
-
{ name: "priority", type: "string", description: "New priority.", enum: PRIORITIES }
|
|
119
|
-
],
|
|
120
|
-
examples: [
|
|
121
|
-
{ note: "Resolve item #7", run: "shipeasy ops update 7 --status resolved" },
|
|
122
|
-
{ note: "Bump priority", run: "shipeasy ops update 7 --priority high" }
|
|
123
|
-
],
|
|
124
|
-
run: (client, i) => {
|
|
125
|
-
const patch = {};
|
|
126
|
-
if (i.status !== void 0) patch.status = i.status;
|
|
127
|
-
if (i.priority !== void 0) patch.priority = i.priority;
|
|
128
|
-
if (!Object.keys(patch).length)
|
|
129
|
-
throw new ApiError("Nothing to update \u2014 pass status and/or priority.", 400);
|
|
130
|
-
return client.ops.update(i.handle, patch);
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
group: QUEUE,
|
|
135
|
-
name: "link-pr",
|
|
136
|
-
mutates: true,
|
|
137
|
-
summary: "Link the PR that fixed an item",
|
|
138
|
-
description: "Link the PR that fixed a queue item (any type). Records connector_data.github.pr. Pass `remove` to unlink.",
|
|
139
|
-
params: [
|
|
140
|
-
{ name: "handle", type: "string", description: "Item number or id.", required: true, positional: true },
|
|
141
|
-
{ name: "prNumber", type: "number", description: "PR number.", positional: true },
|
|
142
|
-
{ name: "url", type: "string", description: "Explicit PR URL (required for error/alert tickets)." },
|
|
143
|
-
{ name: "remove", type: "boolean", description: "Unlink the PR instead of setting one." }
|
|
144
|
-
],
|
|
145
|
-
examples: [
|
|
146
|
-
{ note: "Link the fixing PR", run: "shipeasy ops link-pr 7 42 --url https://github.com/acme/app/pull/42" }
|
|
147
|
-
],
|
|
148
|
-
run: (client, i) => {
|
|
149
|
-
if (i.remove) return client.ops.linkPr(i.handle, { prNumber: null });
|
|
150
|
-
const prNumber = num(i, "prNumber");
|
|
151
|
-
if (prNumber === void 0 || !Number.isInteger(prNumber) || prNumber <= 0)
|
|
152
|
-
throw new ApiError("Pass a positive PR number (or --remove to unlink).", 400);
|
|
153
|
-
return client.ops.linkPr(i.handle, {
|
|
154
|
-
prNumber,
|
|
155
|
-
...i.url ? { prUrl: i.url } : {}
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
group: QUEUE,
|
|
161
|
-
name: "notify",
|
|
162
|
-
mutates: true,
|
|
163
|
-
summary: "Raise a 'needs your attention' bell notification",
|
|
164
|
-
description: "Raise an attention bell notification (agent escalation, create-only). Idempotent on the dedupe key \u2014 pass `item` to derive `feedback:<n>`, or an explicit `key`.",
|
|
165
|
-
params: [
|
|
166
|
-
{ name: "title", type: "string", description: "One-line headline of what's blocked.", required: true },
|
|
167
|
-
{ name: "summary", type: "string", description: "One sentence: why it can't be fixed in code.", required: true },
|
|
168
|
-
{ name: "steps", type: "json", description: "Steps the human should take, as a JSON array of strings." },
|
|
169
|
-
{ name: "href", type: "string", description: "Dashboard-relative deep link." },
|
|
170
|
-
{ name: "item", type: "string", description: "Queue item number this is about (sets dedupe key feedback:<n>)." },
|
|
171
|
-
{ name: "key", type: "string", description: "Explicit dedupe key (overrides item)." }
|
|
172
|
-
],
|
|
173
|
-
examples: [
|
|
174
|
-
{ note: "Escalate a blocked item", run: `shipeasy ops notify --item 7 --title "Needs a DB migration" --summary "Fix requires a schema change I can't apply in code"` }
|
|
175
|
-
],
|
|
176
|
-
run: (client, i) => {
|
|
177
|
-
const item = str(i, "item");
|
|
178
|
-
const dedupeKey = str(i, "key") ?? (item ? `feedback:${item.replace(/^#/, "")}` : void 0);
|
|
179
|
-
return client.ops.notify({
|
|
180
|
-
title: i.title,
|
|
181
|
-
summary: i.summary,
|
|
182
|
-
steps: i.steps ?? [],
|
|
183
|
-
...i.href ? { href: i.href } : {},
|
|
184
|
-
...dedupeKey ? { dedupeKey } : {}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
// ── alert rules (ops alerts …) ───────────────────────────────────────────────
|
|
189
|
-
{
|
|
190
|
-
group: ALERTS,
|
|
191
|
-
name: "list",
|
|
192
|
-
mutates: false,
|
|
193
|
-
summary: "List alert rules",
|
|
194
|
-
description: "List the project's metric-threshold alert rules the analysis cron evaluates.",
|
|
195
|
-
params: [],
|
|
196
|
-
examples: [{ run: "shipeasy ops alerts list" }],
|
|
197
|
-
run: (client) => client.alertRules.list()
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
group: ALERTS,
|
|
201
|
-
name: "channels",
|
|
202
|
-
mutates: false,
|
|
203
|
-
summary: "List the project's Slack channels",
|
|
204
|
-
description: "List the project's Slack channels (for the `slackChannel` alert target).",
|
|
205
|
-
params: [],
|
|
206
|
-
examples: [{ run: "shipeasy ops alerts channels" }],
|
|
207
|
-
run: (client) => client.ops.channels()
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
group: ALERTS,
|
|
211
|
-
name: "create",
|
|
212
|
-
mutates: true,
|
|
213
|
-
summary: "Create an alert rule",
|
|
214
|
-
description: "Create a metric-threshold alert rule. The metric (and its aggregation) is fixed for the rule's life \u2014 delete + recreate to repoint it. Optionally target a Slack channel/email.",
|
|
215
|
-
params: [
|
|
216
|
-
{ name: "name", type: "string", description: "Rule name.", required: true, positional: true },
|
|
217
|
-
{ name: "metric", type: "string", description: "Metric to evaluate (id or name).", required: true },
|
|
218
|
-
{ name: "comparator", type: "string", description: "Comparison operator.", required: true, enum: COMPARATORS },
|
|
219
|
-
{ name: "threshold", type: "number", description: "Threshold the metric value is compared against.", required: true },
|
|
220
|
-
{ name: "window", type: "number", description: "Lookback window in whole hours (1\u2013720). Defaults to 24." },
|
|
221
|
-
{ name: "severity", type: "string", description: "Severity. Defaults to warn.", enum: SEVERITIES },
|
|
222
|
-
{ name: "disabled", type: "boolean", description: "Create the rule disabled." },
|
|
223
|
-
{ name: "slackChannel", type: "string", description: "Slack channel to post to (id or name)." },
|
|
224
|
-
{ name: "email", type: "string", description: "Email address to notify." }
|
|
225
|
-
],
|
|
226
|
-
examples: [
|
|
227
|
-
{ note: "Alert when error rate exceeds 50 / 24h", run: "shipeasy ops alerts create high-error-rate --metric api-errors --comparator gt --threshold 50" },
|
|
228
|
-
{ note: "Post to a Slack channel + email on-call", run: "shipeasy ops alerts create high-error-rate --metric api-errors --comparator gt --threshold 50 --slack-channel '#incidents' --email oncall@acme.com" }
|
|
229
|
-
],
|
|
230
|
-
run: async (client, i) => {
|
|
231
|
-
const metric = await client.metrics.resolve(i.metric);
|
|
232
|
-
const slackChannel = str(i, "slackChannel");
|
|
233
|
-
const email = str(i, "email");
|
|
234
|
-
const notify = slackChannel || email ? {
|
|
235
|
-
slackChannel: slackChannel ? await resolveSlackChannel(client, slackChannel) : null,
|
|
236
|
-
email: email ?? null
|
|
237
|
-
} : void 0;
|
|
238
|
-
return client.alertRules.create({
|
|
239
|
-
name: i.name,
|
|
240
|
-
metricId: metric.id,
|
|
241
|
-
comparator: i.comparator,
|
|
242
|
-
threshold: num(i, "threshold"),
|
|
243
|
-
windowHours: num(i, "window") ?? 24,
|
|
244
|
-
severity: str(i, "severity") ?? "warn",
|
|
245
|
-
enabled: !i.disabled,
|
|
246
|
-
...notify ? { notify } : {}
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
group: ALERTS,
|
|
252
|
-
name: "update",
|
|
253
|
-
mutates: true,
|
|
254
|
-
summary: "Update an alert rule",
|
|
255
|
-
description: "Update an alert rule's tunable knobs (by id, id-prefix, or unique name). The metric is immutable. Pass `clearTarget` to revert the rule's target to the project default.",
|
|
256
|
-
params: [
|
|
257
|
-
{ name: "rule", type: "string", description: "Rule id, id-prefix, or name.", required: true, positional: true },
|
|
258
|
-
{ name: "name", type: "string", description: "New human label." },
|
|
259
|
-
{ name: "comparator", type: "string", description: "Comparison operator.", enum: COMPARATORS },
|
|
260
|
-
{ name: "threshold", type: "number", description: "New threshold." },
|
|
261
|
-
{ name: "window", type: "number", description: "New lookback window in whole hours (1\u2013720)." },
|
|
262
|
-
{ name: "severity", type: "string", description: "New severity.", enum: SEVERITIES },
|
|
263
|
-
{ name: "enabled", type: "boolean", description: "Enable/disable the rule." },
|
|
264
|
-
{ name: "slackChannel", type: "string", description: "Set the Slack channel target (id or name)." },
|
|
265
|
-
{ name: "email", type: "string", description: "Set the email target." },
|
|
266
|
-
{ name: "clearTarget", type: "boolean", description: "Clear the target back to the project default." }
|
|
267
|
-
],
|
|
268
|
-
examples: [
|
|
269
|
-
{ note: "Raise the threshold", run: "shipeasy ops alerts update high-error-rate --threshold 100" },
|
|
270
|
-
{ note: "Disable a rule", run: "shipeasy ops alerts update high-error-rate --enabled false" }
|
|
271
|
-
],
|
|
272
|
-
run: async (client, i) => {
|
|
273
|
-
const rule = await client.alertRules.resolve(i.rule);
|
|
274
|
-
const patch = {};
|
|
275
|
-
if (i.name !== void 0) patch.name = i.name;
|
|
276
|
-
if (i.comparator !== void 0) patch.comparator = i.comparator;
|
|
277
|
-
if (i.threshold !== void 0) patch.threshold = num(i, "threshold");
|
|
278
|
-
if (i.window !== void 0) patch.windowHours = num(i, "window");
|
|
279
|
-
if (i.severity !== void 0) patch.severity = i.severity;
|
|
280
|
-
if (i.enabled !== void 0) patch.enabled = i.enabled;
|
|
281
|
-
const slackChannel = str(i, "slackChannel");
|
|
282
|
-
const email = str(i, "email");
|
|
283
|
-
if (i.clearTarget) {
|
|
284
|
-
patch.notify = { slackChannel: null, email: null };
|
|
285
|
-
} else if (slackChannel || email) {
|
|
286
|
-
patch.notify = {
|
|
287
|
-
slackChannel: slackChannel ? await resolveSlackChannel(client, slackChannel) : rule.notify?.slackChannel ?? null,
|
|
288
|
-
email: email ?? rule.notify?.email ?? null
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
if (!Object.keys(patch).length)
|
|
292
|
-
throw new ApiError("Nothing to update \u2014 pass at least one field to change.", 400);
|
|
293
|
-
return client.alertRules.update(rule.id, patch);
|
|
294
|
-
}
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
group: ALERTS,
|
|
298
|
-
name: "archive",
|
|
299
|
-
mutates: true,
|
|
300
|
-
summary: "Archive an alert rule",
|
|
301
|
-
description: "Archive (delete) an alert rule by id, id-prefix, or unique name.",
|
|
302
|
-
params: [{ name: "rule", type: "string", description: "Rule id, id-prefix, or name.", required: true, positional: true }],
|
|
303
|
-
examples: [{ run: "shipeasy ops alerts archive high-error-rate" }],
|
|
304
|
-
run: async (client, i) => {
|
|
305
|
-
const rule = await client.alertRules.resolve(i.rule);
|
|
306
|
-
await client.alertRules.delete(rule.id);
|
|
307
|
-
return { ok: true, archived: rule.name };
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
];
|
|
311
|
-
export {
|
|
312
|
-
opsOperations
|
|
313
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Operation } from './types.js';
|
|
2
|
-
import '../resources/index.js';
|
|
3
|
-
import 'zod/v4/core';
|
|
4
|
-
import 'zod';
|
|
5
|
-
import '../resources/attributes.js';
|
|
6
|
-
import '../transport.js';
|
|
7
|
-
import '../resources/i18n.js';
|
|
8
|
-
import '../resources/projects.js';
|
|
9
|
-
import '../resources/ops.js';
|
|
10
|
-
import '../resources/events.js';
|
|
11
|
-
import '../resources/metrics.js';
|
|
12
|
-
import '../resources/alert-rules.js';
|
|
13
|
-
import '../schemas/alert-rules.js';
|
|
14
|
-
import '../resources/killswitches.js';
|
|
15
|
-
import '../schemas/killswitches.js';
|
|
16
|
-
import '../schemas/pagination.js';
|
|
17
|
-
import '../resources/universes.js';
|
|
18
|
-
import '../schemas/universes.js';
|
|
19
|
-
import '../resources/configs.js';
|
|
20
|
-
import '../schemas/configs.js';
|
|
21
|
-
import '../resources/experiments.js';
|
|
22
|
-
import '../schemas/experiments.js';
|
|
23
|
-
import '../resources/gates.js';
|
|
24
|
-
import '../schemas/gates.js';
|
|
25
|
-
|
|
26
|
-
declare const projectOperations: Operation[];
|
|
27
|
-
|
|
28
|
-
export { projectOperations };
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// src/operations/projects.ts
|
|
2
|
-
var GROUP = ["projects"];
|
|
3
|
-
var projectOperations = [
|
|
4
|
-
{
|
|
5
|
-
group: GROUP,
|
|
6
|
-
name: "current",
|
|
7
|
-
mutates: false,
|
|
8
|
-
summary: "Show the current project",
|
|
9
|
-
description: "Return the project the session resolves to (plan, status, enabled modules, billing). The server reads the project from the auth header \u2014 no id needed. Powers `whoami`.",
|
|
10
|
-
params: [],
|
|
11
|
-
examples: [{ run: "shipeasy projects current" }],
|
|
12
|
-
run: (client) => client.projects.current()
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
group: GROUP,
|
|
16
|
-
name: "upsert",
|
|
17
|
-
mutates: false,
|
|
18
|
-
summary: "Find-or-create a project by domain",
|
|
19
|
-
description: "Find-or-create a project by domain (idempotent), under the session's owner. Returns the project. The `.shipeasy` bind that records the result locally is a consumer side-effect layered on top of this op \u2014 it is not performed here.",
|
|
20
|
-
params: [
|
|
21
|
-
{ name: "domain", type: "string", description: "Hostname-like project identifier (e.g. acme.com).", required: true },
|
|
22
|
-
{ name: "name", type: "string", description: "Human-readable name (defaults to the domain on first create)." }
|
|
23
|
-
],
|
|
24
|
-
examples: [
|
|
25
|
-
{ note: "Find-or-create by domain", run: "shipeasy projects upsert --domain acme.com" },
|
|
26
|
-
{ note: "Name it explicitly", run: 'shipeasy projects upsert --domain shouks.app --name "Shouks"' }
|
|
27
|
-
],
|
|
28
|
-
run: (client, i) => client.projects.upsert({
|
|
29
|
-
domain: i.domain,
|
|
30
|
-
...i.name ? { name: i.name } : {}
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
];
|
|
34
|
-
export {
|
|
35
|
-
projectOperations
|
|
36
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Operation } from './types.js';
|
|
2
|
-
import '../resources/index.js';
|
|
3
|
-
import 'zod/v4/core';
|
|
4
|
-
import 'zod';
|
|
5
|
-
import '../resources/attributes.js';
|
|
6
|
-
import '../transport.js';
|
|
7
|
-
import '../resources/i18n.js';
|
|
8
|
-
import '../resources/projects.js';
|
|
9
|
-
import '../resources/ops.js';
|
|
10
|
-
import '../resources/events.js';
|
|
11
|
-
import '../resources/metrics.js';
|
|
12
|
-
import '../resources/alert-rules.js';
|
|
13
|
-
import '../schemas/alert-rules.js';
|
|
14
|
-
import '../resources/killswitches.js';
|
|
15
|
-
import '../schemas/killswitches.js';
|
|
16
|
-
import '../schemas/pagination.js';
|
|
17
|
-
import '../resources/universes.js';
|
|
18
|
-
import '../schemas/universes.js';
|
|
19
|
-
import '../resources/configs.js';
|
|
20
|
-
import '../schemas/configs.js';
|
|
21
|
-
import '../resources/experiments.js';
|
|
22
|
-
import '../schemas/experiments.js';
|
|
23
|
-
import '../resources/gates.js';
|
|
24
|
-
import '../schemas/gates.js';
|
|
25
|
-
|
|
26
|
-
declare const docsOperations: Operation[];
|
|
27
|
-
|
|
28
|
-
export { docsOperations };
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
// src/transport.ts
|
|
2
|
-
var ApiError = class extends Error {
|
|
3
|
-
constructor(message, status) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.status = status;
|
|
6
|
-
this.name = "ApiError";
|
|
7
|
-
}
|
|
8
|
-
status;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
// src/operations/util.ts
|
|
12
|
-
var str = (i, k) => i[k] === void 0 ? void 0 : i[k];
|
|
13
|
-
|
|
14
|
-
// src/operations/sdk-docs.ts
|
|
15
|
-
var SDK_REPOS = {
|
|
16
|
-
typescript: { owner: "shipeasy-ai", repo: "sdk" },
|
|
17
|
-
javascript: { owner: "shipeasy-ai", repo: "sdk" },
|
|
18
|
-
node: { owner: "shipeasy-ai", repo: "sdk" },
|
|
19
|
-
ts: { owner: "shipeasy-ai", repo: "sdk" },
|
|
20
|
-
python: { owner: "shipeasy-ai", repo: "sdk-python" },
|
|
21
|
-
go: { owner: "shipeasy-ai", repo: "sdk-go" },
|
|
22
|
-
java: { owner: "shipeasy-ai", repo: "sdk-java" },
|
|
23
|
-
kotlin: { owner: "shipeasy-ai", repo: "sdk-kotlin" },
|
|
24
|
-
php: { owner: "shipeasy-ai", repo: "sdk-php" },
|
|
25
|
-
swift: { owner: "shipeasy-ai", repo: "sdk-swift" },
|
|
26
|
-
ruby: { owner: "shipeasy-ai", repo: "sdk-ruby" }
|
|
27
|
-
};
|
|
28
|
-
var SDK_ENUM = Object.keys(SDK_REPOS);
|
|
29
|
-
var DEFAULT_MANIFEST = {
|
|
30
|
-
schemaVersion: 2,
|
|
31
|
-
sdk: "default",
|
|
32
|
-
placeholders: ["RESOURCE_NAME"],
|
|
33
|
-
skill: "skill/SKILL.md",
|
|
34
|
-
pages: { overview: "pages/overview.md", installation: "pages/installation.md" },
|
|
35
|
-
snippets: { release: { flags: "snippets/release/flags.md" } }
|
|
36
|
-
};
|
|
37
|
-
var DEFAULT_CONTENT = {
|
|
38
|
-
"pages/overview.md": "# Shipeasy SDK\n\nThis SDK has not published its `/docs/` folder yet. See https://docs.shipeasy.ai for the full reference.",
|
|
39
|
-
"pages/installation.md": "# Installation\n\nInstall the Shipeasy SDK for your language, then call `shipeasy({ serverKey })` (server) or `shipeasy({ clientKey })` (browser).",
|
|
40
|
-
"snippets/release/flags.md": "```\nconst on = await client.checkGate(user, '{{RESOURCE_NAME}}');\n```",
|
|
41
|
-
"skill/SKILL.md": "---\nname: shipeasy-sdk\ndescription: Use the Shipeasy SDK for flags, experiments, configs, and i18n.\n---\n\nThis SDK has not published a skill yet. See https://docs.shipeasy.ai."
|
|
42
|
-
};
|
|
43
|
-
function repoFor(sdk) {
|
|
44
|
-
const r = SDK_REPOS[sdk.toLowerCase()];
|
|
45
|
-
if (!r) throw new ApiError(`Unknown SDK '${sdk}'. One of: ${SDK_ENUM.join(", ")}`, 400);
|
|
46
|
-
return r;
|
|
47
|
-
}
|
|
48
|
-
function pagesBase(sdk) {
|
|
49
|
-
const { owner, repo } = repoFor(sdk);
|
|
50
|
-
return `https://${owner}.github.io/${repo}`;
|
|
51
|
-
}
|
|
52
|
-
async function fetchText(url) {
|
|
53
|
-
const res = await fetch(url);
|
|
54
|
-
if (!res.ok) return null;
|
|
55
|
-
return res.text();
|
|
56
|
-
}
|
|
57
|
-
async function loadManifest(sdk) {
|
|
58
|
-
const text = await fetchText(`${pagesBase(sdk)}/manifest.json`);
|
|
59
|
-
if (!text) return { manifest: DEFAULT_MANIFEST, fallback: true };
|
|
60
|
-
try {
|
|
61
|
-
return { manifest: JSON.parse(text), fallback: false };
|
|
62
|
-
} catch {
|
|
63
|
-
return { manifest: DEFAULT_MANIFEST, fallback: true };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
function resolvePath(manifest, handle) {
|
|
67
|
-
if (handle.endsWith(".md")) return handle;
|
|
68
|
-
if (manifest.pages?.[handle]) return manifest.pages[handle];
|
|
69
|
-
if (handle.includes("/")) {
|
|
70
|
-
const [group, resource] = handle.split("/", 2);
|
|
71
|
-
const p = manifest.snippets?.[group]?.[resource];
|
|
72
|
-
if (p) return p;
|
|
73
|
-
}
|
|
74
|
-
throw new ApiError(
|
|
75
|
-
`Doc '${handle}' not found. Run 'docs list --sdk <lang>' to see available pages and snippets.`,
|
|
76
|
-
404
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
function substitute(body, manifest, i) {
|
|
80
|
-
let out = body;
|
|
81
|
-
for (const ph of manifest.placeholders ?? []) {
|
|
82
|
-
const value = str(i, ph) ?? (ph === "RESOURCE_NAME" ? str(i, "name") : void 0) ?? (ph === "FRAMEWORK" ? str(i, "framework") : void 0);
|
|
83
|
-
if (value !== void 0) out = out.replaceAll(`{{${ph}}}`, value);
|
|
84
|
-
}
|
|
85
|
-
return out;
|
|
86
|
-
}
|
|
87
|
-
var docsOperations = [
|
|
88
|
-
{
|
|
89
|
-
group: ["docs"],
|
|
90
|
-
name: "list",
|
|
91
|
-
mutates: false,
|
|
92
|
-
summary: "List an SDK's documentation tree",
|
|
93
|
-
description: "Fetch an SDK's `/docs/manifest.json` and return the doc tree \u2014 the feature-reference pages, the nested snippet groups, and whether an installable skill exists. The runtime 'explore' step before fetching a specific page or snippet.",
|
|
94
|
-
params: [{ name: "sdk", type: "string", description: "SDK language.", required: true, enum: SDK_ENUM }],
|
|
95
|
-
examples: [{ run: "shipeasy docs list --sdk python" }],
|
|
96
|
-
run: async (_client, i) => {
|
|
97
|
-
const { manifest, fallback } = await loadManifest(i.sdk);
|
|
98
|
-
return {
|
|
99
|
-
sdk: i.sdk,
|
|
100
|
-
fallback,
|
|
101
|
-
pages: Object.keys(manifest.pages ?? {}),
|
|
102
|
-
snippets: Object.fromEntries(
|
|
103
|
-
Object.entries(manifest.snippets ?? {}).map(([g, r]) => [g, Object.keys(r)])
|
|
104
|
-
),
|
|
105
|
-
skill: Boolean(manifest.skill)
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
group: ["docs"],
|
|
111
|
-
name: "get",
|
|
112
|
-
mutates: false,
|
|
113
|
-
summary: "Fetch one SDK doc page or snippet",
|
|
114
|
-
description: "Fetch one feature-reference page (`flags`, `experiments`, \u2026) or nested snippet (`release/experiments`, `i18n/setup`, \u2026) from the SDK's published docs, substituting declared {{placeholders}} from caller args. Replaces the old `get_sdk_snippet`.",
|
|
115
|
-
params: [
|
|
116
|
-
{ name: "sdk", type: "string", description: "SDK language.", required: true, enum: SDK_ENUM },
|
|
117
|
-
{ name: "path", type: "string", description: "Page key or snippet 'group/resource'.", required: true, positional: true },
|
|
118
|
-
{ name: "framework", type: "string", description: "Framework hint (substitutes {{FRAMEWORK}})." },
|
|
119
|
-
{ name: "name", type: "string", description: "Resource name (substitutes {{RESOURCE_NAME}})." }
|
|
120
|
-
],
|
|
121
|
-
examples: [
|
|
122
|
-
{ note: "A feature page", run: "shipeasy docs get --sdk python experiments" },
|
|
123
|
-
{ note: "A nested snippet, with a resource name", run: "shipeasy docs get --sdk typescript release/flags --name checkout_v2" }
|
|
124
|
-
],
|
|
125
|
-
run: async (_client, i) => {
|
|
126
|
-
const sdk = i.sdk;
|
|
127
|
-
const { manifest, fallback } = await loadManifest(sdk);
|
|
128
|
-
const path = resolvePath(manifest, i.path);
|
|
129
|
-
const body = fallback ? DEFAULT_CONTENT[path] : await fetchText(`${pagesBase(sdk)}/${path}`) ?? void 0;
|
|
130
|
-
if (body === void 0) throw new ApiError(`Doc '${path}' could not be fetched for '${sdk}'.`, 404);
|
|
131
|
-
return { sdk, path, fallback, content: substitute(body, manifest, i) };
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
group: ["docs"],
|
|
136
|
-
name: "skill",
|
|
137
|
-
mutates: false,
|
|
138
|
-
summary: "Fetch an SDK's installable LLM skill",
|
|
139
|
-
description: "Fetch the SDK's `skill/SKILL.md` (YAML frontmatter intact) so an agent can install it verbatim into its skills directory. The CLI's `--install` writes it locally (a consumer fs side-effect layered on the fetch); the op itself just returns the bytes.",
|
|
140
|
-
params: [
|
|
141
|
-
{ name: "sdk", type: "string", description: "SDK language.", required: true, enum: SDK_ENUM },
|
|
142
|
-
{ name: "install", type: "boolean", description: "CLI only: write the skill to the local agent skills dir." }
|
|
143
|
-
],
|
|
144
|
-
examples: [
|
|
145
|
-
{ run: "shipeasy docs skill --sdk python" },
|
|
146
|
-
{ note: "Install into the local skills dir", run: "shipeasy docs skill --sdk python --install true" }
|
|
147
|
-
],
|
|
148
|
-
run: async (_client, i) => {
|
|
149
|
-
const sdk = i.sdk;
|
|
150
|
-
const { manifest, fallback } = await loadManifest(sdk);
|
|
151
|
-
const skillPath = manifest.skill ?? "skill/SKILL.md";
|
|
152
|
-
const content = fallback ? DEFAULT_CONTENT[skillPath] : await fetchText(`${pagesBase(sdk)}/${skillPath}`) ?? void 0;
|
|
153
|
-
if (content === void 0) throw new ApiError(`No skill published for '${sdk}'.`, 404);
|
|
154
|
-
return { sdk, skillPath, fallback, content };
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
];
|
|
158
|
-
export {
|
|
159
|
-
docsOperations
|
|
160
|
-
};
|