@vectorplane/ctrl-cli 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,6 +18,14 @@ vp login
18
18
  vp logout
19
19
  vp status
20
20
  vp sync
21
+ vp task templates
22
+ vp task run --title "Entrega X" --intention "Implementar fluxo Y"
23
+ vp task run --template code-review --title "Review auth" --intention "Revisar risco e cobertura do fluxo de auth"
24
+ vp task claim --capability qa.test
25
+ vp task execute <task-id> --step <step-id>
26
+ vp task daemon --capability qa.test
27
+ vp context --search "decisões sobre autenticação"
28
+ vp context --delivery --search "fluxo de login" --type decisions
21
29
  vp context --workspace <workspace> --delivery
22
30
  vp session check-in --workspace <workspace> --agent codex --type codex --client openai-codex --feature feature-key --task task-key --owning-path "src/core,src/ui" --need "api-contract" --provide "implementation" --status "starting implementation"
23
31
  vp draft create --type progress --title "Entrega concluída" --content "Resumo da mudança"
@@ -42,6 +50,7 @@ vp draft create --type progress --title "Entrega concluída" --content "Resumo d
42
50
  - salva a sessão localmente
43
51
  - suporta `--no-browser` e `--manual`
44
52
  - em ambientes remotos ou isolados, o loopback local pode exigir um fluxo alternativo
53
+ - a URL web do login é emitida pelo control plane; o domínio do app não deve ser hardcoded em automações externas
45
54
 
46
55
  ### `vp logout`
47
56
 
@@ -59,6 +68,25 @@ vp draft create --type progress --title "Entrega concluída" --content "Resumo d
59
68
  - mostra o estado da sessão local
60
69
  - exibe workspace ativo, diretório atual e última sincronização
61
70
 
71
+ ### `vp task`
72
+
73
+ - cria tasks no orchestrator do workspace
74
+ - lista templates disponíveis com `vp task templates`
75
+ - aceita `--template <slug>` para herdar capabilities e paths padrão do backend
76
+ - lista e inspeciona tasks existentes
77
+ - faz claim explícito de steps `pending_claim` atribuídos a agentes CLI
78
+ - executa steps locais via `metadata.execution.command`
79
+ - suporta loop controlado com `vp task daemon --capability ...`
80
+ - registra delegação de step
81
+ - envia callback de execução por step para concluir a pipeline
82
+ - lê handoff operacional por task
83
+ - consulta observabilidade por task ou workspace
84
+ - consulta health do workspace ligado às tasks
85
+ - para automação local real, o agente de registry deve ter `metadata.execution` com:
86
+ - `type: "command"`
87
+ - `command: "npm"` ou equivalente
88
+ - `args`, `cwd` e `env` opcionais
89
+
62
90
  ### `vp draft`
63
91
 
64
92
  - cria drafts editoriais ligados ao workspace atual
@@ -87,12 +115,16 @@ vp draft create --type progress --title "Entrega concluída" --content "Resumo d
87
115
  - gerencia sessões de agente
88
116
  - `vp context`
89
117
  - carrega contexto remoto do workspace
118
+ - suporta `--search "QUERY"` para busca semântica na memória
119
+ - com `--delivery --search`, retorna delivery context com fragmentos semânticos relevantes
90
120
  - `vp bootstrap`
91
121
  - obtém instruções de setup do workspace
92
122
  - `vp event send`
93
123
  - envia eventos operacionais
94
124
  - `vp draft`
95
125
  - envia e consulta drafts editoriais do workspace
126
+ - `vp task`
127
+ - opera tasks do autonomous control plane
96
128
 
97
129
  ## Persistência local
98
130
 
@@ -7,11 +7,12 @@ import { ensureFreshSession, resolveWorkspaceSlug } from "../core/session.js";
7
7
  import { VectorPlaneApiClient } from "../core/api.js";
8
8
  import { getBoundWorkspace, resolveWorkspaceRoot } from "../core/workspace-binding.js";
9
9
  import { ValidationError } from "../core/errors.js";
10
- import { ensureAgentSetupCurrent } from "../core/agent-setup.js";
10
+ import { ensureRuntimeAgentSetup } from "../core/runtime-agent-setup.js";
11
11
  export async function runContextCommand(cliVersion, args) {
12
12
  const parsed = parseArgs(args);
13
13
  const delivery = getBooleanOption(parsed, "delivery");
14
14
  const snapshot = getBooleanOption(parsed, "snapshot");
15
+ const search = getStringOption(parsed, "search")?.trim();
15
16
  const runtime = await loadRuntimeStatus();
16
17
  const session = await ensureSessionAvailable(runtime.profile.name);
17
18
  const [git, machine, runtimeContext] = await Promise.all([
@@ -36,20 +37,26 @@ export async function runContextCommand(cliVersion, args) {
36
37
  if (!workspace) {
37
38
  throw new ValidationError("Nenhum workspace resolvido para carregar contexto.");
38
39
  }
39
- await ensureAgentSetupCurrent({
40
- rootPath,
41
- workspace,
42
- repoUrl: git.remoteOrigin,
43
- source: git.remoteOrigin ? "api-resolve" : "manual",
44
- accessToken: freshSession.accessToken,
45
- apiClient,
46
- logger: runtime.logger,
47
- });
48
- const payload = delivery
49
- ? await apiClient.getWorkspaceDeliveryContext(freshSession.accessToken, workspace)
50
- : snapshot
51
- ? await apiClient.getWorkspaceSnapshot(freshSession.accessToken, workspace)
52
- : await apiClient.getWorkspaceContext(freshSession.accessToken, workspace);
40
+ await ensureRuntimeAgentSetup({ rootPath, workspace, git, session: freshSession, apiClient, logger: runtime.logger });
41
+ const payload = search
42
+ ? (delivery
43
+ ? await apiClient.getWorkspaceDeliveryContextSemantic(freshSession.accessToken, workspace, {
44
+ query: search,
45
+ type: getStringOption(parsed, "type")?.trim(),
46
+ authority: getStringOption(parsed, "authority")?.trim(),
47
+ limit: Number(getStringOption(parsed, "limit") ?? "0") || undefined,
48
+ })
49
+ : await apiClient.searchWorkspaceMemory(freshSession.accessToken, workspace, {
50
+ query: search,
51
+ type: getStringOption(parsed, "type")?.trim(),
52
+ authority: getStringOption(parsed, "authority")?.trim(),
53
+ limit: Number(getStringOption(parsed, "limit") ?? "0") || undefined,
54
+ }))
55
+ : delivery
56
+ ? await apiClient.getWorkspaceDeliveryContext(freshSession.accessToken, workspace)
57
+ : snapshot
58
+ ? await apiClient.getWorkspaceSnapshot(freshSession.accessToken, workspace)
59
+ : await apiClient.getWorkspaceContext(freshSession.accessToken, workspace);
53
60
  process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
54
61
  return 0;
55
62
  }
@@ -1,76 +1,32 @@
1
1
  import { getBooleanOption, getStringOption, parseArgs } from "../core/cli.js";
2
- import { ensureSessionAvailable, loadSession, upsertProfile } from "../core/config.js";
3
- import { collectGitContext } from "../core/git.js";
4
2
  import { runLoginCommand } from "./login.js";
5
- import { collectMachineContext, collectRuntimeContext } from "../core/machine.js";
6
3
  import { loadRuntimeStatus } from "../core/runtime.js";
7
- import { ensureFreshSession } from "../core/session.js";
8
- import { VectorPlaneApiClient } from "../core/api.js";
9
- import { ensureAgentSetupCurrent } from "../core/agent-setup.js";
10
- import { resolveWorkspaceRoot } from "../core/workspace-binding.js";
11
- import { resolveAuthorizedWorkspace } from "../core/workspace-resolution.js";
4
+ import { buildInitLoginArgs, runInitWorkspaceUseCase } from "../core/init-workspace.js";
12
5
  export async function runInitCommand(cliVersion, args) {
13
6
  const parsed = parseArgs(args);
14
7
  const force = getBooleanOption(parsed, "force");
15
8
  const requestedAgent = getStringOption(parsed, "agent");
16
9
  const explicitWorkspace = getStringOption(parsed, "workspace");
17
- const loginArgs = [];
18
- if (getBooleanOption(parsed, "manual")) {
19
- loginArgs.push("--manual");
20
- }
21
- if (getBooleanOption(parsed, "no-browser")) {
22
- loginArgs.push("--no-browser");
23
- }
24
10
  const requestedProfile = getStringOption(parsed, "profile");
25
- if (requestedProfile) {
26
- loginArgs.push("--profile", requestedProfile);
27
- }
28
- let runtime = await loadRuntimeStatus();
29
- let session = await loadSession(runtime.profile.name);
30
- if (!session) {
31
- runtime.logger.info("sessão local ausente, iniciando login...");
32
- await runLoginCommand(cliVersion, loginArgs);
33
- runtime = await loadRuntimeStatus();
34
- session = await ensureSessionAvailable(runtime.profile.name);
35
- }
36
- const [git, machine, runtimeContext] = await Promise.all([
37
- collectGitContext(process.cwd()),
38
- collectMachineContext(runtime.device, runtime.config),
39
- collectRuntimeContext(cliVersion, "init", process.argv.slice(2)),
40
- ]);
41
- const apiClient = new VectorPlaneApiClient(runtime.profile.apiBaseUrl, runtime.config.requestTimeoutMs, runtime.logger);
42
- const freshSession = await ensureFreshSession({
43
- profileName: runtime.profile.name,
44
- session,
45
- machine,
46
- runtime: runtimeContext,
47
- device: runtime.device,
48
- apiClient,
49
- logger: runtime.logger,
11
+ const loginArgs = await buildInitLoginArgs({
12
+ manual: getBooleanOption(parsed, "manual"),
13
+ noBrowser: getBooleanOption(parsed, "no-browser"),
14
+ profile: requestedProfile ?? undefined,
50
15
  });
51
- const rootPath = resolveWorkspaceRoot(process.cwd(), git);
52
- const workspace = await resolveAuthorizedWorkspace({
53
- apiClient,
54
- accessToken: freshSession.accessToken,
55
- git,
56
- explicitWorkspace: explicitWorkspace ?? undefined,
57
- profile: runtime.profile,
58
- session: freshSession,
59
- });
60
- const result = await ensureAgentSetupCurrent({
61
- rootPath,
62
- workspace,
63
- repoUrl: git.remoteOrigin,
64
- source: git.remoteOrigin ? "api-resolve" : "manual",
65
- accessToken: freshSession.accessToken,
66
- apiClient,
67
- logger: runtime.logger,
68
- explicitAgent: requestedAgent,
16
+ const runtime = await loadRuntimeStatus();
17
+ const result = await runInitWorkspaceUseCase({
18
+ cliVersion,
19
+ commandArgs: process.argv.slice(2),
20
+ runtime,
69
21
  force,
22
+ explicitWorkspace: explicitWorkspace ?? undefined,
23
+ requestedAgent,
24
+ ensureLoggedIn: async () => {
25
+ await runLoginCommand(cliVersion, loginArgs);
26
+ },
70
27
  });
71
- await upsertProfile(runtime.profile.name, { workspace });
72
28
  runtime.logger.success("workspace inicializado.");
73
- process.stdout.write(`Workspace: ${workspace}\n`);
29
+ process.stdout.write(`Workspace: ${result.workspace}\n`);
74
30
  process.stdout.write(`Agente configurado: ${result.agent}\n`);
75
31
  process.stdout.write(`Confiança da detecção: ${result.confidence}\n`);
76
32
  process.stdout.write(`Template: ${result.templatePath} (${result.fileStatus})\n`);
@@ -0,0 +1 @@
1
+ export declare function runRegistryCommand(args: string[]): Promise<number>;
@@ -0,0 +1,116 @@
1
+ import { getBooleanOption, getStringListOption, getStringOption, parseArgs, parseJsonOption, requirePositional } from "../core/cli.js";
2
+ import { ensureSessionAvailable } from "../core/config.js";
3
+ import { loadRuntimeStatus } from "../core/runtime.js";
4
+ import { VectorPlaneApiClient } from "../core/api.js";
5
+ import { ValidationError } from "../core/errors.js";
6
+ function printJsonIfRequested(parsed, payload) {
7
+ if (!getBooleanOption(parsed, "json")) {
8
+ return false;
9
+ }
10
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
11
+ return true;
12
+ }
13
+ function printAgent(agent) {
14
+ process.stdout.write(`Agent: ${agent.id}\n`);
15
+ process.stdout.write(`Nome: ${agent.name}\n`);
16
+ process.stdout.write(`Runtime: ${agent.runtimeType}\n`);
17
+ process.stdout.write(`Provider: ${agent.provider}\n`);
18
+ process.stdout.write(`Model: ${agent.model}\n`);
19
+ process.stdout.write(`Status: ${agent.status}\n`);
20
+ process.stdout.write(`Reliability: ${String(agent.reliabilityScore)}\n`);
21
+ process.stdout.write(`Capabilities: ${agent.capabilities.join(", ")}\n`);
22
+ if (agent.metadata && Object.keys(agent.metadata).length > 0) {
23
+ process.stdout.write(`Metadata: ${JSON.stringify(agent.metadata)}\n`);
24
+ }
25
+ }
26
+ async function resolveRegistryContext() {
27
+ const runtime = await loadRuntimeStatus();
28
+ const session = await ensureSessionAvailable(runtime.profile.name);
29
+ const apiClient = new VectorPlaneApiClient(runtime.profile.apiBaseUrl, runtime.config.requestTimeoutMs, runtime.logger);
30
+ return { runtime, session, apiClient };
31
+ }
32
+ export async function runRegistryCommand(args) {
33
+ const parsed = parseArgs(args);
34
+ const subcommand = requirePositional(parsed, 0, "Uso: vp registry <list|register|update|deactivate> [...]");
35
+ const { runtime, session, apiClient } = await resolveRegistryContext();
36
+ if (subcommand === "list") {
37
+ const agents = await apiClient.listAgentRegistry(session.accessToken);
38
+ if (printJsonIfRequested(parsed, agents))
39
+ return 0;
40
+ if (agents.length === 0) {
41
+ process.stdout.write("VectorPlane: nenhum agente registrado.\n");
42
+ return 0;
43
+ }
44
+ for (const agent of agents) {
45
+ process.stdout.write(`${agent.id} | ${agent.status} | ${agent.runtimeType} | ${agent.provider}/${agent.model} | ${agent.name}\n`);
46
+ }
47
+ return 0;
48
+ }
49
+ if (subcommand === "register") {
50
+ const name = getStringOption(parsed, "name")?.trim();
51
+ const runtimeType = getStringOption(parsed, "runtime")?.trim();
52
+ const provider = getStringOption(parsed, "provider")?.trim();
53
+ const model = getStringOption(parsed, "model")?.trim();
54
+ if (!name || !runtimeType || !provider || !model) {
55
+ throw new ValidationError("Informe `--name`, `--runtime`, `--provider` e `--model`.");
56
+ }
57
+ const agent = await apiClient.createRegistryAgent(session.accessToken, {
58
+ orgId: getStringOption(parsed, "org-id")?.trim() || undefined,
59
+ name,
60
+ runtimeType,
61
+ provider,
62
+ model,
63
+ capabilities: getStringListOption(parsed, "capabilities"),
64
+ costProfile: getStringOption(parsed, "cost")?.trim() || "standard",
65
+ latencyProfile: getStringOption(parsed, "latency")?.trim() || "standard",
66
+ reliabilityScore: Number(getStringOption(parsed, "reliability") ?? "0.9"),
67
+ status: getStringOption(parsed, "status")?.trim() || "active",
68
+ metadata: parseJsonOption(getStringOption(parsed, "metadata")),
69
+ });
70
+ runtime.logger.success("agente registrado.");
71
+ if (!printJsonIfRequested(parsed, agent)) {
72
+ printAgent(agent);
73
+ }
74
+ return 0;
75
+ }
76
+ if (subcommand === "update") {
77
+ const agentId = requirePositional(parsed, 1, "Informe o identificador do agente.");
78
+ const payload = {};
79
+ if (parsed.options.name !== undefined)
80
+ payload.name = getStringOption(parsed, "name")?.trim();
81
+ if (parsed.options.provider !== undefined)
82
+ payload.provider = getStringOption(parsed, "provider")?.trim();
83
+ if (parsed.options.model !== undefined)
84
+ payload.model = getStringOption(parsed, "model")?.trim();
85
+ if (parsed.options.capabilities !== undefined)
86
+ payload.capabilities = getStringListOption(parsed, "capabilities");
87
+ if (parsed.options.cost !== undefined)
88
+ payload.costProfile = getStringOption(parsed, "cost")?.trim();
89
+ if (parsed.options.latency !== undefined)
90
+ payload.latencyProfile = getStringOption(parsed, "latency")?.trim();
91
+ if (parsed.options.reliability !== undefined)
92
+ payload.reliabilityScore = Number(getStringOption(parsed, "reliability"));
93
+ if (parsed.options.status !== undefined)
94
+ payload.status = getStringOption(parsed, "status")?.trim();
95
+ if (parsed.options.metadata !== undefined)
96
+ payload.metadata = parseJsonOption(getStringOption(parsed, "metadata"));
97
+ if (Object.keys(payload).length === 0) {
98
+ throw new ValidationError("Informe ao menos um campo para atualização.");
99
+ }
100
+ const agent = await apiClient.updateRegistryAgent(session.accessToken, agentId, payload);
101
+ runtime.logger.success("agente atualizado.");
102
+ if (!printJsonIfRequested(parsed, agent)) {
103
+ printAgent(agent);
104
+ }
105
+ return 0;
106
+ }
107
+ if (subcommand === "deactivate") {
108
+ const agentId = requirePositional(parsed, 1, "Informe o identificador do agente.");
109
+ await apiClient.deactivateRegistryAgent(session.accessToken, agentId);
110
+ runtime.logger.success("agente desativado.");
111
+ process.stdout.write(`Agent deactivated: ${agentId}\n`);
112
+ return 0;
113
+ }
114
+ throw new ValidationError("Subcomando de registry não suportado.");
115
+ }
116
+ //# sourceMappingURL=registry.js.map
@@ -7,7 +7,7 @@ import { ensureFreshSession, resolveWorkspaceSlug } from "../core/session.js";
7
7
  import { VectorPlaneApiClient } from "../core/api.js";
8
8
  import { deriveClientInstanceId, getBoundWorkspace, resolveWorkspaceRoot } from "../core/workspace-binding.js";
9
9
  import { ValidationError } from "../core/errors.js";
10
- import { ensureAgentSetupCurrent } from "../core/agent-setup.js";
10
+ import { ensureRuntimeAgentSetup } from "../core/runtime-agent-setup.js";
11
11
  function readCollaborationMetadata(parsed, rootPath) {
12
12
  const owningPaths = getStringListOption(parsed, "owning-path");
13
13
  const needs = getStringListOption(parsed, "need");
@@ -57,15 +57,7 @@ export async function runSessionCommand(cliVersion, args) {
57
57
  if (!workspace) {
58
58
  throw new ValidationError("Nenhum workspace resolvido para a sessão.");
59
59
  }
60
- await ensureAgentSetupCurrent({
61
- rootPath,
62
- workspace,
63
- repoUrl: git.remoteOrigin,
64
- source: git.remoteOrigin ? "api-resolve" : "manual",
65
- accessToken: freshSession.accessToken,
66
- apiClient,
67
- logger: runtime.logger,
68
- });
60
+ await ensureRuntimeAgentSetup({ rootPath, workspace, git, session: freshSession, apiClient, logger: runtime.logger });
69
61
  const clientInstanceId = getStringOption(parsed, "client-instance-id") ?? deriveClientInstanceId(runtime.device.machineId, rootPath, git);
70
62
  const metadata = readCollaborationMetadata(parsed, rootPath);
71
63
  if (subcommand === "check-in") {
@@ -10,7 +10,7 @@ import { VectorPlaneApiClient } from "../core/api.js";
10
10
  import { collectWorkspaceContext } from "../core/workspace.js";
11
11
  import { getBoundWorkspace } from "../core/workspace-binding.js";
12
12
  import { ValidationError } from "../core/errors.js";
13
- import { ensureAgentSetupCurrent } from "../core/agent-setup.js";
13
+ import { ensureRuntimeAgentSetup } from "../core/runtime-agent-setup.js";
14
14
  export async function runSyncCommand(cliVersion, args) {
15
15
  const parsed = parseArgs(args);
16
16
  const force = getBooleanOption(parsed, "force");
@@ -40,12 +40,11 @@ export async function runSyncCommand(cliVersion, args) {
40
40
  if (!workspaceSlug) {
41
41
  throw new ValidationError("Nenhum workspace ativo foi resolvido. Use `vp workspace use <workspace>` ou `vp login`.");
42
42
  }
43
- await ensureAgentSetupCurrent({
43
+ await ensureRuntimeAgentSetup({
44
44
  rootPath: workspaceRoot,
45
45
  workspace: workspaceSlug,
46
- repoUrl: git.remoteOrigin,
47
- source: git.remoteOrigin ? "api-resolve" : "manual",
48
- accessToken: freshSession.accessToken,
46
+ git,
47
+ session: freshSession,
49
48
  apiClient,
50
49
  logger: runtime.logger,
51
50
  });
@@ -0,0 +1 @@
1
+ export declare function runTaskCommand(cliVersion: string, args: string[]): Promise<number>;