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.
- package/LICENSE +201 -0
- package/README.md +229 -0
- package/bin/biaws.js +3 -0
- package/docs/command-taxonomy.md +36 -0
- package/docs/instance-lifecycle.md +82 -0
- package/docs/releasing.md +105 -0
- package/package.json +63 -0
- package/shared/skillPackage.js +100 -0
- package/src/apiClient.js +89 -0
- package/src/baseCommands.js +122 -0
- package/src/commands/agent/configure.js +3 -0
- package/src/commands/agent/doctor.js +3 -0
- package/src/commands/agent.js +400 -0
- package/src/commands/api.js +17 -0
- package/src/commands/applications/get.js +17 -0
- package/src/commands/applications/list.js +32 -0
- package/src/commands/applications.js +7 -0
- package/src/commands/configure/claude.js +25 -0
- package/src/commands/configure/codex.js +25 -0
- package/src/commands/configure/doctor.js +49 -0
- package/src/commands/configure/skills.js +74 -0
- package/src/commands/configure.js +19 -0
- package/src/commands/demands/complete-task.js +6 -0
- package/src/commands/demands/get.js +16 -0
- package/src/commands/demands/list.js +48 -0
- package/src/commands/demands/task-status.js +49 -0
- package/src/commands/demands/tasks.js +44 -0
- package/src/commands/demands.js +7 -0
- package/src/commands/instance/backup.js +74 -0
- package/src/commands/instance/list.js +39 -0
- package/src/commands/instance/remove.js +72 -0
- package/src/commands/instance/restore.js +96 -0
- package/src/commands/instance/setup.js +349 -0
- package/src/commands/instance/show.js +31 -0
- package/src/commands/instance/start.js +32 -0
- package/src/commands/instance/status.js +42 -0
- package/src/commands/instance/stop.js +30 -0
- package/src/commands/instance.js +18 -0
- package/src/commands/issues/get.js +16 -0
- package/src/commands/issues/list.js +51 -0
- package/src/commands/issues/transition.js +33 -0
- package/src/commands/issues.js +7 -0
- package/src/commands/monitoring/describe.js +13 -0
- package/src/commands/monitoring/signal.js +25 -0
- package/src/commands/monitoring/signals.js +17 -0
- package/src/commands/monitoring/validate.js +14 -0
- package/src/commands/monitoring.js +163 -0
- package/src/commands/skills/install-all.js +13 -0
- package/src/commands/skills/install.js +16 -0
- package/src/commands/skills/list.js +5 -0
- package/src/commands/skills/publish-all.js +14 -0
- package/src/commands/skills/publish.js +11 -0
- package/src/commands/skills/status.js +7 -0
- package/src/commands/skills/update.js +12 -0
- package/src/commands/skills.js +303 -0
- package/src/commands/workspaces/get.js +15 -0
- package/src/commands/workspaces/list.js +20 -0
- package/src/commands/workspaces.js +7 -0
- package/src/compatibilityCommands.js +107 -0
- package/src/configure/command.js +50 -0
- package/src/core/context.js +162 -0
- package/src/core/errors.js +25 -0
- package/src/core/processRunner.js +119 -0
- package/src/core/prompts.js +138 -0
- package/src/core/redaction.js +29 -0
- package/src/core/terminal.js +72 -0
- package/src/core/wizard.js +279 -0
- package/src/domain/readCommand.js +65 -0
- package/src/domain/readService.js +126 -0
- package/src/domain/writeCommand.js +91 -0
- package/src/domain/writeService.js +122 -0
- package/src/index.js +5 -0
- package/src/instance/command.js +37 -0
- package/src/instance/service.js +515 -0
- package/src/localSkills.js +143 -0
- package/src/skillPackage.js +4 -0
|
@@ -0,0 +1,48 @@
|
|
|
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 DemandList extends ReadCommand {
|
|
9
|
+
static description = "Lista melhorias 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
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { flags } = await this.parse(DemandList);
|
|
18
|
+
const result = await this.read(
|
|
19
|
+
flags,
|
|
20
|
+
(api, c) =>
|
|
21
|
+
api.demands({
|
|
22
|
+
workspaceId: c.workspaceId,
|
|
23
|
+
applicationId: flags.application,
|
|
24
|
+
componentId: flags.component,
|
|
25
|
+
status: flags.status,
|
|
26
|
+
text: flags.search,
|
|
27
|
+
page: flags.page,
|
|
28
|
+
limit: flags.limit,
|
|
29
|
+
}),
|
|
30
|
+
{
|
|
31
|
+
resource: "demands",
|
|
32
|
+
operation: "list",
|
|
33
|
+
requireWorkspace: true,
|
|
34
|
+
scope: (c) => ({
|
|
35
|
+
workspaceId: c.workspaceId,
|
|
36
|
+
applicationId: flags.application,
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
this.emit(flags, result, (p) =>
|
|
41
|
+
table(p.items || [], [
|
|
42
|
+
["CÓDIGO", (x) => x.clientCode || x.id],
|
|
43
|
+
["TÍTULO", (x) => x.title],
|
|
44
|
+
["STATUS", (x) => x.status],
|
|
45
|
+
]),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { WriteCommand, writeFlags } from "../../domain/writeCommand.js";
|
|
3
|
+
import { findTask } from "../../domain/writeService.js";
|
|
4
|
+
|
|
5
|
+
export default class DemandTaskStatus extends WriteCommand {
|
|
6
|
+
static description = "Altera o status de uma tarefa por ação específica";
|
|
7
|
+
static args = {
|
|
8
|
+
demand: Args.string({ required: true }),
|
|
9
|
+
task: Args.string({ required: true }),
|
|
10
|
+
};
|
|
11
|
+
static flags = {
|
|
12
|
+
...writeFlags,
|
|
13
|
+
status: Flags.string({ description: "novo status" }),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(DemandTaskStatus);
|
|
18
|
+
const status = flags.status || this.constructor.defaultStatus;
|
|
19
|
+
if (!status) {
|
|
20
|
+
this.error("Informe --status para alterar a tarefa.", {
|
|
21
|
+
code: "MISSING_STATUS",
|
|
22
|
+
exit: 2,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return this.write(
|
|
26
|
+
flags,
|
|
27
|
+
"task",
|
|
28
|
+
async (service) => {
|
|
29
|
+
const { request, task } = findTask(
|
|
30
|
+
await service.demand(args.demand),
|
|
31
|
+
args.task,
|
|
32
|
+
);
|
|
33
|
+
return {
|
|
34
|
+
resource: "task",
|
|
35
|
+
operation: "status.update",
|
|
36
|
+
requestId: request.id || args.demand,
|
|
37
|
+
applicationId: request.applicationId || task.applicationId || null,
|
|
38
|
+
taskId: task.id || task._id || task.code,
|
|
39
|
+
currentStatus: task.status,
|
|
40
|
+
status,
|
|
41
|
+
label: `Tarefa ${task.code || task.id || task._id}`,
|
|
42
|
+
entity: task,
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
(service, plan) =>
|
|
46
|
+
service.updateTaskStatus(plan.requestId, plan.taskId, plan.status),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { connectionFlags, ReadCommand } from "../../domain/readCommand.js";
|
|
3
|
+
import { readEnvelope, table } from "../../domain/readService.js";
|
|
4
|
+
export default class DemandTasks extends ReadCommand {
|
|
5
|
+
static description = "Lista tarefas de uma melhoria";
|
|
6
|
+
static args = { demand: Args.string({ required: true }) };
|
|
7
|
+
static flags = {
|
|
8
|
+
...connectionFlags,
|
|
9
|
+
status: Flags.string({ description: "filtra por status" }),
|
|
10
|
+
};
|
|
11
|
+
async run() {
|
|
12
|
+
const { args, flags } = await this.parse(DemandTasks);
|
|
13
|
+
const result = await this.read(
|
|
14
|
+
flags,
|
|
15
|
+
async (api, c) => {
|
|
16
|
+
const payload = await api.demand(args.demand, {
|
|
17
|
+
workspaceId: c.workspaceId,
|
|
18
|
+
});
|
|
19
|
+
const request = payload.request || payload;
|
|
20
|
+
const items = (request.tasks || []).filter(
|
|
21
|
+
(x) => !flags.status || x.status === flags.status,
|
|
22
|
+
);
|
|
23
|
+
return { items, meta: { total: items.length } };
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
resource: "tasks",
|
|
27
|
+
operation: "list",
|
|
28
|
+
requireWorkspace: true,
|
|
29
|
+
scope: (c) => ({ workspaceId: c.workspaceId, requestId: args.demand }),
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
result.envelope = readEnvelope("tasks", "list", result.payload, {
|
|
33
|
+
workspaceId: result.context.workspaceId,
|
|
34
|
+
requestId: args.demand,
|
|
35
|
+
});
|
|
36
|
+
this.emit(flags, result, (p) =>
|
|
37
|
+
table(p.items, [
|
|
38
|
+
["CÓDIGO", (x) => x.code || x.id],
|
|
39
|
+
["TÍTULO", (x) => x.title],
|
|
40
|
+
["STATUS", (x) => x.status],
|
|
41
|
+
]),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
import { LocalInstanceCommand } from "../../baseCommands.js";
|
|
4
|
+
import {
|
|
5
|
+
contextFlags,
|
|
6
|
+
contextInput,
|
|
7
|
+
instanceArgument,
|
|
8
|
+
} from "../../instance/command.js";
|
|
9
|
+
import {
|
|
10
|
+
backupArguments,
|
|
11
|
+
executeInstanceScript,
|
|
12
|
+
getInstance,
|
|
13
|
+
withPasswordFile,
|
|
14
|
+
} from "../../instance/service.js";
|
|
15
|
+
|
|
16
|
+
export default class InstanceBackup extends LocalInstanceCommand {
|
|
17
|
+
static description =
|
|
18
|
+
"cria backup completo, criptografado e verificável de uma instância";
|
|
19
|
+
static args = { instance: instanceArgument };
|
|
20
|
+
static flags = {
|
|
21
|
+
...contextFlags,
|
|
22
|
+
output: Flags.string({
|
|
23
|
+
char: "o",
|
|
24
|
+
description: "arquivo de backup de destino",
|
|
25
|
+
}),
|
|
26
|
+
"password-file": Flags.string({
|
|
27
|
+
description: "arquivo privado contendo a senha",
|
|
28
|
+
}),
|
|
29
|
+
json: Flags.boolean({ description: "emite resultado JSON" }),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
async run() {
|
|
33
|
+
const { args, flags } = await this.parse(InstanceBackup);
|
|
34
|
+
const context = await this.localContext(contextInput(flags, args.instance));
|
|
35
|
+
const instance = await getInstance(
|
|
36
|
+
context,
|
|
37
|
+
this.adapters.filesystem,
|
|
38
|
+
args.instance,
|
|
39
|
+
);
|
|
40
|
+
let password;
|
|
41
|
+
if (!flags["password-file"]) {
|
|
42
|
+
if (!context.isInteractive)
|
|
43
|
+
this.error("Informe --password-file em modo não interativo.", {
|
|
44
|
+
code: "BACKUP_PASSWORD_REQUIRED",
|
|
45
|
+
exit: 2,
|
|
46
|
+
});
|
|
47
|
+
password = await this.adapters.prompts.ask({
|
|
48
|
+
name: "password",
|
|
49
|
+
type: "password",
|
|
50
|
+
message: "Senha do backup",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const output = await withPasswordFile(
|
|
54
|
+
this.adapters.filesystem,
|
|
55
|
+
password,
|
|
56
|
+
flags["password-file"],
|
|
57
|
+
async (passwordFile) =>
|
|
58
|
+
executeInstanceScript(
|
|
59
|
+
backupArguments(instance, context, {
|
|
60
|
+
output: flags.output,
|
|
61
|
+
passwordFile,
|
|
62
|
+
}),
|
|
63
|
+
context,
|
|
64
|
+
this.adapters.processRunner,
|
|
65
|
+
{ secrets: password ? [password] : [], silent: flags.json },
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
this.output({ json: flags.json }).result(
|
|
69
|
+
flags.json
|
|
70
|
+
? { instance: instance.name, operation: "backup", output }
|
|
71
|
+
: output,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
import { LocalInstanceCommand } from "../../baseCommands.js";
|
|
4
|
+
import {
|
|
5
|
+
contextFlags,
|
|
6
|
+
contextInput,
|
|
7
|
+
writeResult,
|
|
8
|
+
} from "../../instance/command.js";
|
|
9
|
+
import { listInstances } from "../../instance/service.js";
|
|
10
|
+
|
|
11
|
+
export default class InstanceList extends LocalInstanceCommand {
|
|
12
|
+
static description = "lista instâncias locais sem revelar credenciais";
|
|
13
|
+
static flags = {
|
|
14
|
+
...contextFlags,
|
|
15
|
+
json: Flags.boolean({ description: "emite JSON" }),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
async run() {
|
|
19
|
+
const { flags } = await this.parse(InstanceList);
|
|
20
|
+
const context = await this.localContext(contextInput(flags));
|
|
21
|
+
const instances = (
|
|
22
|
+
await listInstances(context, this.adapters.filesystem)
|
|
23
|
+
).map(({ env, ...item }) => item);
|
|
24
|
+
writeResult(
|
|
25
|
+
this,
|
|
26
|
+
instances,
|
|
27
|
+
(items) =>
|
|
28
|
+
items.length
|
|
29
|
+
? items
|
|
30
|
+
.map(
|
|
31
|
+
(item) =>
|
|
32
|
+
`${item.name}\tMongo ${item.mongoPort}\tAPI ${item.apiPort}\tUI ${item.uiPort}\t${item.directory}`,
|
|
33
|
+
)
|
|
34
|
+
.join("\n")
|
|
35
|
+
: `Nenhuma instância encontrada em ${context.instancesDirectory}.`,
|
|
36
|
+
flags.json,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
import { LocalInstanceCommand } from "../../baseCommands.js";
|
|
4
|
+
import {
|
|
5
|
+
contextFlags,
|
|
6
|
+
contextInput,
|
|
7
|
+
instanceArgument,
|
|
8
|
+
} from "../../instance/command.js";
|
|
9
|
+
import {
|
|
10
|
+
executeInstanceScript,
|
|
11
|
+
getInstance,
|
|
12
|
+
removeArguments,
|
|
13
|
+
} from "../../instance/service.js";
|
|
14
|
+
|
|
15
|
+
export default class InstanceRemove extends LocalInstanceCommand {
|
|
16
|
+
static description =
|
|
17
|
+
"remove uma instância preservando bind mounts externos por padrão";
|
|
18
|
+
static args = { instance: instanceArgument };
|
|
19
|
+
static flags = {
|
|
20
|
+
...contextFlags,
|
|
21
|
+
"delete-external-data": Flags.boolean({
|
|
22
|
+
description: "apaga também bind mounts externos validados",
|
|
23
|
+
}),
|
|
24
|
+
yes: Flags.boolean({ char: "y", description: "confirma a remoção" }),
|
|
25
|
+
json: Flags.boolean({ description: "emite resultado JSON" }),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
async run() {
|
|
29
|
+
const { args, flags } = await this.parse(InstanceRemove);
|
|
30
|
+
const context = await this.localContext(contextInput(flags, args.instance));
|
|
31
|
+
const instance = await getInstance(
|
|
32
|
+
context,
|
|
33
|
+
this.adapters.filesystem,
|
|
34
|
+
args.instance,
|
|
35
|
+
);
|
|
36
|
+
if (!flags.yes) {
|
|
37
|
+
if (!context.isInteractive)
|
|
38
|
+
this.error("Remoção exige --yes em modo não interativo.", {
|
|
39
|
+
code: "CONFIRMATION_REQUIRED",
|
|
40
|
+
exit: 2,
|
|
41
|
+
});
|
|
42
|
+
const confirmation = await this.adapters.prompts.ask({
|
|
43
|
+
name: "confirmation",
|
|
44
|
+
type: "input",
|
|
45
|
+
message: `Digite ${instance.name} para confirmar a remoção`,
|
|
46
|
+
});
|
|
47
|
+
if (confirmation !== instance.name)
|
|
48
|
+
this.error("Remoção cancelada.", {
|
|
49
|
+
code: "CONFIRMATION_MISMATCH",
|
|
50
|
+
exit: 2,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const output = await executeInstanceScript(
|
|
54
|
+
removeArguments(instance, context, {
|
|
55
|
+
deleteExternalData: flags["delete-external-data"],
|
|
56
|
+
}),
|
|
57
|
+
context,
|
|
58
|
+
this.adapters.processRunner,
|
|
59
|
+
{ silent: flags.json },
|
|
60
|
+
);
|
|
61
|
+
this.output({ json: flags.json }).result(
|
|
62
|
+
flags.json
|
|
63
|
+
? {
|
|
64
|
+
instance: instance.name,
|
|
65
|
+
operation: "remove",
|
|
66
|
+
externalDataDeleted: flags["delete-external-data"],
|
|
67
|
+
output,
|
|
68
|
+
}
|
|
69
|
+
: output,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
import { LocalInstanceCommand } from "../../baseCommands.js";
|
|
4
|
+
import {
|
|
5
|
+
contextFlags,
|
|
6
|
+
contextInput,
|
|
7
|
+
instanceArgument,
|
|
8
|
+
} from "../../instance/command.js";
|
|
9
|
+
import {
|
|
10
|
+
executeInstanceScript,
|
|
11
|
+
getInstance,
|
|
12
|
+
restoreArguments,
|
|
13
|
+
withPasswordFile,
|
|
14
|
+
} from "../../instance/service.js";
|
|
15
|
+
|
|
16
|
+
export default class InstanceRestore extends LocalInstanceCommand {
|
|
17
|
+
static description =
|
|
18
|
+
"restaura um backup completo preservando a configuração do host de destino";
|
|
19
|
+
static args = { instance: instanceArgument };
|
|
20
|
+
static flags = {
|
|
21
|
+
...contextFlags,
|
|
22
|
+
archive: Flags.string({
|
|
23
|
+
char: "a",
|
|
24
|
+
required: true,
|
|
25
|
+
description: "backup criptografado",
|
|
26
|
+
}),
|
|
27
|
+
"password-file": Flags.string({
|
|
28
|
+
description: "arquivo privado contendo a senha",
|
|
29
|
+
}),
|
|
30
|
+
yes: Flags.boolean({
|
|
31
|
+
char: "y",
|
|
32
|
+
description: "confirma a substituição dos dados",
|
|
33
|
+
}),
|
|
34
|
+
json: Flags.boolean({ description: "emite resultado JSON" }),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
async run() {
|
|
38
|
+
const { args, flags } = await this.parse(InstanceRestore);
|
|
39
|
+
const context = await this.localContext(contextInput(flags, args.instance));
|
|
40
|
+
const instance = await getInstance(
|
|
41
|
+
context,
|
|
42
|
+
this.adapters.filesystem,
|
|
43
|
+
args.instance,
|
|
44
|
+
);
|
|
45
|
+
if (!flags.yes) {
|
|
46
|
+
if (!context.isInteractive)
|
|
47
|
+
this.error("Restauração exige --yes em modo não interativo.", {
|
|
48
|
+
code: "CONFIRMATION_REQUIRED",
|
|
49
|
+
exit: 2,
|
|
50
|
+
});
|
|
51
|
+
const confirmation = await this.adapters.prompts.ask({
|
|
52
|
+
name: "confirmation",
|
|
53
|
+
type: "input",
|
|
54
|
+
message: `Digite ${instance.name} para confirmar a restauração`,
|
|
55
|
+
});
|
|
56
|
+
if (confirmation !== instance.name)
|
|
57
|
+
this.error("Restauração cancelada.", {
|
|
58
|
+
code: "CONFIRMATION_MISMATCH",
|
|
59
|
+
exit: 2,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
let password;
|
|
63
|
+
if (!flags["password-file"]) {
|
|
64
|
+
if (!context.isInteractive)
|
|
65
|
+
this.error("Informe --password-file em modo não interativo.", {
|
|
66
|
+
code: "BACKUP_PASSWORD_REQUIRED",
|
|
67
|
+
exit: 2,
|
|
68
|
+
});
|
|
69
|
+
password = await this.adapters.prompts.ask({
|
|
70
|
+
name: "password",
|
|
71
|
+
type: "password",
|
|
72
|
+
message: "Senha do backup",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const output = await withPasswordFile(
|
|
76
|
+
this.adapters.filesystem,
|
|
77
|
+
password,
|
|
78
|
+
flags["password-file"],
|
|
79
|
+
(passwordFile) =>
|
|
80
|
+
executeInstanceScript(
|
|
81
|
+
restoreArguments(instance, context, {
|
|
82
|
+
archive: flags.archive,
|
|
83
|
+
passwordFile,
|
|
84
|
+
}),
|
|
85
|
+
context,
|
|
86
|
+
this.adapters.processRunner,
|
|
87
|
+
{ secrets: password ? [password] : [], silent: flags.json },
|
|
88
|
+
),
|
|
89
|
+
);
|
|
90
|
+
this.output({ json: flags.json }).result(
|
|
91
|
+
flags.json
|
|
92
|
+
? { instance: instance.name, operation: "restore", output }
|
|
93
|
+
: output,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|