biaws 0.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 (76) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +229 -0
  3. package/bin/biaws.js +3 -0
  4. package/docs/command-taxonomy.md +36 -0
  5. package/docs/instance-lifecycle.md +82 -0
  6. package/docs/releasing.md +105 -0
  7. package/package.json +63 -0
  8. package/shared/skillPackage.js +100 -0
  9. package/src/apiClient.js +89 -0
  10. package/src/baseCommands.js +122 -0
  11. package/src/commands/agent/configure.js +3 -0
  12. package/src/commands/agent/doctor.js +3 -0
  13. package/src/commands/agent.js +400 -0
  14. package/src/commands/api.js +17 -0
  15. package/src/commands/applications/get.js +17 -0
  16. package/src/commands/applications/list.js +32 -0
  17. package/src/commands/applications.js +7 -0
  18. package/src/commands/configure/claude.js +25 -0
  19. package/src/commands/configure/codex.js +25 -0
  20. package/src/commands/configure/doctor.js +49 -0
  21. package/src/commands/configure/skills.js +74 -0
  22. package/src/commands/configure.js +19 -0
  23. package/src/commands/demands/complete-task.js +6 -0
  24. package/src/commands/demands/get.js +16 -0
  25. package/src/commands/demands/list.js +48 -0
  26. package/src/commands/demands/task-status.js +49 -0
  27. package/src/commands/demands/tasks.js +44 -0
  28. package/src/commands/demands.js +7 -0
  29. package/src/commands/instance/backup.js +74 -0
  30. package/src/commands/instance/list.js +39 -0
  31. package/src/commands/instance/remove.js +72 -0
  32. package/src/commands/instance/restore.js +96 -0
  33. package/src/commands/instance/setup.js +349 -0
  34. package/src/commands/instance/show.js +31 -0
  35. package/src/commands/instance/start.js +32 -0
  36. package/src/commands/instance/status.js +42 -0
  37. package/src/commands/instance/stop.js +30 -0
  38. package/src/commands/instance.js +18 -0
  39. package/src/commands/issues/get.js +16 -0
  40. package/src/commands/issues/list.js +51 -0
  41. package/src/commands/issues/transition.js +33 -0
  42. package/src/commands/issues.js +7 -0
  43. package/src/commands/monitoring/describe.js +13 -0
  44. package/src/commands/monitoring/signal.js +25 -0
  45. package/src/commands/monitoring/signals.js +17 -0
  46. package/src/commands/monitoring/validate.js +14 -0
  47. package/src/commands/monitoring.js +163 -0
  48. package/src/commands/skills/install-all.js +13 -0
  49. package/src/commands/skills/install.js +16 -0
  50. package/src/commands/skills/list.js +5 -0
  51. package/src/commands/skills/publish-all.js +14 -0
  52. package/src/commands/skills/publish.js +11 -0
  53. package/src/commands/skills/status.js +7 -0
  54. package/src/commands/skills/update.js +12 -0
  55. package/src/commands/skills.js +303 -0
  56. package/src/commands/workspaces/get.js +15 -0
  57. package/src/commands/workspaces/list.js +20 -0
  58. package/src/commands/workspaces.js +7 -0
  59. package/src/compatibilityCommands.js +107 -0
  60. package/src/configure/command.js +50 -0
  61. package/src/core/context.js +162 -0
  62. package/src/core/errors.js +25 -0
  63. package/src/core/processRunner.js +119 -0
  64. package/src/core/prompts.js +138 -0
  65. package/src/core/redaction.js +29 -0
  66. package/src/core/terminal.js +72 -0
  67. package/src/core/wizard.js +279 -0
  68. package/src/domain/readCommand.js +65 -0
  69. package/src/domain/readService.js +126 -0
  70. package/src/domain/writeCommand.js +91 -0
  71. package/src/domain/writeService.js +122 -0
  72. package/src/index.js +5 -0
  73. package/src/instance/command.js +37 -0
  74. package/src/instance/service.js +515 -0
  75. package/src/localSkills.js +143 -0
  76. package/src/skillPackage.js +4 -0
@@ -0,0 +1,349 @@
1
+ import { Flags } from "@oclif/core";
2
+
3
+ import { LocalInstanceCommand } from "../../baseCommands.js";
4
+ import {
5
+ buildExecutionPlan,
6
+ executeExecutionPlan,
7
+ summarizeExecutionPlan,
8
+ wizardFlags,
9
+ } from "../../core/wizard.js";
10
+ import {
11
+ contextFlags,
12
+ contextInput,
13
+ writeResult,
14
+ } from "../../instance/command.js";
15
+ import {
16
+ buildSetupConfiguration,
17
+ executeSetup,
18
+ validateInstanceName,
19
+ validatePort,
20
+ validatePublicUrl,
21
+ } from "../../instance/service.js";
22
+
23
+ const setupFlags = {
24
+ ...contextFlags,
25
+ ...wizardFlags,
26
+ name: Flags.string({ char: "n", description: "nome da instância" }),
27
+ "admin-email": Flags.string({
28
+ description: "e-mail do administrador inicial",
29
+ }),
30
+ "admin-name": Flags.string({ description: "nome do administrador inicial" }),
31
+ "public-url": Flags.string({ description: "origem pública HTTP(S) da UI" }),
32
+ "mongo-port": Flags.integer({ description: "porta externa do MongoDB" }),
33
+ "api-port": Flags.integer({ description: "porta externa da API" }),
34
+ "ui-port": Flags.integer({ description: "porta externa da UI" }),
35
+ storage: Flags.string({
36
+ options: ["volumes", "directories"],
37
+ description: "estratégia de storage",
38
+ }),
39
+ "storage-root": Flags.string({
40
+ description: "raiz dos diretórios persistentes",
41
+ }),
42
+ "mongo-path": Flags.string({
43
+ description: "diretório persistente do MongoDB",
44
+ }),
45
+ "issue-path": Flags.string({
46
+ description: "diretório persistente de issues",
47
+ }),
48
+ "request-path": Flags.string({
49
+ description: "diretório persistente de melhorias",
50
+ }),
51
+ "document-path": Flags.string({
52
+ description: "diretório persistente de documentos",
53
+ }),
54
+ "secret-path": Flags.string({
55
+ description: "diretório persistente do cofre",
56
+ }),
57
+ "demo-seed": Flags.boolean({
58
+ allowNo: true,
59
+ description: "carrega dados de demonstração",
60
+ }),
61
+ "disable-rate-limit": Flags.boolean({
62
+ description: "desabilita todas as camadas de rate limit",
63
+ }),
64
+ "api-rate-limit-max": Flags.integer({
65
+ description: "requisições por janela da API",
66
+ }),
67
+ "api-rate-limit-window": Flags.integer({
68
+ description: "janela da API em segundos",
69
+ }),
70
+ "auth-rate-limit-max": Flags.integer({
71
+ description: "requisições por janela de autenticação",
72
+ }),
73
+ "auth-rate-limit-window": Flags.integer({
74
+ description: "janela de autenticação em segundos",
75
+ }),
76
+ "api-key-rate-limit-max": Flags.integer({
77
+ description: "requisições por janela de API key",
78
+ }),
79
+ "api-key-rate-limit-window": Flags.integer({
80
+ description: "janela de API key em segundos",
81
+ }),
82
+ };
83
+
84
+ const definition = {
85
+ kind: "instance.setup",
86
+ questions: [
87
+ {
88
+ name: "name",
89
+ type: "input",
90
+ message: "Nome da instância",
91
+ environment: "BIAWS_INSTANCE",
92
+ validate: (value) => {
93
+ validateInstanceName(value);
94
+ return true;
95
+ },
96
+ },
97
+ {
98
+ name: "adminEmail",
99
+ flag: "admin-email",
100
+ type: "input",
101
+ message: "E-mail do administrador",
102
+ default: "admin@example.com",
103
+ validate: (value) =>
104
+ /^\S+@\S+\.\S+$/u.test(value) || "E-mail administrativo inválido.",
105
+ },
106
+ {
107
+ name: "adminName",
108
+ flag: "admin-name",
109
+ type: "input",
110
+ message: "Nome do administrador",
111
+ default: "Administrador",
112
+ },
113
+ {
114
+ name: "adminPassword",
115
+ type: "password",
116
+ message: "Senha inicial do administrador",
117
+ environment: "BIAWS_BOOTSTRAP_ADMIN_PASSWORD",
118
+ secret: true,
119
+ },
120
+ {
121
+ name: "uiPort",
122
+ flag: "ui-port",
123
+ type: "number",
124
+ message: "Porta da UI",
125
+ default: 4400,
126
+ validate: (value) => {
127
+ validatePort(value, "Porta UI");
128
+ return true;
129
+ },
130
+ },
131
+ {
132
+ name: "apiPort",
133
+ flag: "api-port",
134
+ type: "number",
135
+ message: "Porta da API",
136
+ default: 3100,
137
+ validate: (value) => {
138
+ validatePort(value, "Porta API");
139
+ return true;
140
+ },
141
+ },
142
+ {
143
+ name: "mongoPort",
144
+ flag: "mongo-port",
145
+ type: "number",
146
+ message: "Porta do MongoDB",
147
+ default: 27017,
148
+ validate: (value) => {
149
+ validatePort(value, "Porta MongoDB");
150
+ return true;
151
+ },
152
+ },
153
+ {
154
+ name: "publicUrl",
155
+ flag: "public-url",
156
+ type: "input",
157
+ message: "URL pública",
158
+ default: (values) => `http://localhost:${values.uiPort}`,
159
+ validate: (value) => {
160
+ validatePublicUrl(value);
161
+ return true;
162
+ },
163
+ },
164
+ {
165
+ name: "storage",
166
+ type: "select",
167
+ message: "Estratégia de storage",
168
+ choices: [
169
+ { name: "Volumes Docker", value: "volumes" },
170
+ { name: "Diretórios no host", value: "directories" },
171
+ ],
172
+ default: "volumes",
173
+ },
174
+ {
175
+ name: "storageRoot",
176
+ flag: "storage-root",
177
+ type: "input",
178
+ message: "Raiz de storage",
179
+ required: false,
180
+ when: (values) => values.storage === "directories",
181
+ },
182
+ {
183
+ name: "mongoPath",
184
+ flag: "mongo-path",
185
+ type: "input",
186
+ message: "Diretório MongoDB",
187
+ required: false,
188
+ when: (values) => values.storage === "directories",
189
+ },
190
+ {
191
+ name: "issuePath",
192
+ flag: "issue-path",
193
+ type: "input",
194
+ message: "Diretório de issues",
195
+ required: false,
196
+ when: (values) => values.storage === "directories",
197
+ },
198
+ {
199
+ name: "requestPath",
200
+ flag: "request-path",
201
+ type: "input",
202
+ message: "Diretório de melhorias",
203
+ required: false,
204
+ when: (values) => values.storage === "directories",
205
+ },
206
+ {
207
+ name: "documentPath",
208
+ flag: "document-path",
209
+ type: "input",
210
+ message: "Diretório de documentos",
211
+ required: false,
212
+ when: (values) => values.storage === "directories",
213
+ },
214
+ {
215
+ name: "secretPath",
216
+ flag: "secret-path",
217
+ type: "input",
218
+ message: "Diretório do cofre",
219
+ required: false,
220
+ when: (values) => values.storage === "directories",
221
+ },
222
+ {
223
+ name: "apiRateLimitMax",
224
+ flag: "api-rate-limit-max",
225
+ type: "number",
226
+ message: "Rate limit da API",
227
+ default: 300,
228
+ },
229
+ {
230
+ name: "apiRateLimitWindow",
231
+ flag: "api-rate-limit-window",
232
+ type: "number",
233
+ message: "Janela da API (s)",
234
+ default: 60,
235
+ },
236
+ {
237
+ name: "authRateLimitMax",
238
+ flag: "auth-rate-limit-max",
239
+ type: "number",
240
+ message: "Rate limit de autenticação",
241
+ default: 100,
242
+ },
243
+ {
244
+ name: "authRateLimitWindow",
245
+ flag: "auth-rate-limit-window",
246
+ type: "number",
247
+ message: "Janela de autenticação (s)",
248
+ default: 10,
249
+ },
250
+ {
251
+ name: "apiKeyRateLimitMax",
252
+ flag: "api-key-rate-limit-max",
253
+ type: "number",
254
+ message: "Rate limit de API key",
255
+ default: 1000,
256
+ },
257
+ {
258
+ name: "apiKeyRateLimitWindow",
259
+ flag: "api-key-rate-limit-window",
260
+ type: "number",
261
+ message: "Janela de API key (s)",
262
+ default: 3600,
263
+ },
264
+ {
265
+ name: "disableRateLimit",
266
+ flag: "disable-rate-limit",
267
+ type: "confirm",
268
+ message: "Desabilitar rate limiting?",
269
+ default: false,
270
+ },
271
+ {
272
+ name: "demoSeed",
273
+ flag: "demo-seed",
274
+ type: "confirm",
275
+ message: "Carregar dados de demonstração?",
276
+ default: false,
277
+ },
278
+ ],
279
+ };
280
+
281
+ export default class InstanceSetup extends LocalInstanceCommand {
282
+ static description =
283
+ "cria ou reconcilia uma instância local por plano idempotente";
284
+ static examples = [
285
+ "<%= config.bin %> instance setup --interactive",
286
+ "BIAWS_BOOTSTRAP_ADMIN_PASSWORD=... <%= config.bin %> instance setup --name local --defaults --yes --non-interactive",
287
+ ];
288
+ static flags = setupFlags;
289
+
290
+ async run() {
291
+ const { flags } = await this.parse(InstanceSetup);
292
+ const context = await this.localContext(contextInput(flags, flags.name));
293
+ const plan = await buildExecutionPlan(definition, {
294
+ environment: this.adapters.environment,
295
+ flags,
296
+ options: flags,
297
+ promptAdapter: this.adapters.prompts,
298
+ terminal: this.adapters.terminal,
299
+ });
300
+ const configuration = await buildSetupConfiguration(
301
+ Object.fromEntries(
302
+ definition.questions.map((question) => [
303
+ question.name,
304
+ plan.get(question.name),
305
+ ]),
306
+ ),
307
+ context,
308
+ this.adapters.filesystem,
309
+ );
310
+ if (configuration.storageChanged) {
311
+ this.output().diagnostic(
312
+ "Aviso: o storage mudou; dados existentes não serão movidos automaticamente.",
313
+ );
314
+ }
315
+ this.output().diagnostic(
316
+ `Plano validado: ${JSON.stringify(summarizeExecutionPlan(plan))}`,
317
+ );
318
+ const result = await executeExecutionPlan(
319
+ plan,
320
+ () =>
321
+ executeSetup(
322
+ configuration,
323
+ context,
324
+ this.adapters.processRunner,
325
+ this.adapters.environment,
326
+ { silent: flags.json },
327
+ ),
328
+ {
329
+ options: flags,
330
+ promptAdapter: this.adapters.prompts,
331
+ terminal: this.adapters.terminal,
332
+ },
333
+ );
334
+ writeResult(
335
+ this,
336
+ result,
337
+ (value) =>
338
+ [
339
+ "Configuração concluída.",
340
+ `Instância: ${value.name}`,
341
+ `UI: ${value.ui}`,
342
+ `API: ${value.api}`,
343
+ `MongoDB: ${value.mongo}`,
344
+ `Status: ${value.commands.status}`,
345
+ ].join("\n"),
346
+ flags.json,
347
+ );
348
+ }
349
+ }
@@ -0,0 +1,31 @@
1
+ import { Flags } from "@oclif/core";
2
+
3
+ import { LocalInstanceCommand } from "../../baseCommands.js";
4
+ import {
5
+ contextFlags,
6
+ contextInput,
7
+ instanceArgument,
8
+ instanceSummary,
9
+ writeResult,
10
+ } from "../../instance/command.js";
11
+ import { getInstance } from "../../instance/service.js";
12
+
13
+ export default class InstanceShow extends LocalInstanceCommand {
14
+ static description = "exibe a configuração não sensível de uma instância";
15
+ static args = { instance: instanceArgument };
16
+ static flags = {
17
+ ...contextFlags,
18
+ json: Flags.boolean({ description: "emite JSON" }),
19
+ };
20
+
21
+ async run() {
22
+ const { args, flags } = await this.parse(InstanceShow);
23
+ const context = await this.localContext(contextInput(flags, args.instance));
24
+ const { env, ...instance } = await getInstance(
25
+ context,
26
+ this.adapters.filesystem,
27
+ args.instance,
28
+ );
29
+ writeResult(this, instance, instanceSummary, flags.json);
30
+ }
31
+ }
@@ -0,0 +1,32 @@
1
+ import { LocalInstanceCommand } from "../../baseCommands.js";
2
+ import {
3
+ contextFlags,
4
+ contextInput,
5
+ instanceArgument,
6
+ } from "../../instance/command.js";
7
+ import { getInstance, operateInstance } from "../../instance/service.js";
8
+
9
+ export default class InstanceStart extends LocalInstanceCommand {
10
+ static description = "inicia os serviços de uma instância e aguarda saúde";
11
+ static args = { instance: instanceArgument };
12
+ static flags = contextFlags;
13
+
14
+ async run() {
15
+ const { args, flags } = await this.parse(InstanceStart);
16
+ const context = await this.localContext(contextInput(flags, args.instance));
17
+ const instance = await getInstance(
18
+ context,
19
+ this.adapters.filesystem,
20
+ args.instance,
21
+ );
22
+ await operateInstance(
23
+ instance,
24
+ context,
25
+ this.adapters.processRunner,
26
+ "start",
27
+ );
28
+ this.output().result(
29
+ `Instância ${instance.name} iniciada. UI: ${instance.publicUrl}`,
30
+ );
31
+ }
32
+ }
@@ -0,0 +1,42 @@
1
+ import { Flags } from "@oclif/core";
2
+
3
+ import { LocalInstanceCommand } from "../../baseCommands.js";
4
+ import {
5
+ contextFlags,
6
+ contextInput,
7
+ instanceArgument,
8
+ writeResult,
9
+ } from "../../instance/command.js";
10
+ import { getInstance, operateInstance } from "../../instance/service.js";
11
+
12
+ export default class InstanceStatus extends LocalInstanceCommand {
13
+ static description = "consulta o estado dos containers de uma instância";
14
+ static args = { instance: instanceArgument };
15
+ static flags = {
16
+ ...contextFlags,
17
+ json: Flags.boolean({ description: "emite JSON" }),
18
+ };
19
+
20
+ async run() {
21
+ const { args, flags } = await this.parse(InstanceStatus);
22
+ const context = await this.localContext(contextInput(flags, args.instance));
23
+ const instance = await getInstance(
24
+ context,
25
+ this.adapters.filesystem,
26
+ args.instance,
27
+ );
28
+ const result = await operateInstance(
29
+ instance,
30
+ context,
31
+ this.adapters.processRunner,
32
+ "status",
33
+ );
34
+ writeResult(
35
+ this,
36
+ result,
37
+ (value) =>
38
+ value.output || `Nenhum container ativo para ${value.instance}.`,
39
+ flags.json,
40
+ );
41
+ }
42
+ }
@@ -0,0 +1,30 @@
1
+ import { LocalInstanceCommand } from "../../baseCommands.js";
2
+ import {
3
+ contextFlags,
4
+ contextInput,
5
+ instanceArgument,
6
+ } from "../../instance/command.js";
7
+ import { getInstance, operateInstance } from "../../instance/service.js";
8
+
9
+ export default class InstanceStop extends LocalInstanceCommand {
10
+ static description = "para os serviços de uma instância sem remover dados";
11
+ static args = { instance: instanceArgument };
12
+ static flags = contextFlags;
13
+
14
+ async run() {
15
+ const { args, flags } = await this.parse(InstanceStop);
16
+ const context = await this.localContext(contextInput(flags, args.instance));
17
+ const instance = await getInstance(
18
+ context,
19
+ this.adapters.filesystem,
20
+ args.instance,
21
+ );
22
+ await operateInstance(
23
+ instance,
24
+ context,
25
+ this.adapters.processRunner,
26
+ "stop",
27
+ );
28
+ this.output().result(`Instância ${instance.name} parada.`);
29
+ }
30
+ }
@@ -0,0 +1,18 @@
1
+ import { Help } from "@oclif/core";
2
+
3
+ import { LocalInstanceCommand } from "../baseCommands.js";
4
+
5
+ export default class Instance extends LocalInstanceCommand {
6
+ static description =
7
+ "Instala, configura e opera instâncias locais do Bondia Workspaces";
8
+ static examples = [
9
+ "<%= config.bin %> instance setup",
10
+ "<%= config.bin %> instance status",
11
+ "<%= config.bin %> instance backup",
12
+ ];
13
+
14
+ async run() {
15
+ await this.parse(Instance);
16
+ await new Help(this.config).showHelp(["instance"]);
17
+ }
18
+ }
@@ -0,0 +1,16 @@
1
+ import { Args } from "@oclif/core";
2
+ import { connectionFlags, ReadCommand } from "../../domain/readCommand.js";
3
+ export default class IssueGet extends ReadCommand {
4
+ static description = "Obtém uma issue por ID ou código";
5
+ static args = { id: Args.string({ required: true }) };
6
+ static flags = connectionFlags;
7
+ async run() {
8
+ const { args, flags } = await this.parse(IssueGet);
9
+ const result = await this.read(flags, (api) => api.issue(args.id), {
10
+ resource: "issue",
11
+ operation: "get",
12
+ requireWorkspace: true,
13
+ });
14
+ this.emit(flags, result, (p) => JSON.stringify(p.issue || p, null, 2));
15
+ }
16
+ }
@@ -0,0 +1,51 @@
1
+ import { Flags } from "@oclif/core";
2
+ import {
3
+ connectionFlags,
4
+ listFlags,
5
+ ReadCommand,
6
+ } from "../../domain/readCommand.js";
7
+ import { table } from "../../domain/readService.js";
8
+ export default class IssueList extends ReadCommand {
9
+ static description = "Lista issues no escopo informado";
10
+ static flags = {
11
+ ...connectionFlags,
12
+ ...listFlags,
13
+ application: Flags.string({ description: "ID da aplicação" }),
14
+ component: Flags.string({ description: "ID do componente" }),
15
+ severity: Flags.string({ description: "filtra por severidade" }),
16
+ };
17
+ async run() {
18
+ const { flags } = await this.parse(IssueList);
19
+ const result = await this.read(
20
+ flags,
21
+ (api, c) =>
22
+ api.issues({
23
+ workspaceId: c.workspaceId,
24
+ applicationId: flags.application,
25
+ componentId: flags.component,
26
+ status: flags.status,
27
+ severity: flags.severity,
28
+ q: flags.search,
29
+ page: flags.page,
30
+ limit: flags.limit,
31
+ }),
32
+ {
33
+ resource: "issues",
34
+ operation: "list",
35
+ requireWorkspace: true,
36
+ scope: (c) => ({
37
+ workspaceId: c.workspaceId,
38
+ applicationId: flags.application,
39
+ }),
40
+ },
41
+ );
42
+ this.emit(flags, result, (p) =>
43
+ table(p.items || [], [
44
+ ["ID", (x) => x.clientCode || x.id],
45
+ ["TÍTULO", (x) => x.title || x.summary],
46
+ ["STATUS", (x) => x.status],
47
+ ["SEVERIDADE", (x) => x.severity],
48
+ ]),
49
+ );
50
+ }
51
+ }
@@ -0,0 +1,33 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import { WriteCommand, writeFlags } from "../../domain/writeCommand.js";
3
+
4
+ export default class IssueTransition extends WriteCommand {
5
+ static description = "Executa uma transição suportada de status de issue";
6
+ static args = { issue: Args.string({ required: true }) };
7
+ static flags = {
8
+ ...writeFlags,
9
+ status: Flags.string({ required: true, description: "novo status" }),
10
+ };
11
+
12
+ async run() {
13
+ const { args, flags } = await this.parse(IssueTransition);
14
+ return this.write(
15
+ flags,
16
+ "issue",
17
+ async (service) => {
18
+ const payload = await service.issue(args.issue);
19
+ const issue = payload.issue || payload;
20
+ return {
21
+ resource: "issue",
22
+ operation: "status.transition",
23
+ applicationId: issue.applicationId || null,
24
+ currentStatus: issue.status,
25
+ status: flags.status,
26
+ label: `Issue ${issue.code || issue.id || issue._id || args.issue}`,
27
+ entity: issue,
28
+ };
29
+ },
30
+ (service, plan) => service.updateIssueStatus(args.issue, plan.status),
31
+ );
32
+ }
33
+ }
@@ -0,0 +1,7 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Issues extends Command {
3
+ static description = "Consulta incidentes e issues pela API";
4
+ async run() {
5
+ await this.config.runCommand("help", ["issues"]);
6
+ }
7
+ }
@@ -0,0 +1,13 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { createMonitoringCommand } from "../../compatibilityCommands.js";
3
+
4
+ export default createMonitoringCommand("describe", {
5
+ description: "descreve um contrato de monitoramento versionado",
6
+ flags: {
7
+ template: Flags.string({ description: "ID do template", required: true }),
8
+ "template-version": Flags.string({
9
+ description: "versão do template",
10
+ required: true,
11
+ }),
12
+ },
13
+ });
@@ -0,0 +1,25 @@
1
+ import { Flags } from "@oclif/core";
2
+ import {
3
+ createMonitoringCommand,
4
+ runtimeArgument,
5
+ } from "../../compatibilityCommands.js";
6
+
7
+ export default createMonitoringCommand("signal", {
8
+ description: "registra um sinal idempotente de saúde do runtime",
9
+ args: { runtime: runtimeArgument },
10
+ flags: {
11
+ source: Flags.string({ description: "origem do sinal", required: true }),
12
+ status: Flags.string({
13
+ options: ["unknown", "healthy", "degraded", "unavailable", "stopped"],
14
+ }),
15
+ "signal-id": Flags.string({ description: "identificador idempotente" }),
16
+ "observed-at": Flags.string({ description: "instante observado" }),
17
+ message: Flags.string({ description: "mensagem do sinal" }),
18
+ metadata: Flags.string({ description: "objeto JSON de metadados" }),
19
+ "metadata-profile": Flags.string({ description: "perfil dos metadados" }),
20
+ template: Flags.string({ description: "ID do template" }),
21
+ "template-version": Flags.string({ description: "versão do template" }),
22
+ payload: Flags.string({ description: "payload JSON do template" }),
23
+ },
24
+ positional: (args) => [args.runtime],
25
+ });
@@ -0,0 +1,17 @@
1
+ import { Flags } from "@oclif/core";
2
+ import {
3
+ createMonitoringCommand,
4
+ runtimeArgument,
5
+ } from "../../compatibilityCommands.js";
6
+
7
+ export default createMonitoringCommand("signals", {
8
+ description: "lista sinais recebidos por um runtime",
9
+ args: { runtime: runtimeArgument },
10
+ flags: {
11
+ limit: Flags.integer({ description: "quantidade máxima" }),
12
+ page: Flags.integer({ description: "página" }),
13
+ status: Flags.string({ description: "filtra por estado" }),
14
+ source: Flags.string({ description: "filtra por origem" }),
15
+ },
16
+ positional: (args) => [args.runtime],
17
+ });
@@ -0,0 +1,14 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { createMonitoringCommand } from "../../compatibilityCommands.js";
3
+
4
+ export default createMonitoringCommand("validate", {
5
+ description: "valida um payload sem persistir sinal",
6
+ flags: {
7
+ template: Flags.string({ description: "ID do template", required: true }),
8
+ "template-version": Flags.string({
9
+ description: "versão do template",
10
+ required: true,
11
+ }),
12
+ payload: Flags.string({ description: "payload JSON", required: true }),
13
+ },
14
+ });