@inquir/compute-cli 0.3.0 → 0.4.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 (88) hide show
  1. package/README.md +223 -114
  2. package/dist/commands/admin-tenants.d.ts +11 -0
  3. package/dist/commands/admin-tenants.d.ts.map +1 -0
  4. package/dist/commands/admin-tenants.js +318 -0
  5. package/dist/commands/admin-tenants.js.map +1 -0
  6. package/dist/commands/admin.d.ts +2 -0
  7. package/dist/commands/admin.d.ts.map +1 -0
  8. package/dist/commands/admin.js +445 -0
  9. package/dist/commands/admin.js.map +1 -0
  10. package/dist/commands/apps-describe.d.ts +9 -0
  11. package/dist/commands/apps-describe.d.ts.map +1 -0
  12. package/dist/commands/apps-describe.js +118 -0
  13. package/dist/commands/apps-describe.js.map +1 -0
  14. package/dist/commands/apps-observability.d.ts +9 -0
  15. package/dist/commands/apps-observability.d.ts.map +1 -0
  16. package/dist/commands/apps-observability.js +281 -0
  17. package/dist/commands/apps-observability.js.map +1 -0
  18. package/dist/commands/apps-promote.d.ts +31 -0
  19. package/dist/commands/apps-promote.d.ts.map +1 -0
  20. package/dist/commands/apps-promote.js +115 -0
  21. package/dist/commands/apps-promote.js.map +1 -0
  22. package/dist/commands/apps-resources.d.ts +6 -0
  23. package/dist/commands/apps-resources.d.ts.map +1 -0
  24. package/dist/commands/apps-resources.js +107 -0
  25. package/dist/commands/apps-resources.js.map +1 -0
  26. package/dist/commands/apps.d.ts +25 -2
  27. package/dist/commands/apps.d.ts.map +1 -1
  28. package/dist/commands/apps.js +434 -66
  29. package/dist/commands/apps.js.map +1 -1
  30. package/dist/commands/config.d.ts.map +1 -1
  31. package/dist/commands/config.js +7 -3
  32. package/dist/commands/config.js.map +1 -1
  33. package/dist/commands/delete.d.ts.map +1 -1
  34. package/dist/commands/delete.js +10 -2
  35. package/dist/commands/delete.js.map +1 -1
  36. package/dist/commands/login.d.ts.map +1 -1
  37. package/dist/commands/login.js +78 -33
  38. package/dist/commands/login.js.map +1 -1
  39. package/dist/commands/logout.d.ts.map +1 -1
  40. package/dist/commands/logout.js +37 -5
  41. package/dist/commands/logout.js.map +1 -1
  42. package/dist/commands/mcp.d.ts +13 -0
  43. package/dist/commands/mcp.d.ts.map +1 -1
  44. package/dist/commands/mcp.js +184 -77
  45. package/dist/commands/mcp.js.map +1 -1
  46. package/dist/commands/projects.d.ts.map +1 -1
  47. package/dist/commands/projects.js +107 -11
  48. package/dist/commands/projects.js.map +1 -1
  49. package/dist/index.js +9 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/lib/finite-source-command-client.d.ts +3 -0
  52. package/dist/lib/finite-source-command-client.d.ts.map +1 -0
  53. package/dist/lib/finite-source-command-client.js +3 -0
  54. package/dist/lib/finite-source-command-client.js.map +1 -0
  55. package/dist/lib/mcp-io.d.ts +23 -0
  56. package/dist/lib/mcp-io.d.ts.map +1 -0
  57. package/dist/lib/mcp-io.js +185 -0
  58. package/dist/lib/mcp-io.js.map +1 -0
  59. package/dist/lib/mcp-source-commands.d.ts +17 -0
  60. package/dist/lib/mcp-source-commands.d.ts.map +1 -0
  61. package/dist/lib/mcp-source-commands.js +345 -0
  62. package/dist/lib/mcp-source-commands.js.map +1 -0
  63. package/dist/utils/api.d.ts +19 -10
  64. package/dist/utils/api.d.ts.map +1 -1
  65. package/dist/utils/api.js +22 -4
  66. package/dist/utils/api.js.map +1 -1
  67. package/dist/utils/apps-presentation.d.ts +1 -1
  68. package/dist/utils/apps-presentation.d.ts.map +1 -1
  69. package/dist/utils/apps-presentation.js +10 -0
  70. package/dist/utils/apps-presentation.js.map +1 -1
  71. package/dist/utils/auth.d.ts +21 -1
  72. package/dist/utils/auth.d.ts.map +1 -1
  73. package/dist/utils/auth.js +119 -22
  74. package/dist/utils/auth.js.map +1 -1
  75. package/dist/utils/browser.d.ts +12 -0
  76. package/dist/utils/browser.d.ts.map +1 -1
  77. package/dist/utils/browser.js +37 -16
  78. package/dist/utils/browser.js.map +1 -1
  79. package/dist/utils/package-metadata.js +1 -1
  80. package/dist/utils/project-context.d.ts.map +1 -1
  81. package/dist/utils/project-context.js +7 -5
  82. package/dist/utils/project-context.js.map +1 -1
  83. package/dist/utils/project-lookup.d.ts +10 -0
  84. package/dist/utils/project-lookup.d.ts.map +1 -0
  85. package/dist/utils/project-lookup.js +52 -0
  86. package/dist/utils/project-lookup.js.map +1 -0
  87. package/package.json +10 -10
  88. package/skill/SKILL.md +9 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-observability.d.ts","sourceRoot":"","sources":["../../src/commands/apps-observability.ts"],"names":[],"mappings":"AAEA,OAAO,EAIyC,KAAK,mBAAmB,EAEvE,MAAM,WAAW,CAAC;AACnB,OAAO,EAAoD,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAO3G,eAAO,MAAM,uBAAuB,UAInC,CAAC;AACF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA6BrD,CAAC;AAqBF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,aAAa,SAAK,EAAE,GAAG,SAAa,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAuBpH;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxH;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC3H;AAsCD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CvH"}
@@ -0,0 +1,281 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { ApiError, createAppAlertRule, deleteAppAlertRule, getAppHttpLogHistory, getAppHttpMetrics, getAppLogHistory, getAppMetrics, listAppAlertIncidents, listAppAlertRules, updateAppAlertRule, } from '../sdk.js';
4
+ import { createApiClient, requireAuth, resolveApplication } from '../utils/api.js';
5
+ import { hasFlag, readFlagValue, readJsonFlag, readWorkspaceDir } from '../utils/args.js';
6
+ import { CliError, ExitCode, usageError } from '../utils/errors.js';
7
+ import { formatBytes } from '../utils/apps-presentation.js';
8
+ import { formatTable, printInfo, printLine, printSuccess } from '../utils/output.js';
9
+ import { redact, registerSecret } from '../utils/redact.js';
10
+ export const OBSERVATION_VALUE_FLAGS = [
11
+ '--since', '--from', '--to', '--release', '--replica', '--allocation-fence',
12
+ '--runner', '--runner-epoch', '--container', '--stream', '--level', '--search',
13
+ '--status', '--file',
14
+ ];
15
+ export const OBSERVATION_HELP = {
16
+ metrics: [
17
+ 'Usage: inquir apps metrics <app> [--since 1h|6h|1d|7d|30d] [--http] [--json]',
18
+ ' CPU, RAM, network and disk I/O history by release and replica; --http reads gateway requests.',
19
+ ' --from <ISO> --to <ISO> Use an explicit window (at most 30 days).',
20
+ ' --json All measured points and deployment markers; null means unavailable.',
21
+ ],
22
+ 'log-history': [
23
+ 'Usage: inquir apps log-history <app> [--since 1h] [--http] [--json]',
24
+ ' Also: inquir apps logs <app> --history [options]',
25
+ ' --from <ISO> --to <ISO> Fixed window; retain both values when using --cursor.',
26
+ ' --limit <n> --cursor <c> One page, newest first (runtime <= 200; HTTP <= 500).',
27
+ ' --release <id> Exact release id, including old releases.',
28
+ ' --replica <allocation> Runtime allocation id; --allocation-fence <n> narrows its generation.',
29
+ ' --runner <id> --runner-epoch <n> --container <id> Exact runtime identity.',
30
+ ' --stream stdout|stderr|system --level trace|debug|info|warn|error|fatal',
31
+ ' --search <text> Runtime message search; with --http, literal URL path search.',
32
+ ' --status <100..599> HTTP status filter (requires --http).',
33
+ ' Runtime retention: 7 days. HTTP retention: 30 days. This command does not follow.',
34
+ ],
35
+ alerts: [
36
+ 'Usage: inquir apps alerts <app> [list|incidents|create|update <rule-id>|delete <rule-id>]',
37
+ ' create / update --file <path|-> JSON input; - reads stdin. Destinations are write-only.',
38
+ ' list (default) / incidents Rules or incident delivery status; --json for full output.',
39
+ ' incidents --limit <1..100> Number of recent incidents (default 50).',
40
+ ' update preserves channels when omitted; channels: [] removes them.',
41
+ ' delete disables a rule and resolves its incidents; retained history remains available.',
42
+ ' Metrics: cpu_percent, memory_percent, deployment_failed. See the CLI README for rule JSON.',
43
+ ],
44
+ };
45
+ function value(args, flag) {
46
+ const result = readFlagValue(args, flag);
47
+ if (hasFlag(args, flag) && !result?.trim())
48
+ throw usageError(`Missing ${flag} value`);
49
+ return result;
50
+ }
51
+ function integer(args, flag, min, max) {
52
+ const raw = value(args, flag);
53
+ if (raw === undefined)
54
+ return undefined;
55
+ if (!/^\d+$/.test(raw) || Number(raw) < min || Number(raw) > max) {
56
+ throw usageError(`${flag} must be an integer between ${min} and ${max}`);
57
+ }
58
+ return Number(raw);
59
+ }
60
+ function choice(args, flag, choices) {
61
+ const raw = value(args, flag);
62
+ if (raw === undefined)
63
+ return undefined;
64
+ if (!choices.includes(raw))
65
+ throw usageError(`${flag} must be ${choices.join(', ')}`);
66
+ return raw;
67
+ }
68
+ export function observationRange(args, retentionDays = 30, now = Date.now()) {
69
+ const since = value(args, '--since');
70
+ const from = value(args, '--from');
71
+ const to = value(args, '--to');
72
+ if (since && (from || to))
73
+ throw usageError('Use --since or --from/--to, not both');
74
+ if (hasFlag(args, '--cursor') && (!from || !to)) {
75
+ throw usageError('--cursor requires the original --from and --to values');
76
+ }
77
+ const spans = { '1h': 3_600_000, '6h': 21_600_000, '1d': 86_400_000, '7d': 604_800_000, '30d': 2_592_000_000 };
78
+ const span = spans[since ?? '1h'];
79
+ if (span === undefined)
80
+ throw usageError('--since must be 1h, 6h, 1d, 7d or 30d');
81
+ const parse = (raw) => {
82
+ if (!/^\d{4}-\d{2}-\d{2}T.+(?:Z|[+-]\d{2}:\d{2})$/.test(raw) || !Number.isFinite(Date.parse(raw))) {
83
+ throw usageError('Dates must be ISO 8601 timestamps with a timezone');
84
+ }
85
+ return Date.parse(raw);
86
+ };
87
+ const end = to ? parse(to) : now;
88
+ const start = from ? parse(from) : end - span;
89
+ if (start >= end || end - start > retentionDays * 86_400_000 || end > now + 5000 || end < now - retentionDays * 86_400_000) {
90
+ throw usageError(`Choose a window of at most ${retentionDays} days within retained history`);
91
+ }
92
+ return { from: new Date(start).toISOString(), to: new Date(end).toISOString() };
93
+ }
94
+ export async function metricsSubcommand(args, positionals, options) {
95
+ const [identifier] = positionals;
96
+ if (!identifier || positionals.length > 1)
97
+ throw usageError('Specify one application', 'inquir apps metrics <app>');
98
+ const range = observationRange(args);
99
+ await requireAuth(options);
100
+ const app = await resolveApplication(identifier, options);
101
+ const client = await createApiClient(options);
102
+ if (hasFlag(args, '--http')) {
103
+ const result = await getAppHttpMetrics(client, app.id, range);
104
+ if (readJsonFlag(args))
105
+ return printLine(JSON.stringify(result, null, 2));
106
+ printInfo(`HTTP metrics: ${result.from} to ${result.to} (${result.status})`);
107
+ printLine(formatTable(result.points.map(point => ({
108
+ time: point.timestamp, requests: point.requests, '5xx': point.serverErrors,
109
+ 'error %': point.errorRate.toFixed(2), 'p95 ms': point.latencyP95Ms.toFixed(2),
110
+ bytes: formatBytes(point.responseBytes),
111
+ })), ['time', 'requests', '5xx', 'error %', 'p95 ms', 'bytes']));
112
+ return;
113
+ }
114
+ const result = await getAppMetrics(client, app.id, range);
115
+ if (readJsonFlag(args))
116
+ return printLine(JSON.stringify(result, null, 2));
117
+ const number = (input) => input === null ? 'unavailable' : input.toFixed(2);
118
+ printInfo(`Resource metrics: ${result.from} to ${result.to} (${result.status}); latest point per replica`);
119
+ printLine(formatTable(result.series.flatMap(series => {
120
+ const point = series.points.at(-1);
121
+ return point ? [{ release: series.releaseId, replica: series.allocationId ?? series.containerId,
122
+ time: point.sampledAt, 'CPU %': number(point.cpuPercent), 'RAM %': number(point.memoryPercent),
123
+ RAM: point.memoryWorkingSetBytes === null ? 'unavailable' : formatBytes(point.memoryWorkingSetBytes),
124
+ 'RX B/s': number(point.networkRxBytesPerSecond), 'TX B/s': number(point.networkTxBytesPerSecond),
125
+ 'read B/s': number(point.blockReadBytesPerSecond), 'write B/s': number(point.blockWriteBytesPerSecond),
126
+ }] : [];
127
+ }), ['release', 'replica', 'time', 'CPU %', 'RAM %', 'RAM', 'RX B/s', 'TX B/s', 'read B/s', 'write B/s']));
128
+ if (result.truncated)
129
+ printInfo('The server truncated this range. Narrow --from/--to for complete history.');
130
+ }
131
+ export async function logHistorySubcommand(args, positionals, options) {
132
+ const [identifier] = positionals;
133
+ if (!identifier || positionals.length > 1)
134
+ throw usageError('Specify one application', 'inquir apps log-history <app>');
135
+ if (hasFlag(args, '--follow') || hasFlag(args, '--tail'))
136
+ throw usageError('History is paginated; use apps logs <app> for a live stream');
137
+ const http = hasFlag(args, '--http');
138
+ const range = observationRange(args, http ? 30 : 7);
139
+ const common = { ...range, limit: integer(args, '--limit', 1, http ? 500 : 200) ?? 100,
140
+ cursor: value(args, '--cursor'), releaseId: value(args, '--release') };
141
+ const runtimeFlags = ['--replica', '--allocation-fence', '--runner', '--runner-epoch', '--container', '--stream', '--level'];
142
+ if (http && runtimeFlags.some(flag => hasFlag(args, flag)))
143
+ throw usageError('Replica, stream and level filters apply to runtime logs only');
144
+ if (!http && hasFlag(args, '--status'))
145
+ throw usageError('--status requires --http');
146
+ const runtimeQuery = http ? common : {
147
+ ...common, allocationId: value(args, '--replica'), allocationFence: integer(args, '--allocation-fence', 1, Number.MAX_SAFE_INTEGER),
148
+ runnerId: value(args, '--runner'), runnerEpoch: integer(args, '--runner-epoch', 0, Number.MAX_SAFE_INTEGER),
149
+ containerId: value(args, '--container'), stream: choice(args, '--stream', ['stdout', 'stderr', 'system']),
150
+ level: choice(args, '--level', ['trace', 'debug', 'info', 'warn', 'error', 'fatal']), search: value(args, '--search'),
151
+ };
152
+ if (runtimeQuery.containerId && !/^[a-f0-9]{64}$/.test(runtimeQuery.containerId))
153
+ throw usageError('--container requires the full 64-character container id');
154
+ const search = value(args, '--search');
155
+ if ((search?.length ?? 0) > 200)
156
+ throw usageError('--search must contain at most 200 characters');
157
+ const statusCode = integer(args, '--status', 100, 599);
158
+ await requireAuth(options);
159
+ const app = await resolveApplication(identifier, options);
160
+ const client = await createApiClient(options);
161
+ const result = http
162
+ ? await getAppHttpLogHistory(client, app.id, { ...common, query: search, statusCode })
163
+ : await getAppLogHistory(client, app.id, runtimeQuery);
164
+ if (readJsonFlag(args))
165
+ return printLine(redact(JSON.stringify(result, null, 2)));
166
+ for (const entry of result.entries) {
167
+ printLine('message' in entry
168
+ ? `${entry.occurredAt} ${entry.releaseId} ${entry.allocationId ?? entry.containerId} ${entry.stream} ${entry.message}`
169
+ : `${entry.occurredAt} ${entry.statusCode} ${entry.method} ${entry.path} ${entry.durationMs.toFixed(2)}ms`);
170
+ }
171
+ if (!result.entries.length)
172
+ printInfo('No logs in this window.');
173
+ if (result.nextCursor)
174
+ printInfo(`Older page: --from ${result.from} --to ${result.to} --cursor ${result.nextCursor} (keep the same filters)`);
175
+ }
176
+ async function readRuleInput(args) {
177
+ const filename = value(args, '--file');
178
+ if (!filename)
179
+ throw usageError('Provide rule JSON with --file <path|->');
180
+ const maxBytes = 64 * 1024;
181
+ let raw;
182
+ if (filename === '-') {
183
+ const parts = [];
184
+ let bytes = 0;
185
+ for await (const chunk of process.stdin) {
186
+ const part = Buffer.from(chunk);
187
+ bytes += part.length;
188
+ if (bytes > maxBytes)
189
+ throw usageError('Rule JSON must be at most 64 KiB');
190
+ parts.push(part);
191
+ }
192
+ raw = Buffer.concat(parts).toString('utf8');
193
+ }
194
+ else {
195
+ try {
196
+ raw = await readFile(path.resolve(readWorkspaceDir(args), filename), 'utf8');
197
+ }
198
+ catch {
199
+ throw usageError('Cannot read the rule JSON file');
200
+ }
201
+ }
202
+ if (Buffer.byteLength(raw) > maxBytes)
203
+ throw usageError('Rule JSON must be at most 64 KiB');
204
+ let data;
205
+ try {
206
+ data = JSON.parse(raw);
207
+ }
208
+ catch {
209
+ throw usageError('Rule file must contain valid JSON');
210
+ }
211
+ if (!data || typeof data !== 'object' || Array.isArray(data))
212
+ throw usageError('Rule JSON must be an object');
213
+ const input = data;
214
+ if (Array.isArray(input.channels))
215
+ for (const channel of input.channels) {
216
+ if (channel && typeof channel.url === 'string')
217
+ registerSecret(channel.url);
218
+ }
219
+ return input;
220
+ }
221
+ /** Extra fields from a server/proxy must never echo a write-only channel URL. */
222
+ function safeRule(rule) {
223
+ return { ...rule, channels: rule.channels.map(channel => ({ id: channel.id, type: channel.type, configured: true })) };
224
+ }
225
+ export async function alertsSubcommand(args, positionals, options) {
226
+ const [identifier, action = 'list', ruleId] = positionals;
227
+ if (!identifier || positionals.length > 3)
228
+ throw usageError('Specify an application and alert action', 'inquir apps alerts <app> --help');
229
+ if (!['list', 'incidents', 'create', 'update', 'delete'].includes(action))
230
+ throw usageError('Unknown alert action', 'inquir apps alerts <app> --help');
231
+ if (['update', 'delete'].includes(action) !== Boolean(ruleId))
232
+ throw usageError('Only update and delete require a rule id');
233
+ if (!['create', 'update'].includes(action) && hasFlag(args, '--file'))
234
+ throw usageError('--file applies to create or update only');
235
+ const limit = integer(args, '--limit', 1, 100);
236
+ const input = ['create', 'update'].includes(action) ? await readRuleInput(args) : undefined;
237
+ await requireAuth(options);
238
+ const app = await resolveApplication(identifier, options);
239
+ const client = await createApiClient(options);
240
+ try {
241
+ if (action === 'delete') {
242
+ await deleteAppAlertRule(client, app.id, ruleId);
243
+ if (readJsonFlag(args))
244
+ printLine(JSON.stringify({ deleted: true, ruleId }));
245
+ else
246
+ printSuccess(`Alert rule ${ruleId} disabled; incident history retained.`);
247
+ return;
248
+ }
249
+ if (action === 'incidents') {
250
+ const response = await listAppAlertIncidents(client, app.id, { limit: limit ?? 50 });
251
+ if (readJsonFlag(args))
252
+ printLine(JSON.stringify(response, null, 2));
253
+ else
254
+ printLine(formatTable(response.incidents.map(incident => ({
255
+ id: incident.id, rule: incident.ruleName, metric: incident.metric, status: incident.status,
256
+ started: incident.startedAt, deliveries: incident.deliveries.map(item => `${item.type}:${item.status}`).join(', '),
257
+ })), ['id', 'rule', 'metric', 'status', 'started', 'deliveries']));
258
+ return;
259
+ }
260
+ const response = action === 'create'
261
+ ? { rule: safeRule((await createAppAlertRule(client, app.id, input)).rule) }
262
+ : action === 'update'
263
+ ? { rule: safeRule((await updateAppAlertRule(client, app.id, ruleId, input)).rule) }
264
+ : { rules: (await listAppAlertRules(client, app.id)).rules.map(safeRule) };
265
+ if (readJsonFlag(args))
266
+ return printLine(redact(JSON.stringify(response, null, 2)));
267
+ const rules = response.rule ? [response.rule] : response.rules;
268
+ printLine(formatTable(rules.map(rule => ({ id: rule.id, name: rule.name, metric: rule.metric,
269
+ threshold: rule.threshold, state: rule.evaluationState, channels: rule.channels.map(item => item.type).join(', ') || 'incidents only',
270
+ })), ['id', 'name', 'metric', 'threshold', 'state', 'channels']));
271
+ }
272
+ catch (error) {
273
+ // A validation/proxy response can contain submitted webhook credentials. Keep it out of --debug too.
274
+ throw new CliError(error instanceof ApiError ? `Alert request failed (HTTP ${error.status})` : 'Alert request failed', {
275
+ code: error instanceof ApiError ? `HTTP_${error.status}` : 'ALERT_REQUEST_FAILED',
276
+ exitCode: error instanceof ApiError && [401, 403].includes(error.status) ? ExitCode.AUTH : ExitCode.ERROR,
277
+ fix: 'Check workspace access and rule fields. Notification destinations must be public HTTPS URLs.',
278
+ });
279
+ }
280
+ }
281
+ //# sourceMappingURL=apps-observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-observability.js","sourceRoot":"","sources":["../../src/commands/apps-observability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type ApiRequestOptions, type AppRollout, type PromoteAccepted } from '../utils/api.js';
2
+ /**
3
+ * A promote the server runs as a rolling rollout (K2, COMPUTE_ROLLOUT_STRATEGY
4
+ * =enforce) answers 202 and goes on in the background. The CLI follows it the
5
+ * way the old synchronous promote behaved: until production switches to the
6
+ * release (or the rollout ends without switching), printing progress.
7
+ */
8
+ export declare const PROMOTE_POLL_MS = 2000;
9
+ export interface RolloutWaitOptions {
10
+ intervalMs?: number;
11
+ /** How long to follow it; default: what the rollout's progress deadline allows, plus a minute. */
12
+ timeoutMs?: number;
13
+ sleep?: (ms: number) => Promise<void>;
14
+ now?: () => number;
15
+ onProgress?: (rollout: AppRollout) => void;
16
+ }
17
+ export type RolloutWaitResult = {
18
+ status: 'switched' | 'ended';
19
+ rollout: AppRollout;
20
+ } | {
21
+ status: 'timeout';
22
+ rollout: AppRollout | undefined;
23
+ };
24
+ /** Polls the rollout until it leaves WARMING: production switched, or the rollout ended before it could. */
25
+ export declare function waitForPromoteRollout(accepted: PromoteAccepted, apiOptions: ApiRequestOptions, options?: RolloutWaitOptions): Promise<RolloutWaitResult>;
26
+ /** `inquir apps promote` once the server answered 202. */
27
+ export declare function followPromoteRollout(releaseId: string, accepted: PromoteAccepted, flags: {
28
+ json: boolean;
29
+ wait: boolean;
30
+ }, apiOptions: ApiRequestOptions, options?: Omit<RolloutWaitOptions, 'onProgress'>): Promise<void>;
31
+ //# sourceMappingURL=apps-promote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-promote.d.ts","sourceRoot":"","sources":["../../src/commands/apps-promote.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAIzB;;;;;GAKG;AAEH,eAAO,MAAM,eAAe,OAAQ,CAAC;AAMrC,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAAA;CAAE,CAAC;AAY3D,4GAA4G;AAC5G,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,eAAe,EACzB,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAoB5B;AAOD,0DAA0D;AAC1D,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EACvC,UAAU,EAAE,iBAAiB,EAC7B,OAAO,GAAE,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAM,GACnD,OAAO,CAAC,IAAI,CAAC,CAyDf"}
@@ -0,0 +1,115 @@
1
+ import { getApplicationRollout, } from '../utils/api.js';
2
+ import { ExitCode } from '../utils/errors.js';
3
+ import { dim, printError, printInfo, printLine, printSuccess } from '../utils/output.js';
4
+ /**
5
+ * A promote the server runs as a rolling rollout (K2, COMPUTE_ROLLOUT_STRATEGY
6
+ * =enforce) answers 202 and goes on in the background. The CLI follows it the
7
+ * way the old synchronous promote behaved: until production switches to the
8
+ * release (or the rollout ends without switching), printing progress.
9
+ */
10
+ export const PROMOTE_POLL_MS = 2_000;
11
+ /** Consecutive failed polls (network, a proxy 502) tolerated before giving up. */
12
+ const MAX_POLL_FAILURES = 5;
13
+ /** When the 202 carries no figures to bound the wait by. */
14
+ const FALLBACK_WAIT_MS = 2 * 60 * 60_000;
15
+ /**
16
+ * The longest a rollout can stay before its switch: its progress deadline
17
+ * restarts with every replica that comes up, at most once per replica.
18
+ */
19
+ function defaultTimeoutMs(accepted) {
20
+ const figures = accepted.rollout;
21
+ if (!figures)
22
+ return FALLBACK_WAIT_MS;
23
+ return (Math.max(1, figures.desiredReplicas) + 1) * figures.progressDeadlineSeconds * 1000 + 60_000;
24
+ }
25
+ /** Polls the rollout until it leaves WARMING: production switched, or the rollout ended before it could. */
26
+ export async function waitForPromoteRollout(accepted, apiOptions, options = {}) {
27
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
28
+ const now = options.now ?? Date.now;
29
+ const deadline = now() + (options.timeoutMs ?? defaultTimeoutMs(accepted));
30
+ let latest = accepted.rollout;
31
+ let failures = 0;
32
+ for (;;) {
33
+ try {
34
+ latest = await getApplicationRollout(accepted.applicationId, accepted.rolloutId, apiOptions);
35
+ failures = 0;
36
+ options.onProgress?.(latest);
37
+ if (latest.phase !== 'WARMING') {
38
+ return { status: latest.flippedAt && latest.phase !== 'ROLLED_BACK' ? 'switched' : 'ended', rollout: latest };
39
+ }
40
+ }
41
+ catch (error) {
42
+ if (++failures >= MAX_POLL_FAILURES)
43
+ throw error;
44
+ }
45
+ if (now() >= deadline)
46
+ return { status: 'timeout', rollout: latest };
47
+ await sleep(options.intervalMs ?? PROMOTE_POLL_MS);
48
+ }
49
+ }
50
+ function progressLine(rollout) {
51
+ return ` ${rollout.observedHealthy} of ${rollout.desiredReplicas} replicas serve; ` +
52
+ `production switches at ${rollout.flipAtReplicas}`;
53
+ }
54
+ /** `inquir apps promote` once the server answered 202. */
55
+ export async function followPromoteRollout(releaseId, accepted, flags, apiOptions, options = {}) {
56
+ const short = releaseId.slice(0, 8);
57
+ if (!flags.wait) {
58
+ if (flags.json) {
59
+ printLine(JSON.stringify(accepted, null, 2));
60
+ return;
61
+ }
62
+ printInfo(`Rolling out ${short}: production switches once enough replicas serve`);
63
+ printInfo(dim(` it goes on on the server; follow it: GET ${accepted.pollUrl}`));
64
+ return;
65
+ }
66
+ if (!flags.json) {
67
+ printInfo(`Rolling out ${short}: production switches once enough replicas serve`);
68
+ if (accepted.rollout)
69
+ printInfo(dim(progressLine(accepted.rollout)));
70
+ }
71
+ let shown = accepted.rollout?.observedHealthy ?? -1;
72
+ const result = await waitForPromoteRollout(accepted, apiOptions, {
73
+ ...options,
74
+ onProgress: (rollout) => {
75
+ if (flags.json || rollout.phase !== 'WARMING' || rollout.observedHealthy === shown)
76
+ return;
77
+ shown = rollout.observedHealthy;
78
+ printInfo(dim(progressLine(rollout)));
79
+ },
80
+ });
81
+ if (flags.json) {
82
+ printLine(JSON.stringify({ ...accepted, status: result.rollout?.phase ?? accepted.status, rollout: result.rollout ?? null,
83
+ servingProduction: result.status === 'switched' }, null, 2));
84
+ if (result.status !== 'switched')
85
+ process.exitCode = ExitCode.ERROR;
86
+ return;
87
+ }
88
+ if (result.status === 'timeout') {
89
+ printError(`Release ${short} has not taken production yet; the CLI stopped waiting, the rollout goes on. ` +
90
+ `Follow it: GET ${accepted.pollUrl}`);
91
+ process.exitCode = ExitCode.ERROR;
92
+ return;
93
+ }
94
+ const { rollout } = result;
95
+ if (result.status === 'ended') {
96
+ printError(`Rollout ${rollout.phase.toLowerCase().replace('_', ' ')}: ${rollout.reason ?? 'production did not switch'}`);
97
+ process.exitCode = ExitCode.ERROR;
98
+ return;
99
+ }
100
+ printSuccess(`Production now serves ${short}`);
101
+ if (rollout.phase === 'PROGRESSING') {
102
+ printInfo(dim(` ${rollout.observedHealthy} of ${rollout.desiredReplicas} replicas serve; the rest roll out in the background`));
103
+ }
104
+ if (rollout.predecessorReleaseId && rollout.phase !== 'COMPLETE') {
105
+ printInfo(dim(` previous release ${rollout.predecessorReleaseId.slice(0, 8)} is kept running as the rollback until then`));
106
+ }
107
+ else if (rollout.predecessorReleaseId) {
108
+ printInfo(dim(` previous release ${rollout.predecessorReleaseId.slice(0, 8)} kept for rollback`));
109
+ }
110
+ if (rollout.phase === 'FAILED') {
111
+ printError(` ${rollout.reason ?? 'the rollout stopped making progress'}`);
112
+ process.exitCode = ExitCode.ERROR;
113
+ }
114
+ }
115
+ //# sourceMappingURL=apps-promote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-promote.js","sourceRoot":"","sources":["../../src/commands/apps-promote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type ApiRequestOptions } from '../utils/api.js';
2
+ export declare const RESOURCES_VALUE_FLAGS: string[];
3
+ export declare const RESOURCES_HELP: Record<string, string[]>;
4
+ /** `apps resources recommend <app>`: the only action today; applying stays an explicit update. */
5
+ export declare function resourcesSubcommand(args: string[], positionals: string[], options: ApiRequestOptions): Promise<void>;
6
+ //# sourceMappingURL=apps-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-resources.d.ts","sourceRoot":"","sources":["../../src/commands/apps-resources.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoD,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAM3G,eAAO,MAAM,qBAAqB,UAAa,CAAC;AAChD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAUnD,CAAC;AAcF,kGAAkG;AAClG,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1H"}
@@ -0,0 +1,107 @@
1
+ import { getAppResourceRecommendation, } from '../sdk.js';
2
+ import { createApiClient, requireAuth, resolveApplication } from '../utils/api.js';
3
+ import { hasFlag, readFlagValue, readJsonFlag } from '../utils/args.js';
4
+ import { usageError } from '../utils/errors.js';
5
+ import { formatTable, printInfo, printLine } from '../utils/output.js';
6
+ const MAX_DAYS = 7;
7
+ export const RESOURCES_VALUE_FLAGS = ['--days'];
8
+ export const RESOURCES_HELP = {
9
+ resources: [
10
+ 'Usage: inquir apps resources recommend <app> [--days 1-7] [--json]',
11
+ ' Read-only CPU/RAM right-sizing from what the containers used. Memory: 1.2 x the peak working',
12
+ ' set, at least 64 MB (256 MB for a database) and never below the 30-day peak + 10%. CPU: the',
13
+ ' limit follows the peak, the reserved request the 95th percentile. Needs 24 h of data.',
14
+ ' Nothing changes until you apply it: apps update <app> --memory <mb> --cpu <vcpus>, then redeploy.',
15
+ ' --days <n> Window in days (default 7)',
16
+ ' --json Everything, including each release (replica set) seen in the window',
17
+ ],
18
+ };
19
+ function readDays(args) {
20
+ const raw = readFlagValue(args, '--days');
21
+ if (raw === undefined) {
22
+ if (hasFlag(args, '--days'))
23
+ throw usageError('Missing --days value', 'inquir apps resources recommend <app> --days 7');
24
+ return undefined;
25
+ }
26
+ if (!/^\d+$/.test(raw) || Number(raw) < 1 || Number(raw) > MAX_DAYS) {
27
+ throw usageError(`--days must be a whole number from 1 to ${MAX_DAYS}`, 'inquir apps resources recommend <app> --days 7');
28
+ }
29
+ return Number(raw);
30
+ }
31
+ /** `apps resources recommend <app>`: the only action today; applying stays an explicit update. */
32
+ export async function resourcesSubcommand(args, positionals, options) {
33
+ const [action, identifier, ...extra] = positionals;
34
+ if (action !== 'recommend') {
35
+ throw usageError(action ? `Unknown apps resources action: ${action}` : 'Missing apps resources action', 'inquir apps resources recommend <app>');
36
+ }
37
+ if (!identifier || extra.length > 0)
38
+ throw usageError('Specify one application', 'inquir apps resources recommend <app>');
39
+ const days = readDays(args);
40
+ await requireAuth(options);
41
+ const app = await resolveApplication(identifier, options);
42
+ const client = await createApiClient(options);
43
+ const result = await getAppResourceRecommendation(client, app.id, days === undefined ? {} : { days });
44
+ if (readJsonFlag(args))
45
+ return printLine(JSON.stringify(result, null, 2));
46
+ printRecommendation(app.name || identifier, result);
47
+ }
48
+ const mb = (value) => value === null ? '-' : `${value} MB`;
49
+ const cores = (value) => value === null ? '-' : `${value} cores`;
50
+ const vcpus = (value) => value === null ? '-' : `${value} vCPU`;
51
+ const millis = (value) => value === null ? '-' : `${value} m`;
52
+ const DECIDED_BY = {
53
+ headroom: '1.2 x peak',
54
+ minimum: 'the 64 MB minimum',
55
+ database: 'the 256 MB database floor',
56
+ declared: 'the floor the runtime spec declares',
57
+ retained_max: 'the 30-day peak + 10%',
58
+ maximum: 'the 8192 MB maximum',
59
+ };
60
+ function printRecommendation(name, result) {
61
+ const { recommendation: rec } = result;
62
+ const window = `${result.window.days} day${result.window.days === 1 ? '' : 's'}`;
63
+ if (rec.status !== 'ok') {
64
+ printInfo(rec.status === 'no_data'
65
+ ? `No resource measurements for ${name}'s production replicas in the last ${window}.`
66
+ : `Not enough data for ${name} yet: ${rec.confidence.coverageDays} of the 1 day of observed usage a recommendation needs (last ${window}).`);
67
+ }
68
+ else {
69
+ printInfo(`Right-sizing for ${name}, last ${window}: confidence ${rec.confidence.level} ` +
70
+ `(${rec.confidence.coverageDays} days observed, ${rec.confidence.samples} samples)`);
71
+ printLine(formatTable(rows(rec), ['resource', 'current', 'recommended', 'observed']));
72
+ if (rec.memory.decidedBy)
73
+ printInfo(`Memory decided by ${DECIDED_BY[rec.memory.decidedBy] ?? rec.memory.decidedBy}.`);
74
+ if (rec.savings) {
75
+ const replicas = `${rec.savings.replicas} replica${rec.savings.replicas === 1 ? '' : 's'}`;
76
+ const cpu = rec.savings.cpuRequestMillis === null ? '' : ` and ${rec.savings.cpuRequestMillis} mCPU`;
77
+ printInfo(`${rec.savings.memoryMb >= 0 ? 'Frees' : 'Needs'} ${Math.abs(rec.savings.memoryMb)} MB${cpu} of reservation across ${replicas}.`);
78
+ }
79
+ if (rec.memory.recommendedMb !== null && rec.cpu.recommendedLimitVCpus !== null) {
80
+ printInfo(`Apply (nothing changes until you do): inquir apps update ${name} --memory ${rec.memory.recommendedMb} ` +
81
+ `--cpu ${rec.cpu.recommendedLimitVCpus}, then inquir apps redeploy ${name}`);
82
+ }
83
+ }
84
+ if (result.replicaSets.length > 0) {
85
+ printInfo('Replica sets (releases) in the window:');
86
+ printLine(formatTable(result.replicaSets.map((set) => ({
87
+ release: `${set.releaseId}${set.production ? ' (production)' : ''}`,
88
+ status: set.releaseStatus,
89
+ 'current MB': set.memory.currentMb,
90
+ 'peak MB': set.memory.maxObservedMb ?? '-',
91
+ 'recommended MB': set.memory.recommendedMb ?? '-',
92
+ 'p95 cores': set.cpu.p95Cores ?? '-',
93
+ confidence: set.status === 'ok' ? set.confidence.level : set.status,
94
+ })), ['release', 'status', 'current MB', 'peak MB', 'recommended MB', 'p95 cores', 'confidence']));
95
+ }
96
+ }
97
+ function rows(rec) {
98
+ return [
99
+ { resource: 'memory', current: mb(rec.memory.currentMb), recommended: mb(rec.memory.recommendedMb),
100
+ observed: `peak ${mb(rec.memory.maxObservedMb)}, mean ${mb(rec.memory.avgObservedMb)}` },
101
+ { resource: 'CPU limit', current: vcpus(rec.cpu.currentLimitVCpus), recommended: vcpus(rec.cpu.recommendedLimitVCpus),
102
+ observed: `peak ${cores(rec.cpu.maxCores)}` },
103
+ { resource: 'CPU request', current: millis(rec.cpu.currentRequestMillis), recommended: millis(rec.cpu.recommendedRequestMillis),
104
+ observed: `p95 ${cores(rec.cpu.p95Cores)} (alone: ${millis(rec.cpu.suggestedRequestMillis)})` },
105
+ ];
106
+ }
107
+ //# sourceMappingURL=apps-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-resources.js","sourceRoot":"","sources":["../../src/commands/apps-resources.ts"],"names":[],"mappings":"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"}