biaws 0.4.0 → 0.5.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 (57) hide show
  1. package/README.md +7 -6
  2. package/docs/instance-lifecycle.md +25 -8
  3. package/docs/releasing.md +4 -3
  4. package/package.json +1 -1
  5. package/shared/skillPackage.js +9 -22
  6. package/src/admin/commands.js +18 -45
  7. package/src/admin/monitoringCommands.js +3 -12
  8. package/src/apiClient.js +5 -13
  9. package/src/baseCommands.js +7 -31
  10. package/src/commandFactories.js +5 -17
  11. package/src/commands/agent.js +36 -95
  12. package/src/commands/api.js +1 -2
  13. package/src/commands/applications/get.js +1 -3
  14. package/src/commands/applications/list.js +1 -5
  15. package/src/commands/configure/claude.js +2 -7
  16. package/src/commands/configure/codex.js +2 -7
  17. package/src/commands/configure/skills.js +6 -13
  18. package/src/commands/configure.js +1 -2
  19. package/src/commands/demands/get.js +5 -5
  20. package/src/commands/demands/list.js +1 -5
  21. package/src/commands/demands/task-status.js +2 -6
  22. package/src/commands/demands/tasks.js +1 -3
  23. package/src/commands/instance/backup.js +4 -18
  24. package/src/commands/instance/list.js +2 -8
  25. package/src/commands/instance/remove.js +4 -17
  26. package/src/commands/instance/restore.js +14 -32
  27. package/src/commands/instance/setup.js +12 -36
  28. package/src/commands/instance/show.js +2 -12
  29. package/src/commands/instance/start.js +4 -19
  30. package/src/commands/instance/status.js +4 -24
  31. package/src/commands/instance/stop.js +3 -16
  32. package/src/commands/instance/update.js +30 -58
  33. package/src/commands/instance.js +1 -2
  34. package/src/commands/issues/list.js +1 -5
  35. package/src/commands/monitoring/signal.js +1 -4
  36. package/src/commands/monitoring/signals.js +1 -4
  37. package/src/commands/monitoring.js +8 -26
  38. package/src/commands/skills/update.js +1 -4
  39. package/src/commands/skills.js +19 -58
  40. package/src/configuration/commands.js +27 -63
  41. package/src/configure/command.js +4 -9
  42. package/src/core/configuration.js +15 -45
  43. package/src/core/context.js +17 -43
  44. package/src/core/processRunner.js +11 -19
  45. package/src/core/prompts.js +12 -30
  46. package/src/core/redaction.js +2 -5
  47. package/src/core/terminal.js +1 -4
  48. package/src/core/wizard.js +23 -72
  49. package/src/domain/readService.js +5 -16
  50. package/src/domain/writeCommand.js +5 -12
  51. package/src/domain/writeService.js +10 -17
  52. package/src/instance/command.js +1 -2
  53. package/src/instance/release.js +100 -0
  54. package/src/instance/service.js +77 -203
  55. package/src/localSkills.js +9 -38
  56. package/src/skillPackage.js +1 -4
  57. package/src/workspace/commands.js +15 -24
package/README.md CHANGED
@@ -15,8 +15,8 @@ Uma execução descartável pode usar `npx biaws help`. Em um checkout de
15
15
  desenvolvimento, `npm --prefix biaws-cli link` cria o mesmo comando global.
16
16
 
17
17
  O pacote requer Node.js 20.19 ou superior. Operações administrativas de
18
- instância também exigem Git, Docker e Docker Compose. Windows é suportado por
19
- WSL2, não de forma nativa.
18
+ instância também exigem Git, Bash, `curl`, OpenSSL, `tar`, Docker e Docker
19
+ Compose. Windows é suportado por WSL2, não de forma nativa.
20
20
 
21
21
  ## Organização
22
22
 
@@ -123,7 +123,7 @@ biaws workspace api PATCH /recurso/ID --body '{"status":"Ativo"}'
123
123
  biaws workspace agent configure codex
124
124
  biaws workspace agent configure claude
125
125
  biaws workspace agent configure codex --no-interactive --env-file /caminho/instancia.env --workspace workspace-id
126
- biaws workspace agent doctor codex
126
+ biaws workspace agent doctor codex --env-file /caminho/instancia.env
127
127
  biaws workspace skills list
128
128
  biaws workspace skills install SKILL_ID
129
129
  biaws workspace skills update
@@ -158,13 +158,14 @@ Diagnostique os pré-requisitos e baixe uma release verificada:
158
158
 
159
159
  ```bash
160
160
  biaws admin doctor
161
- biaws admin install --version 1.0.0 --dry-run
162
- biaws admin install --version 1.0.0 --directory /opt/biaws
161
+ biaws admin install --version <versão> --dry-run
162
+ biaws admin install --version <versão> --directory /opt/biaws
163
163
  ```
164
164
 
165
165
  O instalador busca `biaws-<versão>.tar.gz` e seu arquivo `.sha256` na release do
166
166
  GitHub. Ele recusa diretórios não vazios e extrai somente depois de verificar o
167
- checksum.
167
+ checksum. Use somente uma versão que possua esses dois assets publicados; o
168
+ pacote npm isolado não contém o runtime Docker.
168
169
 
169
170
  Gerencie as instâncias:
170
171
 
@@ -52,10 +52,18 @@ biaws admin instance update local --check
52
52
  biaws admin instance update local --check --json
53
53
  ```
54
54
 
55
- O resultado informa `currentVersion`, `newVersion` e `updateRequired`.
56
- Instâncias criadas antes desse mecanismo começam com `currentVersion` igual a
57
- `unknown` e são consideradas pendentes. Se as versões forem iguais, o comando
58
- não cria backup nem reconstrói containers; use `--force` para repetir o deploy.
55
+ O resultado informa `currentVersion`, `newVersion`, `updateRequired`,
56
+ `legacyInstallation`, `installedRelease`, `availableRelease` e `differences`.
57
+ Cada diferença contém `field`, `current` e `available`; a saída textual também
58
+ mostra as alterações. O manifesto `release.json` do checkout descreve a versão
59
+ da plataforma, a revisão de implantação e as versões de API, UI e executor.
60
+ Qualquer diferença nesses campos exige atualização, mesmo com a mesma versão
61
+ geral. A versão do CLI e a do MCP não participam dessa comparação.
62
+
63
+ Instâncias sem `instances/<nome>/release.json` são legadas e exigem atualização,
64
+ mesmo com `BIAWS_VERSION` igual. Um snapshot inválido causa erro explícito.
65
+ Quando o manifesto é igual, não há backup nem reconstrução; `--force` permite
66
+ repetir o deploy. `--check` é somente leitura e não precisa executar Docker.
59
67
 
60
68
  Por padrão, o comando valida o arquivo Compose, solicita uma senha, cria um
61
69
  backup completo e então executa `up -d --build --wait`. Em automação, use um
@@ -70,10 +78,19 @@ local pode ser dispensada explicitamente com `--skip-backup`. O update preserva
70
78
  o project name, o `.env`, os volumes e os bind mounts da instância. Ele não
71
79
  executa `git pull` nem troca a versão do checkout.
72
80
 
73
- A versão implantada só é registrada depois que `up -d --build --wait` termina
74
- com sucesso. Ela também é exposta pelo `/api/health` e pelos labels dos
75
- containers de API e UI. A versão nova é lida do `biaws-cli/package.json` da
76
- raiz selecionada por `--root`/`BIAWS_ROOT`.
81
+ O manifesto aplicado só é registrado depois que `up -d --build --wait` termina
82
+ com sucesso. O update inclui o executor local já existente no projeto Compose;
83
+ executores externos continuam sendo atualizados separadamente. Cada arquivo de
84
+ estado é substituído atomicamente, preservando o `.env` e suas permissões
85
+ privadas. Se o deploy falhar, o snapshot anterior permanece. Se a gravação do
86
+ estado falhar após o deploy, o comando falha e deve ser repetido para reconciliar.
87
+
88
+ `release.json` vem da raiz selecionada por `--root`/`BIAWS_ROOT` e deve estar
89
+ sincronizado com os pacotes. Sua `version` é exposta pelo `/api/health` e pelos
90
+ labels de API e UI. O setup registra o mesmo snapshot após o bootstrap; com
91
+ `--skip-bootstrap`, ele não registra uma release. O restore invalida o snapshot
92
+ porque não restaura imagens: execute update no checkout desejado depois dele.
93
+ Consulte [o guia de versões](../../docs/versions.md) para preparar uma release.
77
94
 
78
95
  ## Smoke test Docker real
79
96
 
package/docs/releasing.md CHANGED
@@ -84,9 +84,10 @@ ordem, em uma instância isolada:
84
84
 
85
85
  1. `biaws --help` e `biaws --version` pela instalação empacotada;
86
86
  2. `biaws admin instance setup` e `biaws workspace agent configure codex|claude` com `BIAWS_ROOT`;
87
- 3. uma consulta `workspaces list --json` e outra por código, como
88
- `demands get <código> --json`;
89
- 4. uma escrita idempotente com `demands task-status ... --yes --json`, seguida
87
+ 3. uma consulta `biaws workspace list --json` e outra por código, como
88
+ `biaws workspace demands get <código> --json`;
89
+ 4. uma escrita idempotente com `biaws workspace demands task-status ... --yes
90
+ --json`, seguida
90
91
  de nova leitura;
91
92
  5. `biaws admin instance backup`, restore em uma instância de destino e validação de
92
93
  API/UI;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "biaws",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "CLI do Bondia Workspaces para administração, configuração e operação de workspaces",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -15,11 +15,8 @@ async function collectFiles(root, current = root, result = []) {
15
15
  entries.sort((a, b) => a.name.localeCompare(b.name));
16
16
  for (const entry of entries) {
17
17
  const absolutePath = path.join(current, entry.name);
18
- const relativePath = normalizeRelativePath(
19
- path.relative(root, absolutePath),
20
- );
21
- if (entry.isSymbolicLink())
22
- throw new Error(`Links simbólicos não são permitidos: ${relativePath}`);
18
+ const relativePath = normalizeRelativePath(path.relative(root, absolutePath));
19
+ if (entry.isSymbolicLink()) throw new Error(`Links simbólicos não são permitidos: ${relativePath}`);
23
20
  if (entry.isDirectory()) await collectFiles(root, absolutePath, result);
24
21
  else if (entry.isFile()) result.push({ absolutePath, path: relativePath });
25
22
  }
@@ -43,38 +40,28 @@ function extractFrontmatter(markdown) {
43
40
  export async function buildSkillPayload(directory, options = {}) {
44
41
  const root = path.resolve(directory);
45
42
  const stats = await lstat(root);
46
- if (!stats.isDirectory())
47
- throw new Error(`Diretório de skill inválido: ${root}`);
43
+ if (!stats.isDirectory()) throw new Error(`Diretório de skill inválido: ${root}`);
48
44
  const entries = await collectFiles(root);
49
45
  if (!entries.some((entry) => entry.path === "SKILL.md")) {
50
46
  throw new Error(`SKILL.md não encontrado em ${root}`);
51
47
  }
52
- if (entries.length > MAX_FILES)
53
- throw new Error(`A skill excede o limite de ${MAX_FILES} arquivos`);
48
+ if (entries.length > MAX_FILES) throw new Error(`A skill excede o limite de ${MAX_FILES} arquivos`);
54
49
 
55
50
  let totalBytes = 0;
56
51
  const files = [];
57
52
  for (const entry of entries) {
58
53
  const content = await readFile(entry.absolutePath);
59
- if (content.length > MAX_FILE_BYTES)
60
- throw new Error(`Arquivo excede ${MAX_FILE_BYTES} bytes: ${entry.path}`);
54
+ if (content.length > MAX_FILE_BYTES) throw new Error(`Arquivo excede ${MAX_FILE_BYTES} bytes: ${entry.path}`);
61
55
  totalBytes += content.length;
62
- if (totalBytes > MAX_PACKAGE_BYTES)
63
- throw new Error(`A skill excede o limite de ${MAX_PACKAGE_BYTES} bytes`);
56
+ if (totalBytes > MAX_PACKAGE_BYTES) throw new Error(`A skill excede o limite de ${MAX_PACKAGE_BYTES} bytes`);
64
57
  files.push({ path: entry.path, contentBase64: content.toString("base64") });
65
58
  }
66
59
  const skillMarkdown = await readFile(path.join(root, "SKILL.md"), "utf8");
67
60
  const frontmatter = extractFrontmatter(skillMarkdown);
68
- const skillId = String(
69
- options.id || frontmatter.name || path.basename(root),
70
- ).trim();
71
- const description = String(
72
- options.description || frontmatter.description || "",
73
- ).trim();
61
+ const skillId = String(options.id || frontmatter.name || path.basename(root)).trim();
62
+ const description = String(options.description || frontmatter.description || "").trim();
74
63
  if (!description) {
75
- throw new Error(
76
- "Descrição ausente; informe --description ou adicione description ao SKILL.md",
77
- );
64
+ throw new Error("Descrição ausente; informe --description ou adicione description ao SKILL.md");
78
65
  }
79
66
  return {
80
67
  skillId,
@@ -50,6 +50,10 @@ export class AdminDoctorCommand extends BaseCommand {
50
50
  const checks = [
51
51
  { name: "Node.js", command: "node", args: ["--version"] },
52
52
  { name: "Git", command: "git", args: ["--version"] },
53
+ { name: "Bash", command: "bash", args: ["--version"] },
54
+ { name: "curl", command: "curl", args: ["--version"] },
55
+ { name: "OpenSSL", command: "openssl", args: ["version"] },
56
+ { name: "tar", command: "tar", args: ["--version"] },
53
57
  { name: "Docker", command: "docker", args: ["--version"] },
54
58
  {
55
59
  name: "Docker Compose",
@@ -60,11 +64,7 @@ export class AdminDoctorCommand extends BaseCommand {
60
64
  const items = [];
61
65
  for (const check of checks) {
62
66
  try {
63
- const result = await this.adapters.processRunner.run(
64
- check.command,
65
- check.args,
66
- { silent: true },
67
- );
67
+ const result = await this.adapters.processRunner.run(check.command, check.args, { silent: true });
68
68
  items.push({
69
69
  name: check.name,
70
70
  status: "disponível",
@@ -84,12 +84,7 @@ export class AdminDoctorCommand extends BaseCommand {
84
84
  this,
85
85
  flags.json,
86
86
  { healthy, items },
87
- items
88
- .map(
89
- (item) =>
90
- `${item.name}: ${item.status}${item.version ? ` (${item.version})` : ""}`,
91
- )
92
- .join("\n"),
87
+ items.map((item) => `${item.name}: ${item.status}${item.version ? ` (${item.version})` : ""}`).join("\n"),
93
88
  );
94
89
  }
95
90
  }
@@ -103,13 +98,10 @@ async function ensureEmptyDirectory(filesystem, directory) {
103
98
  try {
104
99
  const entries = await filesystem.readdir(directory);
105
100
  if (entries.length) {
106
- throw new CliError(
107
- `O diretório de destino não está vazio: ${directory}.`,
108
- {
109
- code: "INSTALL_DIRECTORY_NOT_EMPTY",
110
- exitCode: 2,
111
- },
112
- );
101
+ throw new CliError(`O diretório de destino não está vazio: ${directory}.`, {
102
+ code: "INSTALL_DIRECTORY_NOT_EMPTY",
103
+ exitCode: 2,
104
+ });
113
105
  }
114
106
  } catch (error) {
115
107
  if (error.code !== "ENOENT") throw error;
@@ -136,10 +128,7 @@ async function expectedChecksum(url, explicit) {
136
128
  { code: "INSTALL_CHECKSUM_REQUIRED" },
137
129
  );
138
130
  }
139
- return (await response.text())
140
- .trim()
141
- .split(/\s+/u)[0]
142
- .toLocaleLowerCase("en-US");
131
+ return (await response.text()).trim().split(/\s+/u)[0].toLocaleLowerCase("en-US");
143
132
  }
144
133
 
145
134
  export class AdminInstallCommand extends BaseCommand {
@@ -161,18 +150,11 @@ export class AdminInstallCommand extends BaseCommand {
161
150
  async run() {
162
151
  const { flags } = await this.parse(this.constructor);
163
152
  const version = flags.version || this.config.version;
164
- const directory = path.resolve(
165
- flags.directory || path.join(this.adapters.cwd(), `biaws-${version}`),
166
- );
153
+ const directory = path.resolve(flags.directory || path.join(this.adapters.cwd(), `biaws-${version}`));
167
154
  const url = githubArchive(flags.repository, version);
168
155
  const plan = { directory, source: url, version };
169
156
  if (flags["dry-run"]) {
170
- emit(
171
- this,
172
- flags.json,
173
- { ...plan, dryRun: true },
174
- `Release v${version}\nOrigem: ${url}\nDestino: ${directory}`,
175
- );
157
+ emit(this, flags.json, { ...plan, dryRun: true }, `Release v${version}\nOrigem: ${url}\nDestino: ${directory}`);
176
158
  return;
177
159
  }
178
160
  await ensureEmptyDirectory(this.adapters.filesystem, directory);
@@ -180,24 +162,15 @@ export class AdminInstallCommand extends BaseCommand {
180
162
  const checksum = await expectedChecksum(url, flags.checksum);
181
163
  const actual = createHash("sha256").update(archive).digest("hex");
182
164
  if (actual !== checksum) {
183
- throw new CliError(
184
- `Checksum inválido: esperado ${checksum}, obtido ${actual}.`,
185
- { code: "INSTALL_CHECKSUM_MISMATCH" },
186
- );
165
+ throw new CliError(`Checksum inválido: esperado ${checksum}, obtido ${actual}.`, {
166
+ code: "INSTALL_CHECKSUM_MISMATCH",
167
+ });
187
168
  }
188
- const temporary = await this.adapters.filesystem.mkdtemp(
189
- path.join(tmpdir(), "biaws-install-"),
190
- );
169
+ const temporary = await this.adapters.filesystem.mkdtemp(path.join(tmpdir(), "biaws-install-"));
191
170
  const archivePath = path.join(temporary, "biaws.tar.gz");
192
171
  try {
193
172
  await this.adapters.filesystem.writeFile(archivePath, archive);
194
- await this.adapters.processRunner.run("tar", [
195
- "-xzf",
196
- archivePath,
197
- "--strip-components=1",
198
- "-C",
199
- directory,
200
- ]);
173
+ await this.adapters.processRunner.run("tar", ["-xzf", archivePath, "--strip-components=1", "-C", directory]);
201
174
  } finally {
202
175
  await this.adapters.filesystem.rm(temporary, {
203
176
  recursive: true,
@@ -39,11 +39,7 @@ export function createAdminMonitoringCommand(action) {
39
39
  instance: flags.instance,
40
40
  root: flags.root,
41
41
  });
42
- const script = path.join(
43
- context.repositoryRoot,
44
- "scripts",
45
- "manage-monitoring-workspaces.sh",
46
- );
42
+ const script = path.join(context.repositoryRoot, "scripts", "manage-monitoring-workspaces.sh");
47
43
  await this.adapters.processRunner.run("bash", [
48
44
  script,
49
45
  "--instance",
@@ -56,8 +52,7 @@ export function createAdminMonitoringCommand(action) {
56
52
  }
57
53
 
58
54
  export class AdminMonitoringProvisionCommand extends LocalInstanceCommand {
59
- static description =
60
- "provisiona a identidade técnica de monitoramento de um workspace";
55
+ static description = "provisiona a identidade técnica de monitoramento de um workspace";
61
56
  static args = {
62
57
  workspace: Args.string({
63
58
  description: "identificador local do workspace",
@@ -72,11 +67,7 @@ export class AdminMonitoringProvisionCommand extends LocalInstanceCommand {
72
67
  instance: flags.instance,
73
68
  root: flags.root,
74
69
  });
75
- const script = path.join(
76
- context.repositoryRoot,
77
- "scripts",
78
- "provision-monitoring-workspace.mjs",
79
- );
70
+ const script = path.join(context.repositoryRoot, "scripts", "provision-monitoring-workspace.mjs");
80
71
  await this.adapters.processRunner.run("node", [
81
72
  script,
82
73
  "--instance",
package/src/apiClient.js CHANGED
@@ -40,22 +40,14 @@ export function createApiClient(baseUrl, apiKey, workspaceId = "") {
40
40
  }
41
41
 
42
42
  return {
43
- withWorkspace: (selectedWorkspaceId) =>
44
- createApiClient(baseUrl, apiKey, selectedWorkspaceId),
43
+ withWorkspace: (selectedWorkspaceId) => createApiClient(baseUrl, apiKey, selectedWorkspaceId),
45
44
  request: (path, options = {}) => request(path, options, apiRoot),
46
45
  identity: () => request("/auth/me", {}, apiRoot),
47
- list: (options = {}) =>
48
- request(options.includeDeprecated ? "?includeDeprecated=true" : ""),
46
+ list: (options = {}) => request(options.includeDeprecated ? "?includeDeprecated=true" : ""),
49
47
  get: (skillId, version) =>
50
- request(
51
- `/${encodeURIComponent(skillId)}${version ? `?version=${encodeURIComponent(version)}` : ""}`,
52
- ),
53
- download: (skillId, version) =>
54
- request(
55
- `/${encodeURIComponent(skillId)}/${encodeURIComponent(version)}/download`,
56
- ),
57
- publish: (payload) =>
58
- request("", { method: "POST", body: JSON.stringify(payload) }),
48
+ request(`/${encodeURIComponent(skillId)}${version ? `?version=${encodeURIComponent(version)}` : ""}`),
49
+ download: (skillId, version) => request(`/${encodeURIComponent(skillId)}/${encodeURIComponent(version)}/download`),
50
+ publish: (payload) => request("", { method: "POST", body: JSON.stringify(payload) }),
59
51
  monitoring: {
60
52
  describeTemplate: (templateId, version) =>
61
53
  request(
@@ -1,36 +1,16 @@
1
- import {
2
- access,
3
- chmod,
4
- mkdtemp,
5
- mkdir,
6
- readFile,
7
- readdir,
8
- stat,
9
- rm,
10
- writeFile,
11
- } from "node:fs/promises";
1
+ import { access, chmod, mkdtemp, mkdir, readFile, readdir, rename, stat, rm, writeFile } from "node:fs/promises";
12
2
  import path from "node:path";
13
3
  import { fileURLToPath } from "node:url";
14
4
 
15
5
  import { Command } from "@oclif/core";
16
6
 
17
7
  import { createApiClient } from "./apiClient.js";
18
- import {
19
- resolveAuthenticatedContext,
20
- resolveCommandContext,
21
- } from "./core/context.js";
8
+ import { resolveAuthenticatedContext, resolveCommandContext } from "./core/context.js";
22
9
  import { ProcessRunner } from "./core/processRunner.js";
23
10
  import { createPromptAdapter } from "./core/prompts.js";
24
- import {
25
- CliLogger,
26
- CliOutput,
27
- createTerminalAdapter,
28
- } from "./core/terminal.js";
11
+ import { CliLogger, CliOutput, createTerminalAdapter } from "./core/terminal.js";
29
12
 
30
- export const TOOL_DIRECTORY = path.resolve(
31
- path.dirname(fileURLToPath(import.meta.url)),
32
- "..",
33
- );
13
+ export const TOOL_DIRECTORY = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
34
14
 
35
15
  export function createCommandAdapters(overrides = {}) {
36
16
  const environment = overrides.environment || { ...process.env };
@@ -41,6 +21,7 @@ export function createCommandAdapters(overrides = {}) {
41
21
  mkdir,
42
22
  readFile,
43
23
  readdir,
24
+ rename,
44
25
  stat,
45
26
  rm,
46
27
  writeFile,
@@ -53,8 +34,7 @@ export function createCommandAdapters(overrides = {}) {
53
34
  stdout: terminal.stdout,
54
35
  stderr: terminal.stderr,
55
36
  });
56
- const prompts =
57
- overrides.prompts || createPromptAdapter(terminal, overrides.promptOptions);
37
+ const prompts = overrides.prompts || createPromptAdapter(terminal, overrides.promptOptions);
58
38
  return Object.freeze({
59
39
  apiFactory: overrides.apiFactory || createApiClient,
60
40
  cwd: overrides.cwd || (() => process.cwd()),
@@ -110,11 +90,7 @@ export class AuthenticatedApiCommand extends BaseCommand {
110
90
  });
111
91
  return Object.freeze({
112
92
  ...context,
113
- api: this.adapters.apiFactory(
114
- context.apiUrl,
115
- context.apiKey,
116
- context.workspaceId,
117
- ),
93
+ api: this.adapters.apiFactory(context.apiUrl, context.apiKey, context.workspaceId),
118
94
  });
119
95
  }
120
96
  }
@@ -40,13 +40,8 @@ export function createSkillsCommand(action, definition = {}) {
40
40
 
41
41
  async run() {
42
42
  const { args, flags } = await this.parse(this.constructor);
43
- const context = await this.authenticatedContext(
44
- authenticatedInput(flags),
45
- { requireWorkspace: true },
46
- );
47
- const positional = definition.positional
48
- ? definition.positional(args)
49
- : [];
43
+ const context = await this.authenticatedContext(authenticatedInput(flags), { requireWorkspace: true });
44
+ const positional = definition.positional ? definition.positional(args) : [];
50
45
  await runSkillsCommand(context.api, action, positional, flags);
51
46
  }
52
47
  };
@@ -60,13 +55,8 @@ export function createMonitoringCommand(action, definition = {}) {
60
55
 
61
56
  async run() {
62
57
  const { args, flags } = await this.parse(this.constructor);
63
- const context = await this.authenticatedContext(
64
- authenticatedInput(flags),
65
- { requireWorkspace: true },
66
- );
67
- const positional = definition.positional
68
- ? definition.positional(args)
69
- : [];
58
+ const context = await this.authenticatedContext(authenticatedInput(flags), { requireWorkspace: true });
59
+ const positional = definition.positional ? definition.positional(args) : [];
70
60
  await runMonitoringCommand(context.api, action, positional, flags);
71
61
  }
72
62
  };
@@ -87,9 +77,7 @@ export function createAgentCommand(action) {
87
77
  async run() {
88
78
  const { args, flags } = await this.parse(this.constructor);
89
79
  const input =
90
- action === "configure"
91
- ? await interactiveConfigureInput(this, flags)
92
- : configureContextInput(flags);
80
+ action === "configure" ? await interactiveConfigureInput(this, flags) : configureContextInput(flags);
93
81
  const context = await this.projectContext(input);
94
82
  await runAgentCommand(
95
83
  context.api,