@vectorplane/ctrl-cli 0.1.10 → 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.
@@ -0,0 +1,13 @@
1
+ export type SupportedAgent = "claude" | "cursor" | "windsurf" | "copilot" | "codex" | "generic";
2
+ export type DetectionConfidence = "high" | "medium" | "low";
3
+ export interface AgentDetectionResult {
4
+ selected: SupportedAgent | null;
5
+ confidence: DetectionConfidence;
6
+ reasons: string[];
7
+ candidates: SupportedAgent[];
8
+ }
9
+ export declare function detectAgentRuntime(rootPath: string): Promise<AgentDetectionResult>;
10
+ export declare function resolveAgentSelection(rootPath: string, explicitAgent?: SupportedAgent): Promise<{
11
+ agent: SupportedAgent;
12
+ detection: AgentDetectionResult;
13
+ }>;
@@ -0,0 +1,117 @@
1
+ import { access } from "node:fs/promises";
2
+ import { constants as fsConstants } from "node:fs";
3
+ import path from "node:path";
4
+ import readline from "node:readline/promises";
5
+ import { ValidationError } from "./errors.js";
6
+ async function pathExists(filePath) {
7
+ try {
8
+ await access(filePath, fsConstants.F_OK);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ function uniqueAgents(values) {
16
+ return [...new Set(values)];
17
+ }
18
+ export async function detectAgentRuntime(rootPath) {
19
+ const scores = new Map();
20
+ const reasons = new Map();
21
+ const addScore = (agent, amount, reason) => {
22
+ scores.set(agent, (scores.get(agent) ?? 0) + amount);
23
+ reasons.set(agent, [...(reasons.get(agent) ?? []), reason]);
24
+ };
25
+ const fileCandidates = [
26
+ { agent: "claude", file: path.join(rootPath, "CLAUDE.md") },
27
+ { agent: "cursor", file: path.join(rootPath, ".cursor") },
28
+ { agent: "windsurf", file: path.join(rootPath, ".windsurfrules") },
29
+ { agent: "copilot", file: path.join(rootPath, ".github", "copilot-instructions.md") },
30
+ { agent: "codex", file: path.join(rootPath, "AGENTS.md") },
31
+ ];
32
+ for (const candidate of fileCandidates) {
33
+ if (await pathExists(candidate.file)) {
34
+ addScore(candidate.agent, 25, `file:${path.relative(rootPath, candidate.file) || candidate.file}`);
35
+ }
36
+ }
37
+ const envSignals = [
38
+ { agent: "cursor", value: process.env.CURSOR_TRACE_ID, reason: "env:CURSOR_TRACE_ID" },
39
+ { agent: "windsurf", value: process.env.WINDSURF_SESSION_ID, reason: "env:WINDSURF_SESSION_ID" },
40
+ { agent: "codex", value: process.env.CODEX_ENV, reason: "env:CODEX_ENV" },
41
+ { agent: "claude", value: process.env.CLAUDECODE, reason: "env:CLAUDECODE" },
42
+ { agent: "copilot", value: process.env.GITHUB_COPILOT, reason: "env:GITHUB_COPILOT" },
43
+ ];
44
+ for (const signal of envSignals) {
45
+ if (signal.value) {
46
+ addScore(signal.agent, 100, signal.reason);
47
+ }
48
+ }
49
+ const ranked = [...scores.entries()].sort((left, right) => right[1] - left[1]);
50
+ if (ranked.length === 0) {
51
+ return { selected: null, confidence: "low", reasons: [], candidates: [] };
52
+ }
53
+ const topScore = ranked[0][1];
54
+ const candidates = uniqueAgents(ranked.filter((entry) => entry[1] === topScore).map(([agent]) => agent));
55
+ const selected = candidates.length === 1 ? candidates[0] : null;
56
+ return {
57
+ selected,
58
+ confidence: topScore >= 100 ? "high" : candidates.length === 1 ? "medium" : "low",
59
+ reasons: selected ? (reasons.get(selected) ?? []) : candidates.flatMap((agent) => reasons.get(agent) ?? []),
60
+ candidates,
61
+ };
62
+ }
63
+ async function promptForAgent(detection) {
64
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
65
+ throw new ValidationError("Não foi possível detectar o agente local com segurança. Use --agent claude|cursor|windsurf|copilot|codex|generic.");
66
+ }
67
+ const ordered = uniqueAgents([
68
+ ...detection.candidates,
69
+ "claude",
70
+ "cursor",
71
+ "windsurf",
72
+ "copilot",
73
+ "codex",
74
+ "generic",
75
+ ]);
76
+ process.stdout.write("VectorPlane: não foi possível identificar o agente local com segurança.\n");
77
+ ordered.forEach((agent, index) => {
78
+ process.stdout.write(` ${index + 1}. ${agent}\n`);
79
+ });
80
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
81
+ try {
82
+ const answer = (await rl.question("Selecione o agente local: ")).trim();
83
+ const index = Number(answer);
84
+ if (Number.isInteger(index) && index >= 1 && index <= ordered.length) {
85
+ return ordered[index - 1];
86
+ }
87
+ if (ordered.includes(answer)) {
88
+ return answer;
89
+ }
90
+ }
91
+ finally {
92
+ rl.close();
93
+ }
94
+ throw new ValidationError("Seleção de agente inválida.");
95
+ }
96
+ export async function resolveAgentSelection(rootPath, explicitAgent) {
97
+ if (explicitAgent) {
98
+ return {
99
+ agent: explicitAgent,
100
+ detection: {
101
+ selected: explicitAgent,
102
+ confidence: "high",
103
+ reasons: ["explicit-flag"],
104
+ candidates: [explicitAgent],
105
+ },
106
+ };
107
+ }
108
+ const detection = await detectAgentRuntime(rootPath);
109
+ if (detection.selected && detection.confidence !== "low") {
110
+ return { agent: detection.selected, detection };
111
+ }
112
+ return {
113
+ agent: await promptForAgent(detection),
114
+ detection,
115
+ };
116
+ }
117
+ //# sourceMappingURL=agent-runtime-detection.js.map
@@ -0,0 +1,20 @@
1
+ import type { VectorPlaneApiClient } from "./api.js";
2
+ import type { Logger } from "./logger.js";
3
+ import { type DetectionConfidence, type SupportedAgent } from "./agent-runtime-detection.js";
4
+ export declare function ensureAgentSetupCurrent(params: {
5
+ rootPath: string;
6
+ workspace: string;
7
+ repoUrl: string | null;
8
+ source: "manual" | "api-resolve" | "session";
9
+ accessToken: string;
10
+ apiClient: VectorPlaneApiClient;
11
+ logger: Logger;
12
+ explicitAgent?: SupportedAgent;
13
+ force?: boolean;
14
+ }): Promise<{
15
+ agent: SupportedAgent;
16
+ templatePath: string;
17
+ fileStatus: "created" | "updated" | "unchanged";
18
+ changed: boolean;
19
+ confidence: DetectionConfidence;
20
+ }>;
@@ -0,0 +1,119 @@
1
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { constants as fsConstants } from "node:fs";
3
+ import path from "node:path";
4
+ import { ValidationError } from "./errors.js";
5
+ import { bindWorkspaceToRoot, getWorkspaceBinding } from "./workspace-binding.js";
6
+ import { detectAgentRuntime, resolveAgentSelection, } from "./agent-runtime-detection.js";
7
+ const AGENT_TEMPLATE_PATHS = {
8
+ claude: "CLAUDE.md",
9
+ cursor: ".cursor/rules/traceplane.mdc",
10
+ windsurf: ".windsurfrules",
11
+ copilot: ".github/copilot-instructions.md",
12
+ codex: "AGENTS.md",
13
+ generic: "AGENTS.md",
14
+ };
15
+ async function pathExists(filePath) {
16
+ try {
17
+ await access(filePath, fsConstants.F_OK);
18
+ return true;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ async function appendGitIgnoreEntry(rootPath, relativeTarget) {
25
+ const gitIgnorePath = path.join(rootPath, ".gitignore");
26
+ const normalizedEntry = relativeTarget.replace(/\\/g, "/");
27
+ const current = await readFile(gitIgnorePath, "utf8").catch(() => "");
28
+ const lines = current.split(/\r?\n/).map((line) => line.trim());
29
+ if (lines.includes(normalizedEntry)) {
30
+ return;
31
+ }
32
+ const next = current.trimEnd();
33
+ const updated = `${next}${next ? "\n" : ""}${normalizedEntry}\n`;
34
+ await writeFile(gitIgnorePath, updated, "utf8");
35
+ }
36
+ async function writeTemplateFile(rootPath, relativeTarget, content, force) {
37
+ const absoluteTarget = path.join(rootPath, relativeTarget);
38
+ await mkdir(path.dirname(absoluteTarget), { recursive: true });
39
+ if (await pathExists(absoluteTarget)) {
40
+ const current = await readFile(absoluteTarget, "utf8");
41
+ if (current === content) {
42
+ return "unchanged";
43
+ }
44
+ if (!force) {
45
+ throw new ValidationError(`O arquivo ${relativeTarget} já existe. Use --force para sobrescrever.`);
46
+ }
47
+ await writeFile(absoluteTarget, content, "utf8");
48
+ return "updated";
49
+ }
50
+ await writeFile(absoluteTarget, content, "utf8");
51
+ return "created";
52
+ }
53
+ function getAgentTemplate(setup, agent) {
54
+ const template = setup.agents[agent];
55
+ if (!template) {
56
+ throw new ValidationError(`O backend não retornou template para o agente ${agent}.`);
57
+ }
58
+ return template;
59
+ }
60
+ export async function ensureAgentSetupCurrent(params) {
61
+ const binding = await getWorkspaceBinding(params.rootPath);
62
+ let selection;
63
+ if (!params.explicitAgent && binding?.configuredAgent) {
64
+ const detection = await detectAgentRuntime(params.rootPath);
65
+ if (!detection.selected && detection.confidence === "low") {
66
+ selection = {
67
+ agent: binding.configuredAgent,
68
+ detection: {
69
+ selected: binding.configuredAgent,
70
+ confidence: "low",
71
+ reasons: ["binding-fallback"],
72
+ candidates: [binding.configuredAgent],
73
+ },
74
+ };
75
+ }
76
+ else {
77
+ selection = await resolveAgentSelection(params.rootPath, params.explicitAgent);
78
+ }
79
+ }
80
+ else {
81
+ selection = await resolveAgentSelection(params.rootPath, params.explicitAgent);
82
+ }
83
+ const { agent, detection } = selection;
84
+ const expectedPath = AGENT_TEMPLATE_PATHS[agent];
85
+ if (binding?.workspace === params.workspace && binding.configuredAgent === agent && binding.templatePath === expectedPath && await pathExists(path.join(params.rootPath, expectedPath))) {
86
+ return {
87
+ agent,
88
+ templatePath: expectedPath,
89
+ fileStatus: "unchanged",
90
+ changed: false,
91
+ confidence: detection.confidence,
92
+ };
93
+ }
94
+ const setup = await params.apiClient.getAgentSetup(params.accessToken, params.workspace);
95
+ const template = getAgentTemplate(setup, agent);
96
+ const fileStatus = await writeTemplateFile(params.rootPath, template.filename, template.content, params.force ?? false);
97
+ await appendGitIgnoreEntry(params.rootPath, template.filename);
98
+ await bindWorkspaceToRoot({
99
+ rootPath: params.rootPath,
100
+ workspace: params.workspace,
101
+ repoUrl: params.repoUrl,
102
+ source: params.source,
103
+ configuredAgent: agent,
104
+ agentConfidence: detection.confidence,
105
+ templatePath: template.filename,
106
+ agentConfiguredAt: new Date().toISOString(),
107
+ });
108
+ if (binding?.configuredAgent && binding.configuredAgent !== agent) {
109
+ params.logger.info(`agente ativo detectado mudou de ${binding.configuredAgent} para ${agent}; setup local atualizado.`);
110
+ }
111
+ return {
112
+ agent,
113
+ templatePath: template.filename,
114
+ fileStatus,
115
+ changed: true,
116
+ confidence: detection.confidence,
117
+ };
118
+ }
119
+ //# sourceMappingURL=agent-setup.js.map
@@ -1,6 +1,6 @@
1
1
  import type { Logger } from "./logger.js";
2
2
  import type { CurrentUserResponse, AuthCodeExchangeRequest, AuthTokenExchangeResponse, CreateLoginAttemptRequest, CreateLoginAttemptResponse, LoginAttemptStatusResponse, RefreshTokenRequest } from "../types/auth.js";
3
- import type { AgentCheckoutRequest, AgentHeartbeatRequest, AgentSessionRequest, AgentSessionResponse, EventRequest, MemoryDraftCreateRequest, MemoryDraftRecord, MemoryDraftStatus, ResolveWorkspaceRequest, ResolveWorkspaceResponse, SyncRequest, SyncResponse } from "../types/api.js";
3
+ import type { AgentCheckoutRequest, AgentHeartbeatRequest, AgentSessionRequest, AgentSessionResponse, EventRequest, MemoryDraftCreateRequest, MemoryDraftRecord, MemoryDraftStatus, MemorySearchRecord, ClaimableTaskStepRecord, ClaimedTaskStepResponse, TaskCreateRequest, TaskHandoffRecord, TaskObservabilityRecord, TaskRecord, ResolveWorkspaceRequest, ResolveWorkspaceResponse, SyncRequest, SyncResponse, WorkspaceAgentSetup, WorkspacePolicyRuleRecord, AgentRegistryRecord, TaskTemplateRecord } from "../types/api.js";
4
4
  export declare class VectorPlaneApiClient {
5
5
  private readonly apiBaseUrl;
6
6
  private readonly timeoutMs;
@@ -21,9 +21,99 @@ export declare class VectorPlaneApiClient {
21
21
  getWorkspaceContext(accessToken: string, workspaceId: string): Promise<Record<string, unknown>>;
22
22
  getWorkspaceSnapshot(accessToken: string, workspaceId: string): Promise<Record<string, unknown>>;
23
23
  getWorkspaceDeliveryContext(accessToken: string, workspaceId: string): Promise<Record<string, unknown>>;
24
- getAgentSetup(accessToken: string, workspaceId: string): Promise<Record<string, unknown>>;
24
+ getWorkspaceDeliveryContextSemantic(accessToken: string, workspaceId: string, params: {
25
+ query: string;
26
+ type?: string;
27
+ authority?: string;
28
+ limit?: number;
29
+ }): Promise<Record<string, unknown>>;
30
+ getAgentSetup(accessToken: string, workspaceId: string): Promise<WorkspaceAgentSetup>;
31
+ listWorkspacePolicyRules(accessToken: string, workspaceRef: string): Promise<WorkspacePolicyRuleRecord[]>;
32
+ createWorkspacePolicyRule(accessToken: string, workspaceRef: string, payload: {
33
+ name: string;
34
+ pathPrefix?: string;
35
+ capability?: string;
36
+ effect: WorkspacePolicyRuleRecord["effect"];
37
+ rationale?: string;
38
+ conditions?: WorkspacePolicyRuleRecord["conditions"];
39
+ approvalRole?: string;
40
+ enabled?: boolean;
41
+ }): Promise<WorkspacePolicyRuleRecord>;
42
+ updateWorkspacePolicyRule(accessToken: string, workspaceRef: string, ruleId: string, payload: {
43
+ name?: string;
44
+ pathPrefix?: string | null;
45
+ capability?: string | null;
46
+ effect?: WorkspacePolicyRuleRecord["effect"];
47
+ rationale?: string | null;
48
+ conditions?: WorkspacePolicyRuleRecord["conditions"] | null;
49
+ approvalRole?: string | null;
50
+ enabled?: boolean;
51
+ }): Promise<WorkspacePolicyRuleRecord>;
25
52
  listMemoryDrafts(accessToken: string, workspaceRef: string, status?: MemoryDraftStatus): Promise<MemoryDraftRecord[]>;
26
53
  createMemoryDraft(accessToken: string, workspaceRef: string, payload: MemoryDraftCreateRequest): Promise<MemoryDraftRecord>;
54
+ searchWorkspaceMemory(accessToken: string, workspaceRef: string, params: {
55
+ query: string;
56
+ type?: string;
57
+ authority?: string;
58
+ limit?: number;
59
+ }): Promise<MemorySearchRecord[]>;
60
+ listTasks(accessToken: string, workspaceRef: string): Promise<TaskRecord[]>;
61
+ createTask(accessToken: string, workspaceRef: string, payload: TaskCreateRequest): Promise<TaskRecord>;
62
+ listTaskTemplates(accessToken: string): Promise<TaskTemplateRecord[]>;
63
+ getTask(accessToken: string, workspaceRef: string, taskId: string): Promise<TaskRecord>;
64
+ listClaimableTaskSteps(accessToken: string, workspaceRef: string, filters?: {
65
+ capability?: string;
66
+ agentName?: string;
67
+ }): Promise<ClaimableTaskStepRecord[]>;
68
+ claimTaskStep(accessToken: string, workspaceRef: string, taskId: string, stepId: string, payload?: {
69
+ sessionId?: string;
70
+ clientInstanceId?: string;
71
+ agentName?: string;
72
+ }): Promise<ClaimedTaskStepResponse>;
73
+ delegateTask(accessToken: string, workspaceRef: string, taskId: string, stepId: string, toAgentId: string, reason: string): Promise<TaskRecord>;
74
+ callbackTaskStep(accessToken: string, workspaceRef: string, taskId: string, stepId: string, payload: {
75
+ status: "running" | "completed" | "failed" | "blocked";
76
+ agentId?: string;
77
+ output?: Record<string, unknown>;
78
+ error?: string;
79
+ }): Promise<TaskRecord>;
80
+ getTaskHandoff(accessToken: string, workspaceRef: string, taskId: string): Promise<TaskHandoffRecord>;
81
+ getTaskObservability(accessToken: string, workspaceRef: string, taskId: string): Promise<TaskObservabilityRecord>;
82
+ getWorkspaceTaskObservability(accessToken: string, workspaceRef: string): Promise<TaskObservabilityRecord>;
83
+ approveTask(accessToken: string, workspaceRef: string, taskId: string, payload: {
84
+ approved: boolean;
85
+ approvedBy?: string;
86
+ rationale?: string;
87
+ }): Promise<TaskRecord>;
88
+ listAgentRegistry(accessToken: string): Promise<AgentRegistryRecord[]>;
89
+ createRegistryAgent(accessToken: string, payload: {
90
+ orgId?: string;
91
+ name: string;
92
+ runtimeType: string;
93
+ provider: string;
94
+ model: string;
95
+ capabilities: string[];
96
+ costProfile: string;
97
+ latencyProfile: string;
98
+ reliabilityScore: number;
99
+ status?: string;
100
+ metadata?: Record<string, unknown>;
101
+ }): Promise<AgentRegistryRecord>;
102
+ updateRegistryAgent(accessToken: string, agentId: string, payload: {
103
+ name?: string;
104
+ provider?: string;
105
+ model?: string;
106
+ capabilities?: string[];
107
+ costProfile?: string;
108
+ latencyProfile?: string;
109
+ reliabilityScore?: number;
110
+ status?: string;
111
+ metadata?: Record<string, unknown>;
112
+ }): Promise<AgentRegistryRecord>;
113
+ deactivateRegistryAgent(accessToken: string, agentId: string): Promise<{
114
+ deactivated: boolean;
115
+ }>;
116
+ getWorkspaceHealth(accessToken: string, workspaceRef: string): Promise<Record<string, unknown>>;
27
117
  checkInAgent(accessToken: string, payload: AgentSessionRequest): Promise<AgentSessionResponse>;
28
118
  heartbeatAgent(accessToken: string, payload: AgentHeartbeatRequest): Promise<AgentSessionResponse>;
29
119
  checkOutAgent(accessToken: string, payload: AgentCheckoutRequest): Promise<AgentSessionResponse>;
package/dist/core/api.js CHANGED
@@ -152,6 +152,26 @@ export class VectorPlaneApiClient {
152
152
  },
153
153
  }, this.timeoutMs, this.logger);
154
154
  }
155
+ async getWorkspaceDeliveryContextSemantic(accessToken, workspaceId, params) {
156
+ const url = new URL(`${this.apiBaseUrl}/cli/workspace/${workspaceId}/delivery-context`);
157
+ url.searchParams.set("mode", "semantic");
158
+ url.searchParams.set("query", params.query);
159
+ if (params.type) {
160
+ url.searchParams.set("type", params.type);
161
+ }
162
+ if (params.authority) {
163
+ url.searchParams.set("authority", params.authority);
164
+ }
165
+ if (typeof params.limit === "number") {
166
+ url.searchParams.set("limit", String(params.limit));
167
+ }
168
+ return requestJson(url.toString(), {
169
+ method: "GET",
170
+ headers: {
171
+ "Authorization": `Bearer ${accessToken}`,
172
+ },
173
+ }, this.timeoutMs, this.logger);
174
+ }
155
175
  async getAgentSetup(accessToken, workspaceId) {
156
176
  return requestJson(`${this.apiBaseUrl}/cli/workspace/${workspaceId}/agent-setup`, {
157
177
  method: "GET",
@@ -160,6 +180,28 @@ export class VectorPlaneApiClient {
160
180
  },
161
181
  }, this.timeoutMs, this.logger);
162
182
  }
183
+ async listWorkspacePolicyRules(accessToken, workspaceRef) {
184
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/policy-rules`, {
185
+ method: "GET",
186
+ headers: {
187
+ "Authorization": `Bearer ${accessToken}`,
188
+ },
189
+ }, this.timeoutMs, this.logger);
190
+ }
191
+ async createWorkspacePolicyRule(accessToken, workspaceRef, payload) {
192
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/policy-rules`, {
193
+ method: "POST",
194
+ headers: authHeaders(accessToken),
195
+ body: JSON.stringify(payload),
196
+ }, this.timeoutMs, this.logger);
197
+ }
198
+ async updateWorkspacePolicyRule(accessToken, workspaceRef, ruleId, payload) {
199
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/policy-rules/${ruleId}`, {
200
+ method: "PUT",
201
+ headers: authHeaders(accessToken),
202
+ body: JSON.stringify(payload),
203
+ }, this.timeoutMs, this.logger);
204
+ }
163
205
  async listMemoryDrafts(accessToken, workspaceRef, status) {
164
206
  const url = new URL(`${this.apiBaseUrl}/cli/workspace/${workspaceRef}/memory-drafts`);
165
207
  if (status) {
@@ -179,6 +221,159 @@ export class VectorPlaneApiClient {
179
221
  body: JSON.stringify(payload),
180
222
  }, this.timeoutMs, this.logger);
181
223
  }
224
+ async searchWorkspaceMemory(accessToken, workspaceRef, params) {
225
+ const url = new URL(`${this.apiBaseUrl}/cli/workspace/${workspaceRef}/memory/search`);
226
+ url.searchParams.set("q", params.query);
227
+ if (params.type) {
228
+ url.searchParams.set("type", params.type);
229
+ }
230
+ if (params.authority) {
231
+ url.searchParams.set("authority", params.authority);
232
+ }
233
+ if (typeof params.limit === "number") {
234
+ url.searchParams.set("limit", String(params.limit));
235
+ }
236
+ return requestJson(url.toString(), {
237
+ method: "GET",
238
+ headers: {
239
+ "Authorization": `Bearer ${accessToken}`,
240
+ },
241
+ }, this.timeoutMs, this.logger);
242
+ }
243
+ async listTasks(accessToken, workspaceRef) {
244
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks`, {
245
+ method: "GET",
246
+ headers: {
247
+ "Authorization": `Bearer ${accessToken}`,
248
+ },
249
+ }, this.timeoutMs, this.logger);
250
+ }
251
+ async createTask(accessToken, workspaceRef, payload) {
252
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks`, {
253
+ method: "POST",
254
+ headers: authHeaders(accessToken),
255
+ body: JSON.stringify(payload),
256
+ }, this.timeoutMs, this.logger);
257
+ }
258
+ async listTaskTemplates(accessToken) {
259
+ return requestJson(`${this.apiBaseUrl}/admin/task-templates`, {
260
+ method: "GET",
261
+ headers: {
262
+ "Authorization": `Bearer ${accessToken}`,
263
+ },
264
+ }, this.timeoutMs, this.logger);
265
+ }
266
+ async getTask(accessToken, workspaceRef, taskId) {
267
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}`, {
268
+ method: "GET",
269
+ headers: {
270
+ "Authorization": `Bearer ${accessToken}`,
271
+ },
272
+ }, this.timeoutMs, this.logger);
273
+ }
274
+ async listClaimableTaskSteps(accessToken, workspaceRef, filters) {
275
+ const url = new URL(`${this.apiBaseUrl}/cli/workspace/${workspaceRef}/tasks/claimable`);
276
+ if (filters?.capability) {
277
+ url.searchParams.set("capability", filters.capability);
278
+ }
279
+ if (filters?.agentName) {
280
+ url.searchParams.set("agent_name", filters.agentName);
281
+ }
282
+ return requestJson(url.toString(), {
283
+ method: "GET",
284
+ headers: {
285
+ "Authorization": `Bearer ${accessToken}`,
286
+ },
287
+ }, this.timeoutMs, this.logger);
288
+ }
289
+ async claimTaskStep(accessToken, workspaceRef, taskId, stepId, payload) {
290
+ return requestJson(`${this.apiBaseUrl}/cli/workspace/${workspaceRef}/tasks/${taskId}/steps/${stepId}/claim`, {
291
+ method: "POST",
292
+ headers: authHeaders(accessToken),
293
+ body: JSON.stringify(payload ?? {}),
294
+ }, this.timeoutMs, this.logger);
295
+ }
296
+ async delegateTask(accessToken, workspaceRef, taskId, stepId, toAgentId, reason) {
297
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}/delegate`, {
298
+ method: "POST",
299
+ headers: authHeaders(accessToken),
300
+ body: JSON.stringify({ stepId, toAgentId, reason }),
301
+ }, this.timeoutMs, this.logger);
302
+ }
303
+ async callbackTaskStep(accessToken, workspaceRef, taskId, stepId, payload) {
304
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}/steps/${stepId}/callback`, {
305
+ method: "POST",
306
+ headers: authHeaders(accessToken),
307
+ body: JSON.stringify(payload),
308
+ }, this.timeoutMs, this.logger);
309
+ }
310
+ async getTaskHandoff(accessToken, workspaceRef, taskId) {
311
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}/handoff`, {
312
+ method: "GET",
313
+ headers: {
314
+ "Authorization": `Bearer ${accessToken}`,
315
+ },
316
+ }, this.timeoutMs, this.logger);
317
+ }
318
+ async getTaskObservability(accessToken, workspaceRef, taskId) {
319
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}/observability`, {
320
+ method: "GET",
321
+ headers: {
322
+ "Authorization": `Bearer ${accessToken}`,
323
+ },
324
+ }, this.timeoutMs, this.logger);
325
+ }
326
+ async getWorkspaceTaskObservability(accessToken, workspaceRef) {
327
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/observability`, {
328
+ method: "GET",
329
+ headers: {
330
+ "Authorization": `Bearer ${accessToken}`,
331
+ },
332
+ }, this.timeoutMs, this.logger);
333
+ }
334
+ async approveTask(accessToken, workspaceRef, taskId, payload) {
335
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/tasks/${taskId}/approve`, {
336
+ method: "POST",
337
+ headers: authHeaders(accessToken),
338
+ body: JSON.stringify(payload),
339
+ }, this.timeoutMs, this.logger);
340
+ }
341
+ async listAgentRegistry(accessToken) {
342
+ return requestJson(`${this.apiBaseUrl}/admin/agent-registry`, {
343
+ method: "GET",
344
+ headers: {
345
+ "Authorization": `Bearer ${accessToken}`,
346
+ },
347
+ }, this.timeoutMs, this.logger);
348
+ }
349
+ async createRegistryAgent(accessToken, payload) {
350
+ return requestJson(`${this.apiBaseUrl}/admin/agent-registry`, {
351
+ method: "POST",
352
+ headers: authHeaders(accessToken),
353
+ body: JSON.stringify(payload),
354
+ }, this.timeoutMs, this.logger);
355
+ }
356
+ async updateRegistryAgent(accessToken, agentId, payload) {
357
+ return requestJson(`${this.apiBaseUrl}/admin/agent-registry/${agentId}`, {
358
+ method: "PUT",
359
+ headers: authHeaders(accessToken),
360
+ body: JSON.stringify(payload),
361
+ }, this.timeoutMs, this.logger);
362
+ }
363
+ async deactivateRegistryAgent(accessToken, agentId) {
364
+ return requestJson(`${this.apiBaseUrl}/admin/agent-registry/${agentId}/deactivate`, {
365
+ method: "POST",
366
+ headers: authHeaders(accessToken),
367
+ }, this.timeoutMs, this.logger);
368
+ }
369
+ async getWorkspaceHealth(accessToken, workspaceRef) {
370
+ return requestJson(`${this.apiBaseUrl}/workspace/${workspaceRef}/health`, {
371
+ method: "GET",
372
+ headers: {
373
+ "Authorization": `Bearer ${accessToken}`,
374
+ },
375
+ }, this.timeoutMs, this.logger);
376
+ }
182
377
  async checkInAgent(accessToken, payload) {
183
378
  return requestJson(`${this.apiBaseUrl}/cli/workspace/${payload.workspaceId}/agents/check-in`, {
184
379
  method: "POST",
@@ -0,0 +1,29 @@
1
+ import type { SupportedAgent } from "./agent-runtime-detection.js";
2
+ import type { CliConfig, CliProfileConfig } from "../types/config.js";
3
+ import type { DeviceIdentity } from "../types/machine.js";
4
+ import type { Logger } from "./logger.js";
5
+ export declare function buildInitLoginArgs(params: {
6
+ manual: boolean;
7
+ noBrowser: boolean;
8
+ profile?: string;
9
+ }): Promise<string[]>;
10
+ export declare function runInitWorkspaceUseCase(params: {
11
+ cliVersion: string;
12
+ commandArgs: string[];
13
+ runtime: {
14
+ profile: CliProfileConfig;
15
+ config: CliConfig;
16
+ device: DeviceIdentity;
17
+ logger: Logger;
18
+ };
19
+ force: boolean;
20
+ explicitWorkspace?: string;
21
+ requestedAgent?: SupportedAgent;
22
+ ensureLoggedIn: () => Promise<void>;
23
+ }): Promise<{
24
+ workspace: string;
25
+ agent: SupportedAgent;
26
+ confidence: string;
27
+ templatePath: string;
28
+ fileStatus: string;
29
+ }>;