@kb-labs/host-agent-entry 2.94.0 → 2.98.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.
@@ -1,4 +1,4 @@
1
- import { defineCommand } from '@kb-labs/sdk';
1
+ import { defineCommand, handleError } from '@kb-labs/sdk';
2
2
  import { readFileSync } from 'fs';
3
3
  import { join } from 'path';
4
4
  import { homedir } from 'os';
@@ -48,11 +48,11 @@ var list_default = defineCommand({
48
48
  const body = await res.json();
49
49
  hosts = body.hosts;
50
50
  } else {
51
- ctx.ui?.error?.(`Failed to list hosts: HTTP ${res.status}`);
51
+ handleError(ctx, new Error(`Failed to list hosts: HTTP ${res.status}`), input.json);
52
52
  return { exitCode: 1, hosts: [] };
53
53
  }
54
54
  } catch (err) {
55
- ctx.ui?.error?.(`Cannot reach Gateway at ${gatewayUrl}: ${err instanceof Error ? err.message : String(err)}`);
55
+ handleError(ctx, new Error(`Cannot reach Gateway at ${gatewayUrl}: ${err instanceof Error ? err.message : String(err)}`), input.json);
56
56
  return { exitCode: 1, hosts: [] };
57
57
  }
58
58
  if (input.json) {
@@ -63,20 +63,6 @@ var list_default = defineCommand({
63
63
  ctx.ui?.info?.("No Workspace Agents connected.");
64
64
  return { exitCode: 0, hosts: [] };
65
65
  }
66
- const statusIcon = (s) => {
67
- switch (s) {
68
- case "online":
69
- return "\x1B[32m\u25CF\x1B[0m";
70
- case "reconnecting":
71
- return "\x1B[33m\u25D0\x1B[0m";
72
- case "degraded":
73
- return "\x1B[33m\u25D0\x1B[0m";
74
- case "offline":
75
- return "\x1B[31m\u25CB\x1B[0m";
76
- default:
77
- return "?";
78
- }
79
- };
80
66
  const ago = (ts) => {
81
67
  const sec = Math.floor((Date.now() - ts) / 1e3);
82
68
  if (sec < 60) {
@@ -90,18 +76,14 @@ var list_default = defineCommand({
90
76
  }
91
77
  return `${Math.floor(sec / 86400)}d ago`;
92
78
  };
93
- const lines = hosts.map(
94
- (h) => ` ${statusIcon(h.status)} ${h.name.padEnd(28)} ${h.status.padEnd(14)} ${(h.capabilities || []).join(", ").padEnd(30)} ${ago(h.lastSeen)}`
95
- );
96
- ctx.ui?.success?.("Workspace Agents", {
79
+ const onlineCount = hosts.filter((h) => h.status === "online").length;
80
+ const offlineCount = hosts.filter((h) => h.status === "offline").length;
81
+ ctx.ui?.success?.(`${onlineCount} online, ${offlineCount} offline (${hosts.length} total)`, {
97
82
  sections: [{
98
- items: [
99
- ` ${"Name".padEnd(30)} ${"Status".padEnd(14)} ${"Capabilities".padEnd(30)} Last Seen`,
100
- ` ${"\u2500".repeat(30)} ${"\u2500".repeat(14)} ${"\u2500".repeat(30)} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,
101
- ...lines,
102
- "",
103
- ` ${hosts.filter((h) => h.status === "online").length} online, ${hosts.filter((h) => h.status === "offline").length} offline (${hosts.length} total)`
104
- ]
83
+ header: "Agents",
84
+ items: hosts.map(
85
+ (h) => `${h.name} ${h.status} ${(h.capabilities || []).join(", ") || "\u2014"} ${ago(h.lastSeen)}`
86
+ )
105
87
  }]
106
88
  });
107
89
  return { exitCode: 0, hosts };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/list.ts"],"names":[],"mappings":"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","file":"list.js","sourcesContent":["/**\n * workspace:list command\n * List all connected Workspace Agents via Gateway REST API.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\ntype ListInput = {\n json?: boolean;\n gateway?: string;\n flags?: ListInput;\n};\n\ninterface HostEntry {\n hostId: string;\n name: string;\n status: string;\n capabilities: string[];\n hostType?: string;\n lastSeen: number;\n connections: string[];\n}\n\ntype ListResult = {\n exitCode: number;\n hosts: HostEntry[];\n};\n\nexport default defineCommand({\n id: 'workspace:list',\n description: 'List all connected Workspace Agents',\n\n handler: {\n async execute(ctx: PluginContextV3, rawInput: ListInput): Promise<ListResult> {\n const input: ListInput = rawInput.flags ?? rawInput;\n\n // Resolve Gateway URL: flag > agent config > env > default\n let gatewayUrl = input.gateway;\n if (!gatewayUrl) {\n try {\n const configPath = join(homedir(), '.kb', 'agent.json');\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n gatewayUrl = config.gatewayUrl;\n } catch {\n // No agent config\n }\n }\n gatewayUrl = gatewayUrl ?? ctx.runtime?.env?.('KB_GATEWAY_URL') ?? 'http://localhost:4000';\n\n // Get auth token\n let token: string | undefined;\n try {\n const configPath = join(homedir(), '.kb', 'agent.json');\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n if (config.clientId && config.clientSecret) {\n const tokenRes = await fetch(`${gatewayUrl}/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: config.clientId, clientSecret: config.clientSecret }),\n });\n if (tokenRes.ok) {\n const body = await tokenRes.json() as { accessToken?: string };\n token = body.accessToken;\n }\n }\n } catch {\n // Auth failed — try without\n }\n\n // Fetch hosts\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n let hosts: HostEntry[] = [];\n try {\n const res = await fetch(`${gatewayUrl}/hosts`, { headers });\n if (res.ok) {\n const body = await res.json() as { hosts: HostEntry[] };\n hosts = body.hosts;\n } else {\n ctx.ui?.error?.(`Failed to list hosts: HTTP ${res.status}`);\n return { exitCode: 1, hosts: [] };\n }\n } catch (err) {\n ctx.ui?.error?.(`Cannot reach Gateway at ${gatewayUrl}: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, hosts: [] };\n }\n\n if (input.json) {\n ctx.ui?.json?.({ hosts });\n return { exitCode: 0, hosts };\n }\n\n if (hosts.length === 0) {\n ctx.ui?.info?.('No Workspace Agents connected.');\n return { exitCode: 0, hosts: [] };\n }\n\n // Format table\n const statusIcon = (s: string) => {\n switch (s) {\n case 'online': return '\\u001b[32m●\\u001b[0m';\n case 'reconnecting': return '\\u001b[33m◐\\u001b[0m';\n case 'degraded': return '\\u001b[33m◐\\u001b[0m';\n case 'offline': return '\\u001b[31m○\\u001b[0m';\n default: return '?';\n }\n };\n\n const ago = (ts: number) => {\n const sec = Math.floor((Date.now() - ts) / 1000);\n if (sec < 60) {return `${sec}s ago`;}\n if (sec < 3600) {return `${Math.floor(sec / 60)}m ago`;}\n if (sec < 86400) {return `${Math.floor(sec / 3600)}h ago`;}\n return `${Math.floor(sec / 86400)}d ago`;\n };\n\n const lines = hosts.map(h =>\n ` ${statusIcon(h.status)} ${h.name.padEnd(28)} ${h.status.padEnd(14)} ${(h.capabilities || []).join(', ').padEnd(30)} ${ago(h.lastSeen)}`\n );\n\n ctx.ui?.success?.('Workspace Agents', {\n sections: [{\n items: [\n ` ${'Name'.padEnd(30)} ${'Status'.padEnd(14)} ${'Capabilities'.padEnd(30)} Last Seen`,\n ` ${'─'.repeat(30)} ${'─'.repeat(14)} ${'─'.repeat(30)} ─────────`,\n ...lines,\n '',\n ` ${hosts.filter(h => h.status === 'online').length} online, ${hosts.filter(h => h.status === 'offline').length} offline (${hosts.length} total)`,\n ],\n }],\n });\n\n return { exitCode: 0, hosts };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/commands/list.ts"],"names":[],"mappings":"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","file":"list.js","sourcesContent":["/**\n * workspace:list command\n * List all connected Workspace Agents via Gateway REST API.\n */\n\nimport { defineCommand, handleError, type PluginContextV3 } from '@kb-labs/sdk';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\ntype ListInput = {\n json?: boolean;\n gateway?: string;\n flags?: ListInput;\n};\n\ninterface HostEntry {\n hostId: string;\n name: string;\n status: string;\n capabilities: string[];\n hostType?: string;\n lastSeen: number;\n connections: string[];\n}\n\ntype ListResult = {\n exitCode: number;\n hosts: HostEntry[];\n};\n\nexport default defineCommand({\n id: 'workspace:list',\n description: 'List all connected Workspace Agents',\n\n handler: {\n async execute(ctx: PluginContextV3, rawInput: ListInput): Promise<ListResult> {\n const input: ListInput = rawInput.flags ?? rawInput;\n\n // Resolve Gateway URL: flag > agent config > env > default\n let gatewayUrl = input.gateway;\n if (!gatewayUrl) {\n try {\n const configPath = join(homedir(), '.kb', 'agent.json');\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n gatewayUrl = config.gatewayUrl;\n } catch {\n // No agent config\n }\n }\n gatewayUrl = gatewayUrl ?? ctx.runtime?.env?.('KB_GATEWAY_URL') ?? 'http://localhost:4000';\n\n // Get auth token\n let token: string | undefined;\n try {\n const configPath = join(homedir(), '.kb', 'agent.json');\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n if (config.clientId && config.clientSecret) {\n const tokenRes = await fetch(`${gatewayUrl}/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientId: config.clientId, clientSecret: config.clientSecret }),\n });\n if (tokenRes.ok) {\n const body = await tokenRes.json() as { accessToken?: string };\n token = body.accessToken;\n }\n }\n } catch {\n // Auth failed — try without\n }\n\n // Fetch hosts\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n let hosts: HostEntry[] = [];\n try {\n const res = await fetch(`${gatewayUrl}/hosts`, { headers });\n if (res.ok) {\n const body = await res.json() as { hosts: HostEntry[] };\n hosts = body.hosts;\n } else {\n handleError(ctx, new Error(`Failed to list hosts: HTTP ${res.status}`), input.json);\n return { exitCode: 1, hosts: [] };\n }\n } catch (err) {\n handleError(ctx, new Error(`Cannot reach Gateway at ${gatewayUrl}: ${err instanceof Error ? err.message : String(err)}`), input.json);\n return { exitCode: 1, hosts: [] };\n }\n\n if (input.json) {\n ctx.ui?.json?.({ hosts });\n return { exitCode: 0, hosts };\n }\n\n if (hosts.length === 0) {\n ctx.ui?.info?.('No Workspace Agents connected.');\n return { exitCode: 0, hosts: [] };\n }\n\n const ago = (ts: number) => {\n const sec = Math.floor((Date.now() - ts) / 1000);\n if (sec < 60) {return `${sec}s ago`;}\n if (sec < 3600) {return `${Math.floor(sec / 60)}m ago`;}\n if (sec < 86400) {return `${Math.floor(sec / 3600)}h ago`;}\n return `${Math.floor(sec / 86400)}d ago`;\n };\n\n const onlineCount = hosts.filter(h => h.status === 'online').length;\n const offlineCount = hosts.filter(h => h.status === 'offline').length;\n\n ctx.ui?.success?.(`${onlineCount} online, ${offlineCount} offline (${hosts.length} total)`, {\n sections: [{\n header: 'Agents',\n items: hosts.map(h =>\n `${h.name} ${h.status} ${(h.capabilities || []).join(', ') || ''} ${ago(h.lastSeen)}`\n ),\n }],\n });\n\n return { exitCode: 0, hosts };\n },\n },\n});\n"]}
@@ -1,17 +1,14 @@
1
1
  import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
2
3
 
3
- /**
4
- * workspace:register command (alias: agent:register)
5
- * Register this machine with a Platform Gateway and save credentials to ~/.kb/agent.json.
6
- */
7
- type RegisterInput = {
8
- gateway: string;
4
+ interface RegisterFlags {
5
+ gateway?: string;
9
6
  name?: string;
10
7
  workspace?: string[];
11
8
  namespace?: string;
12
9
  json?: boolean;
13
- flags?: RegisterInput;
14
- };
15
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, RegisterInput, unknown>;
10
+ 'dry-run'?: boolean;
11
+ }
12
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<RegisterFlags>, unknown>;
16
13
 
17
14
  export { _default as default };
@@ -1,4 +1,4 @@
1
- import { defineCommand } from '@kb-labs/sdk';
1
+ import { defineCommand, validationError, handleError } from '@kb-labs/sdk';
2
2
  import { stat, mkdir, writeFile } from 'fs/promises';
3
3
  import { resolve, normalize, join } from 'path';
4
4
  import { hostname, homedir } from 'os';
@@ -8,12 +8,24 @@ var register_default = defineCommand({
8
8
  id: "workspace:register",
9
9
  description: "Register this machine with a Platform Gateway",
10
10
  handler: {
11
- async execute(ctx, rawInput) {
12
- const input = rawInput.flags ?? rawInput;
13
- const gatewayUrl = (input.gateway ?? "").replace(/\/$/, "");
14
- const name = input.name ?? hostname();
15
- const namespaceId = input.namespace ?? "default";
16
- const rawWorkspace = input.workspace;
11
+ async intent(_ctx, input) {
12
+ const flags = input.flags;
13
+ const gatewayUrl = (flags.gateway ?? "").replace(/\/$/, "");
14
+ const name = flags.name ?? "(this machine)";
15
+ return {
16
+ summary: `Register workspace agent with Gateway ${gatewayUrl || "(unknown)"}`,
17
+ operations: [
18
+ { type: "create", resource: "agent-credentials", details: { name, gateway: gatewayUrl } },
19
+ { type: "create", resource: "file", details: { path: "~/.kb/agent.json" } }
20
+ ]
21
+ };
22
+ },
23
+ async execute(ctx, input) {
24
+ const flags = input.flags;
25
+ const gatewayUrl = (flags.gateway ?? "").replace(/\/$/, "");
26
+ const name = flags.name ?? hostname();
27
+ const namespaceId = flags.namespace ?? "default";
28
+ const rawWorkspace = flags.workspace;
17
29
  const rawPaths = rawWorkspace ? Array.isArray(rawWorkspace) ? rawWorkspace : [rawWorkspace] : [process.cwd()];
18
30
  const workspacePaths = [];
19
31
  for (const p of rawPaths) {
@@ -24,17 +36,17 @@ var register_default = defineCommand({
24
36
  } catch {
25
37
  }
26
38
  if (!pathStat?.isDirectory()) {
27
- ctx.ui?.error?.(`Workspace path does not exist or is not a directory: ${resolved}`);
39
+ validationError(ctx, `Workspace path does not exist or is not a directory: ${resolved}`, void 0, flags.json);
28
40
  return { exitCode: 1 };
29
41
  }
30
42
  workspacePaths.push(resolved);
31
43
  }
32
44
  if (!gatewayUrl) {
33
- ctx.ui?.error?.("--gateway is required. Example: kb workspace:register --gateway http://localhost:4000");
45
+ validationError(ctx, "--gateway is required", "Usage: kb workspace:register --gateway http://localhost:4000", flags.json);
34
46
  return { exitCode: 1 };
35
47
  }
36
48
  if (!gatewayUrl.startsWith("http://") && !gatewayUrl.startsWith("https://")) {
37
- ctx.ui?.error?.("Invalid gateway URL \u2014 must start with http:// or https://");
49
+ validationError(ctx, "Invalid gateway URL \u2014 must start with http:// or https://", void 0, flags.json);
38
50
  return { exitCode: 1 };
39
51
  }
40
52
  ctx.ui?.info?.(`Registering with Gateway: ${gatewayUrl}`);
@@ -46,29 +58,29 @@ var register_default = defineCommand({
46
58
  body: JSON.stringify({ name, namespaceId, capabilities: ["filesystem", "git", "execution", "search", "shell"] })
47
59
  });
48
60
  } catch (err) {
49
- ctx.ui?.error?.(`Failed to reach Gateway: ${err instanceof Error ? err.message : String(err)}`);
61
+ handleError(ctx, err instanceof Error ? new Error(`Failed to reach Gateway: ${err.message}`) : err, flags.json);
50
62
  return { exitCode: 1 };
51
63
  }
52
64
  if (!res.ok) {
53
65
  const rawBody = await res.text().catch(() => "");
54
66
  const body = rawBody.slice(0, 200).replace(/[\r\n]/g, " ");
55
- ctx.ui?.error?.(`Gateway returned ${res.status}: ${body}`);
67
+ handleError(ctx, new Error(`Gateway returned ${res.status}: ${body}`), flags.json);
56
68
  return { exitCode: 1 };
57
69
  }
58
70
  let data;
59
71
  try {
60
72
  data = await res.json();
61
73
  } catch {
62
- ctx.ui?.error?.("Gateway response is not valid JSON");
74
+ handleError(ctx, new Error("Gateway response is not valid JSON"), flags.json);
63
75
  return { exitCode: 1 };
64
76
  }
65
77
  if (!data.clientId || !data.clientSecret || !data.hostId) {
66
- ctx.ui?.error?.("Gateway response is missing required fields (clientId, clientSecret, hostId)");
78
+ handleError(ctx, new Error("Gateway response is missing required fields (clientId, clientSecret, hostId)"), flags.json);
67
79
  return { exitCode: 1 };
68
80
  }
69
81
  const SECRET_PATTERN = /^[A-Za-z0-9_\-+/=]{16,}$/;
70
82
  if (typeof data.clientSecret !== "string" || !SECRET_PATTERN.test(data.clientSecret)) {
71
- ctx.ui?.error?.("Gateway returned an invalid client secret (unexpected format)");
83
+ handleError(ctx, new Error("Gateway returned an invalid client secret (unexpected format)"), flags.json);
72
84
  return { exitCode: 1 };
73
85
  }
74
86
  const kbDir = join(homedir(), ".kb");
@@ -88,7 +100,7 @@ var register_default = defineCommand({
88
100
  }
89
101
  };
90
102
  await writeFile(configPath, JSON.stringify(agentConfig, null, 2), { mode: 384 });
91
- if (input.json) {
103
+ if (flags.json) {
92
104
  ctx.ui?.json?.({ configPath, hostId: data.hostId, clientId: data.clientId });
93
105
  } else {
94
106
  ctx.ui?.success?.("Workspace Agent registered", {
@@ -101,9 +113,9 @@ var register_default = defineCommand({
101
113
  `Workspaces: ${workspacePaths.join(", ")}`,
102
114
  `Config: ${configPath}`
103
115
  ]
104
- }]
116
+ }],
117
+ hint: "Next: start the daemon with `kb-dev start host-agent` or `kb workspace:start`."
105
118
  });
106
- ctx.ui?.info?.("Next: start the daemon with `pnpm dev:start:host-agent` or `kb workspace:start`.");
107
119
  }
108
120
  return { exitCode: 0, configPath };
109
121
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/register.ts"],"names":[],"mappings":"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","file":"register.js","sourcesContent":["/**\n * workspace:register command (alias: agent:register)\n * Register this machine with a Platform Gateway and save credentials to ~/.kb/agent.json.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { writeFile, mkdir, stat } from 'node:fs/promises';\nimport { join, resolve, normalize } from 'node:path';\nimport { homedir, hostname } from 'node:os';\n\ntype RegisterInput = {\n gateway: string;\n name?: string;\n workspace?: string[];\n namespace?: string;\n json?: boolean;\n flags?: RegisterInput;\n};\n\ntype RegisterResult = {\n exitCode: number;\n configPath?: string;\n};\n\nexport default defineCommand({\n id: 'workspace:register',\n description: 'Register this machine with a Platform Gateway',\n\n handler: {\n async execute(ctx: PluginContextV3, rawInput: RegisterInput): Promise<RegisterResult> {\n const input: RegisterInput = rawInput.flags ?? rawInput;\n const gatewayUrl = (input.gateway ?? '').replace(/\\/$/, '');\n const name = input.name ?? hostname();\n const namespaceId = input.namespace ?? 'default';\n const rawWorkspace = input.workspace;\n const rawPaths = rawWorkspace\n ? (Array.isArray(rawWorkspace) ? rawWorkspace : [rawWorkspace as unknown as string])\n : [process.cwd()];\n\n // Resolve and validate workspace paths: must be absolute directories, no traversal\n const workspacePaths: string[] = [];\n for (const p of rawPaths) {\n const resolved = resolve(normalize(p));\n let pathStat: Awaited<ReturnType<typeof stat>> | null = null;\n try { pathStat = await stat(resolved); } catch { /* will error below */ }\n if (!pathStat?.isDirectory()) {\n ctx.ui?.error?.(`Workspace path does not exist or is not a directory: ${resolved}`);\n return { exitCode: 1 };\n }\n workspacePaths.push(resolved);\n }\n\n if (!gatewayUrl) {\n ctx.ui?.error?.('--gateway is required. Example: kb workspace:register --gateway http://localhost:4000');\n return { exitCode: 1 };\n }\n\n // Validate URL\n if (!gatewayUrl.startsWith('http://') && !gatewayUrl.startsWith('https://')) {\n ctx.ui?.error?.('Invalid gateway URL — must start with http:// or https://');\n return { exitCode: 1 };\n }\n\n ctx.ui?.info?.(`Registering with Gateway: ${gatewayUrl}`);\n\n // POST /auth/register\n let res: Response;\n try {\n res = await fetch(`${gatewayUrl}/auth/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, namespaceId, capabilities: ['filesystem', 'git', 'execution', 'search', 'shell'] }),\n });\n } catch (err) {\n ctx.ui?.error?.(`Failed to reach Gateway: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1 };\n }\n\n if (!res.ok) {\n const rawBody = await res.text().catch(() => '');\n const body = rawBody.slice(0, 200).replace(/[\\r\\n]/g, ' ');\n ctx.ui?.error?.(`Gateway returned ${res.status}: ${body}`);\n return { exitCode: 1 };\n }\n\n let data: { clientId?: string; clientSecret?: string; hostId?: string };\n try {\n data = await res.json() as typeof data;\n } catch {\n ctx.ui?.error?.('Gateway response is not valid JSON');\n return { exitCode: 1 };\n }\n\n if (!data.clientId || !data.clientSecret || !data.hostId) {\n ctx.ui?.error?.('Gateway response is missing required fields (clientId, clientSecret, hostId)');\n return { exitCode: 1 };\n }\n\n // Format validation — secrets must be non-empty strings with safe characters only\n const SECRET_PATTERN = /^[A-Za-z0-9_\\-+/=]{16,}$/;\n if (typeof data.clientSecret !== 'string' || !SECRET_PATTERN.test(data.clientSecret)) {\n ctx.ui?.error?.('Gateway returned an invalid client secret (unexpected format)');\n return { exitCode: 1 };\n }\n\n // Write ~/.kb/agent.json\n const kbDir = join(homedir(), '.kb');\n await mkdir(kbDir, { recursive: true });\n const configPath = join(kbDir, 'agent.json');\n\n const agentConfig = {\n clientId: data.clientId,\n clientSecret: data.clientSecret,\n hostId: data.hostId,\n gatewayUrl,\n namespaceId,\n hostType: 'local' as const,\n workspacePaths,\n execution: {\n mode: 'in-process' as const,\n timeoutMs: 120_000,\n },\n };\n\n await writeFile(configPath, JSON.stringify(agentConfig, null, 2), { mode: 0o600 });\n\n if (input.json) {\n ctx.ui?.json?.({ configPath, hostId: data.hostId, clientId: data.clientId });\n } else {\n ctx.ui?.success?.('Workspace Agent registered', {\n sections: [{\n items: [\n `Host ID: ${data.hostId}`,\n `Client ID: ${data.clientId}`,\n `Gateway: ${gatewayUrl}`,\n `Namespace: ${namespaceId}`,\n `Workspaces: ${workspacePaths.join(', ')}`,\n `Config: ${configPath}`,\n ],\n }],\n });\n ctx.ui?.info?.('Next: start the daemon with `pnpm dev:start:host-agent` or `kb workspace:start`.');\n }\n\n return { exitCode: 0, configPath };\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/commands/register.ts"],"names":[],"mappings":"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","file":"register.js","sourcesContent":["/**\n * workspace:register command (alias: agent:register)\n * Register this machine with a Platform Gateway and save credentials to ~/.kb/agent.json.\n */\n\nimport { defineCommand, validationError, handleError, type PluginContextV3, type CLIInput } from '@kb-labs/sdk';\nimport { writeFile, mkdir, stat } from 'node:fs/promises';\nimport { join, resolve, normalize } from 'node:path';\nimport { homedir, hostname } from 'node:os';\n\ninterface RegisterFlags {\n gateway?: string;\n name?: string;\n workspace?: string[];\n namespace?: string;\n json?: boolean;\n 'dry-run'?: boolean;\n}\n\ntype RegisterResult = {\n exitCode: number;\n configPath?: string;\n};\n\nexport default defineCommand({\n id: 'workspace:register',\n description: 'Register this machine with a Platform Gateway',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<RegisterFlags>) {\n const flags = input.flags;\n const gatewayUrl = (flags.gateway ?? '').replace(/\\/$/, '');\n const name = flags.name ?? '(this machine)';\n return {\n summary: `Register workspace agent with Gateway ${gatewayUrl || '(unknown)'}`,\n operations: [\n { type: 'create' as const, resource: 'agent-credentials', details: { name, gateway: gatewayUrl } },\n { type: 'create' as const, resource: 'file', details: { path: '~/.kb/agent.json' } },\n ],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<RegisterFlags>): Promise<RegisterResult> {\n const flags = input.flags;\n const gatewayUrl = (flags.gateway ?? '').replace(/\\/$/, '');\n const name = flags.name ?? hostname();\n const namespaceId = flags.namespace ?? 'default';\n const rawWorkspace = flags.workspace;\n const rawPaths = rawWorkspace\n ? (Array.isArray(rawWorkspace) ? rawWorkspace : [rawWorkspace as unknown as string])\n : [process.cwd()];\n\n // Resolve and validate workspace paths: must be absolute directories, no traversal\n const workspacePaths: string[] = [];\n for (const p of rawPaths) {\n const resolved = resolve(normalize(p));\n let pathStat: Awaited<ReturnType<typeof stat>> | null = null;\n try { pathStat = await stat(resolved); } catch { /* will error below */ }\n if (!pathStat?.isDirectory()) {\n validationError(ctx, `Workspace path does not exist or is not a directory: ${resolved}`, undefined, flags.json);\n return { exitCode: 1 };\n }\n workspacePaths.push(resolved);\n }\n\n if (!gatewayUrl) {\n validationError(ctx, '--gateway is required', 'Usage: kb workspace:register --gateway http://localhost:4000', flags.json);\n return { exitCode: 1 };\n }\n\n // Validate URL\n if (!gatewayUrl.startsWith('http://') && !gatewayUrl.startsWith('https://')) {\n validationError(ctx, 'Invalid gateway URL — must start with http:// or https://', undefined, flags.json);\n return { exitCode: 1 };\n }\n\n ctx.ui?.info?.(`Registering with Gateway: ${gatewayUrl}`);\n\n // POST /auth/register\n let res: Response;\n try {\n res = await fetch(`${gatewayUrl}/auth/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, namespaceId, capabilities: ['filesystem', 'git', 'execution', 'search', 'shell'] }),\n });\n } catch (err) {\n handleError(ctx, err instanceof Error ? new Error(`Failed to reach Gateway: ${err.message}`) : err, flags.json);\n return { exitCode: 1 };\n }\n\n if (!res.ok) {\n const rawBody = await res.text().catch(() => '');\n const body = rawBody.slice(0, 200).replace(/[\\r\\n]/g, ' ');\n handleError(ctx, new Error(`Gateway returned ${res.status}: ${body}`), flags.json);\n return { exitCode: 1 };\n }\n\n let data: { clientId?: string; clientSecret?: string; hostId?: string };\n try {\n data = await res.json() as typeof data;\n } catch {\n handleError(ctx, new Error('Gateway response is not valid JSON'), flags.json);\n return { exitCode: 1 };\n }\n\n if (!data.clientId || !data.clientSecret || !data.hostId) {\n handleError(ctx, new Error('Gateway response is missing required fields (clientId, clientSecret, hostId)'), flags.json);\n return { exitCode: 1 };\n }\n\n // Format validation — secrets must be non-empty strings with safe characters only\n const SECRET_PATTERN = /^[A-Za-z0-9_\\-+/=]{16,}$/;\n if (typeof data.clientSecret !== 'string' || !SECRET_PATTERN.test(data.clientSecret)) {\n handleError(ctx, new Error('Gateway returned an invalid client secret (unexpected format)'), flags.json);\n return { exitCode: 1 };\n }\n\n // Write ~/.kb/agent.json\n const kbDir = join(homedir(), '.kb');\n await mkdir(kbDir, { recursive: true });\n const configPath = join(kbDir, 'agent.json');\n\n const agentConfig = {\n clientId: data.clientId,\n clientSecret: data.clientSecret,\n hostId: data.hostId,\n gatewayUrl,\n namespaceId,\n hostType: 'local' as const,\n workspacePaths,\n execution: {\n mode: 'in-process' as const,\n timeoutMs: 120_000,\n },\n };\n\n await writeFile(configPath, JSON.stringify(agentConfig, null, 2), { mode: 0o600 });\n\n if (flags.json) {\n ctx.ui?.json?.({ configPath, hostId: data.hostId, clientId: data.clientId });\n } else {\n ctx.ui?.success?.('Workspace Agent registered', {\n sections: [{\n items: [\n `Host ID: ${data.hostId}`,\n `Client ID: ${data.clientId}`,\n `Gateway: ${gatewayUrl}`,\n `Namespace: ${namespaceId}`,\n `Workspaces: ${workspacePaths.join(', ')}`,\n `Config: ${configPath}`,\n ],\n }],\n hint: 'Next: start the daemon with `kb-dev start host-agent` or `kb workspace:start`.',\n });\n }\n\n return { exitCode: 0, configPath };\n },\n },\n});\n"]}
@@ -22,7 +22,7 @@ var status_default = defineCommand({
22
22
  if (input.json) {
23
23
  ctx.ui?.json?.({ running: false });
24
24
  } else {
25
- ctx.ui?.info?.("Workspace Agent is not running. Start with: pnpm dev:start host-agent");
25
+ ctx.ui?.info?.("Workspace Agent is not running. Start with: kb-dev start host-agent");
26
26
  }
27
27
  return { exitCode: 0, running: false };
28
28
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;AAsBA,IAAO,iBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,kBAAA;AAAA,EACJ,WAAA,EAAa,oCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,QAAA,EAA8C;AAChF,MAAA,MAAM,KAAA,GAAqB,SAAS,KAAA,IAAS,QAAA;AAE7C,MAAA,IAAI,SAAA,GAAyG,IAAA;AAE7G,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,EAAE,IAAA,EAAM,QAAQ,CAAA;AAClD,QAAA,MAAM,SAAS,IAAI,eAAA,CAAgB,EAAE,SAAA,EAAW,cAAA,EAAgB,KAAM,CAAA;AACtE,QAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,QAAA,SAAA,GAAY,MAAM,OAAO,MAAA,EAAO;AAChC,QAAA,MAAA,CAAO,KAAA,EAAM;AAAA,MACf,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,IAAI,MAAM,IAAA,EAAM;AACd,UAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,QACnC,CAAA,MAAO;AACL,UAAA,GAAA,CAAI,EAAA,EAAI,OAAO,uEAAuE,CAAA;AAAA,QACxF;AACA,QAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MACvC;AAEA,MAAA,MAAM,cAAc,SAAA,CAAU,SAAA,GAC1B,WAAA,GACA,SAAA,CAAU,eACR,iBAAA,GACA,cAAA;AAEN,MAAA,MAAM,MAAA,GAAuB;AAAA,QAC3B,QAAA,EAAU,CAAA;AAAA,QACV,OAAA,EAAS,IAAA;AAAA,QACT,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,YAAY,SAAA,CAAU;AAAA,OACxB;AAEA,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,OAAO,MAAM,CAAA;AAAA,MACvB,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,EAAA,EAAI,UAAU,wBAAA,EAA0B;AAAA,UAC1C,UAAU,CAAC;AAAA,YACT,KAAA,EAAO;AAAA,cACL,eAAe,WAAW,CAAA,CAAA;AAAA,cAC1B,GAAI,UAAU,MAAA,GAAS,CAAC,eAAe,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA,GAAI,EAAC;AAAA,cAC9D,GAAI,UAAU,UAAA,GAAa,CAAC,eAAe,SAAA,CAAU,UAAU,CAAA,CAAE,CAAA,GAAI;AAAC;AACxE,WACD;AAAA,SACF,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA;AAEJ,CAAC","file":"status.js","sourcesContent":["/**\n * workspace:status command (alias: agent:status)\n * Show Workspace Agent daemon status via IPC socket.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { HostAgentClient } from '@kb-labs/host-agent-client';\nimport { createTransport } from '@kb-labs/host-agent-transport';\n\ntype StatusInput = {\n json?: boolean;\n flags?: StatusInput;\n};\n\ntype StatusResult = {\n exitCode: number;\n running: boolean;\n connected?: boolean;\n hostId?: string;\n gatewayUrl?: string;\n};\n\nexport default defineCommand({\n id: 'workspace:status',\n description: 'Show Workspace Agent daemon status',\n\n handler: {\n async execute(ctx: PluginContextV3, rawInput: StatusInput): Promise<StatusResult> {\n const input: StatusInput = rawInput.flags ?? rawInput;\n\n let ipcStatus: { connected: boolean; hostId?: string; gatewayUrl?: string; reconnecting?: boolean } | null = null;\n\n try {\n const transport = createTransport({ mode: 'auto' });\n const client = new HostAgentClient({ transport, requestTimeout: 3000 });\n await client.connect();\n ipcStatus = await client.status();\n client.close();\n } catch {\n // IPC unreachable — daemon not running\n }\n\n if (ipcStatus === null) {\n if (input.json) {\n ctx.ui?.json?.({ running: false });\n } else {\n ctx.ui?.info?.('Workspace Agent is not running. Start with: pnpm dev:start host-agent');\n }\n return { exitCode: 0, running: false };\n }\n\n const statusLabel = ipcStatus.connected\n ? 'connected'\n : ipcStatus.reconnecting\n ? 'reconnecting...'\n : 'disconnected';\n\n const result: StatusResult = {\n exitCode: 0,\n running: true,\n connected: ipcStatus.connected,\n hostId: ipcStatus.hostId,\n gatewayUrl: ipcStatus.gatewayUrl,\n };\n\n if (input.json) {\n ctx.ui?.json?.(result);\n } else {\n ctx.ui?.success?.('Workspace Agent Status', {\n sections: [{\n items: [\n `Status: ${statusLabel}`,\n ...(ipcStatus.hostId ? [`Host ID: ${ipcStatus.hostId}`] : []),\n ...(ipcStatus.gatewayUrl ? [`Gateway: ${ipcStatus.gatewayUrl}`] : []),\n ],\n }],\n });\n }\n\n return result;\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;AAsBA,IAAO,iBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,kBAAA;AAAA,EACJ,WAAA,EAAa,oCAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,QAAA,EAA8C;AAChF,MAAA,MAAM,KAAA,GAAqB,SAAS,KAAA,IAAS,QAAA;AAE7C,MAAA,IAAI,SAAA,GAAyG,IAAA;AAE7G,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,EAAE,IAAA,EAAM,QAAQ,CAAA;AAClD,QAAA,MAAM,SAAS,IAAI,eAAA,CAAgB,EAAE,SAAA,EAAW,cAAA,EAAgB,KAAM,CAAA;AACtE,QAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,QAAA,SAAA,GAAY,MAAM,OAAO,MAAA,EAAO;AAChC,QAAA,MAAA,CAAO,KAAA,EAAM;AAAA,MACf,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,IAAI,MAAM,IAAA,EAAM;AACd,UAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,EAAE,OAAA,EAAS,OAAO,CAAA;AAAA,QACnC,CAAA,MAAO;AACL,UAAA,GAAA,CAAI,EAAA,EAAI,OAAO,qEAAqE,CAAA;AAAA,QACtF;AACA,QAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MACvC;AAEA,MAAA,MAAM,cAAc,SAAA,CAAU,SAAA,GAC1B,WAAA,GACA,SAAA,CAAU,eACR,iBAAA,GACA,cAAA;AAEN,MAAA,MAAM,MAAA,GAAuB;AAAA,QAC3B,QAAA,EAAU,CAAA;AAAA,QACV,OAAA,EAAS,IAAA;AAAA,QACT,WAAW,SAAA,CAAU,SAAA;AAAA,QACrB,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,YAAY,SAAA,CAAU;AAAA,OACxB;AAEA,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,OAAO,MAAM,CAAA;AAAA,MACvB,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,EAAA,EAAI,UAAU,wBAAA,EAA0B;AAAA,UAC1C,UAAU,CAAC;AAAA,YACT,KAAA,EAAO;AAAA,cACL,eAAe,WAAW,CAAA,CAAA;AAAA,cAC1B,GAAI,UAAU,MAAA,GAAS,CAAC,eAAe,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA,GAAI,EAAC;AAAA,cAC9D,GAAI,UAAU,UAAA,GAAa,CAAC,eAAe,SAAA,CAAU,UAAU,CAAA,CAAE,CAAA,GAAI;AAAC;AACxE,WACD;AAAA,SACF,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA;AAEJ,CAAC","file":"status.js","sourcesContent":["/**\n * workspace:status command (alias: agent:status)\n * Show Workspace Agent daemon status via IPC socket.\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { HostAgentClient } from '@kb-labs/host-agent-client';\nimport { createTransport } from '@kb-labs/host-agent-transport';\n\ntype StatusInput = {\n json?: boolean;\n flags?: StatusInput;\n};\n\ntype StatusResult = {\n exitCode: number;\n running: boolean;\n connected?: boolean;\n hostId?: string;\n gatewayUrl?: string;\n};\n\nexport default defineCommand({\n id: 'workspace:status',\n description: 'Show Workspace Agent daemon status',\n\n handler: {\n async execute(ctx: PluginContextV3, rawInput: StatusInput): Promise<StatusResult> {\n const input: StatusInput = rawInput.flags ?? rawInput;\n\n let ipcStatus: { connected: boolean; hostId?: string; gatewayUrl?: string; reconnecting?: boolean } | null = null;\n\n try {\n const transport = createTransport({ mode: 'auto' });\n const client = new HostAgentClient({ transport, requestTimeout: 3000 });\n await client.connect();\n ipcStatus = await client.status();\n client.close();\n } catch {\n // IPC unreachable — daemon not running\n }\n\n if (ipcStatus === null) {\n if (input.json) {\n ctx.ui?.json?.({ running: false });\n } else {\n ctx.ui?.info?.('Workspace Agent is not running. Start with: kb-dev start host-agent');\n }\n return { exitCode: 0, running: false };\n }\n\n const statusLabel = ipcStatus.connected\n ? 'connected'\n : ipcStatus.reconnecting\n ? 'reconnecting...'\n : 'disconnected';\n\n const result: StatusResult = {\n exitCode: 0,\n running: true,\n connected: ipcStatus.connected,\n hostId: ipcStatus.hostId,\n gatewayUrl: ipcStatus.gatewayUrl,\n };\n\n if (input.json) {\n ctx.ui?.json?.(result);\n } else {\n ctx.ui?.success?.('Workspace Agent Status', {\n sections: [{\n items: [\n `Status: ${statusLabel}`,\n ...(ipcStatus.hostId ? [`Host ID: ${ipcStatus.hostId}`] : []),\n ...(ipcStatus.gatewayUrl ? [`Gateway: ${ipcStatus.gatewayUrl}`] : []),\n ],\n }],\n });\n }\n\n return result;\n },\n },\n});\n"]}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { default as manifest, default as pluginManifest } from './manifest.js';
2
- import '@kb-labs/perm-presets';
2
+ import '@kb-labs/plugin-contracts';
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ var manifest = {
62
62
  version: "0.2.0",
63
63
  display: {
64
64
  name: "Workspace Agent",
65
- description: "Connect this machine to KB Labs Platform for remote plugin execution.",
65
+ description: "Connect machine to platform for remote execution",
66
66
  tags: ["workspace-agent", "gateway", "cloud", "execution"]
67
67
  },
68
68
  platform: {
@@ -70,15 +70,24 @@ var manifest = {
70
70
  optional: ["logger"]
71
71
  },
72
72
  cli: {
73
+ groupMeta: [
74
+ {
75
+ path: "workspace",
76
+ describe: "Workspace management"
77
+ },
78
+ {
79
+ path: "agent",
80
+ describe: "Agent management"
81
+ }
82
+ ],
73
83
  commands: [
74
84
  // Primary commands: workspace:*
75
85
  {
76
- id: "register",
77
- group: "workspace",
86
+ path: "workspace register",
78
87
  describe: "Register this machine with a Platform Gateway.",
88
+ operationType: "mutate",
79
89
  longDescription: "Calls POST /auth/register on the given Gateway URL, receives credentials, and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.",
80
90
  handler: "./commands/register.js#default",
81
- handlerPath: "./commands/register.js",
82
91
  flags: defineCommandFlags(registerFlags),
83
92
  examples: [
84
93
  "kb workspace:register --gateway http://localhost:4000",
@@ -86,12 +95,11 @@ var manifest = {
86
95
  ]
87
96
  },
88
97
  {
89
- id: "status",
90
- group: "workspace",
98
+ path: "workspace status",
91
99
  describe: "Show Workspace Agent connection status.",
92
- longDescription: "Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). Start the daemon with `kb workspace:start` or `pnpm dev:start:host-agent`.",
100
+ operationType: "read",
101
+ longDescription: "Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). Start the daemon with `kb workspace:start` or `kb-dev start host-agent`.",
93
102
  handler: "./commands/status.js#default",
94
- handlerPath: "./commands/status.js",
95
103
  flags: defineCommandFlags(statusFlags),
96
104
  examples: [
97
105
  "kb workspace:status",
@@ -99,12 +107,11 @@ var manifest = {
99
107
  ]
100
108
  },
101
109
  {
102
- id: "list",
103
- group: "workspace",
110
+ path: "workspace list",
104
111
  describe: "List all connected Workspace Agents.",
112
+ operationType: "read",
105
113
  longDescription: "Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.",
106
114
  handler: "./commands/list.js#default",
107
- handlerPath: "./commands/list.js",
108
115
  flags: defineCommandFlags(listFlags),
109
116
  examples: [
110
117
  "kb workspace:list",
@@ -114,22 +121,18 @@ var manifest = {
114
121
  },
115
122
  // Legacy aliases: agent:* (backwards compatible)
116
123
  {
117
- id: "register",
118
- group: "agent",
124
+ path: "agent register",
119
125
  describe: "[Alias for workspace:register] Register this machine with a Platform Gateway.",
120
126
  handler: "./commands/register.js#default",
121
- handlerPath: "./commands/register.js",
122
127
  flags: defineCommandFlags(registerFlags),
123
128
  examples: [
124
129
  "kb agent:register --gateway http://localhost:4000"
125
130
  ]
126
131
  },
127
132
  {
128
- id: "status",
129
- group: "agent",
133
+ path: "agent status",
130
134
  describe: "[Alias for workspace:status] Show Workspace Agent connection status.",
131
135
  handler: "./commands/status.js#default",
132
- handlerPath: "./commands/status.js",
133
136
  flags: defineCommandFlags(statusFlags),
134
137
  examples: [
135
138
  "kb agent:status",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/flags.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const registerFlags = {\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (e.g. http://localhost:4000 or https://gateway.example.com)',\n required: true,\n },\n name: {\n type: 'string' as const,\n describe: 'Display name for this host (default: hostname)',\n },\n workspace: {\n type: 'array' as const,\n describe: 'Workspace paths this agent is allowed to access (can specify multiple)',\n string: true,\n },\n namespace: {\n type: 'string' as const,\n describe: 'Namespace ID (default: \"default\")',\n default: 'default',\n },\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const statusFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const listFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (default: from ~/.kb/agent.json or http://localhost:4000)',\n },\n};\n","import { defineCommandFlags, combinePermissions, kbPlatformPreset } from '@kb-labs/sdk';\nimport { registerFlags, statusFlags, listFlags } from './commands/flags.js';\n\nconst pluginPermissions = combinePermissions()\n .with(kbPlatformPreset)\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/**', '~/.kb/**'],\n })\n .withEnv(['HOME', 'USER', 'KB_GATEWAY_URL'])\n .withQuotas({\n timeoutMs: 30000,\n memoryMb: 128,\n })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/host-agent',\n version: '0.2.0',\n\n display: {\n name: 'Workspace Agent',\n description: 'Connect this machine to KB Labs Platform for remote plugin execution.',\n tags: ['workspace-agent', 'gateway', 'cloud', 'execution'],\n },\n\n platform: {\n requires: [],\n optional: ['logger'],\n },\n\n cli: {\n commands: [\n // Primary commands: workspace:*\n {\n id: 'register',\n group: 'workspace',\n describe: 'Register this machine with a Platform Gateway.',\n longDescription:\n 'Calls POST /auth/register on the given Gateway URL, receives credentials, ' +\n 'and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.',\n\n handler: './commands/register.js#default',\n handlerPath: './commands/register.js',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb workspace:register --gateway http://localhost:4000',\n 'kb workspace:register --gateway https://gateway.kblabs.dev --name my-laptop --workspace ~/projects/my-app',\n ],\n },\n\n {\n id: 'status',\n group: 'workspace',\n describe: 'Show Workspace Agent connection status.',\n longDescription:\n 'Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). ' +\n 'Start the daemon with `kb workspace:start` or `pnpm dev:start:host-agent`.',\n\n handler: './commands/status.js#default',\n handlerPath: './commands/status.js',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb workspace:status',\n 'kb workspace:status --json',\n ],\n },\n\n {\n id: 'list',\n group: 'workspace',\n describe: 'List all connected Workspace Agents.',\n longDescription:\n 'Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.',\n\n handler: './commands/list.js#default',\n handlerPath: './commands/list.js',\n\n flags: defineCommandFlags(listFlags),\n\n examples: [\n 'kb workspace:list',\n 'kb workspace:list --json',\n 'kb workspace:list --gateway https://gateway.kblabs.dev',\n ],\n },\n\n // Legacy aliases: agent:* (backwards compatible)\n {\n id: 'register',\n group: 'agent',\n describe: '[Alias for workspace:register] Register this machine with a Platform Gateway.',\n\n handler: './commands/register.js#default',\n handlerPath: './commands/register.js',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb agent:register --gateway http://localhost:4000',\n ],\n },\n\n {\n id: 'status',\n group: 'agent',\n describe: '[Alias for workspace:status] Show Workspace Agent connection status.',\n\n handler: './commands/status.js#default',\n handlerPath: './commands/status.js',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb agent:status',\n 'kb agent:status --json',\n ],\n },\n ],\n },\n\n capabilities: [],\n permissions: pluginPermissions,\n artifacts: [\n {\n id: 'workspace-agent.config',\n pathTemplate: '~/.kb/agent.json',\n description: 'Workspace Agent credentials and configuration.',\n },\n ],\n};\n\nexport default manifest;\n"]}
1
+ {"version":3,"sources":["../src/commands/flags.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const registerFlags = {\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (e.g. http://localhost:4000 or https://gateway.example.com)',\n required: true,\n },\n name: {\n type: 'string' as const,\n describe: 'Display name for this host (default: hostname)',\n },\n workspace: {\n type: 'array' as const,\n describe: 'Workspace paths this agent is allowed to access (can specify multiple)',\n string: true,\n },\n namespace: {\n type: 'string' as const,\n describe: 'Namespace ID (default: \"default\")',\n default: 'default',\n },\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const statusFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const listFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (default: from ~/.kb/agent.json or http://localhost:4000)',\n },\n};\n","import { defineCommandFlags, combinePermissions, kbPlatformPreset } from '@kb-labs/sdk';\nimport { registerFlags, statusFlags, listFlags } from './commands/flags.js';\n\nconst pluginPermissions = combinePermissions()\n .with(kbPlatformPreset)\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/**', '~/.kb/**'],\n })\n .withEnv(['HOME', 'USER', 'KB_GATEWAY_URL'])\n .withQuotas({\n timeoutMs: 30000,\n memoryMb: 128,\n })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/host-agent',\n version: '0.2.0',\n\n display: {\n name: 'Workspace Agent',\n description: 'Connect machine to platform for remote execution',\n tags: ['workspace-agent', 'gateway', 'cloud', 'execution'],\n },\n\n platform: {\n requires: [],\n optional: ['logger'],\n },\n\n cli: {\n groupMeta: [\n {\n path: 'workspace',\n describe: 'Workspace management',\n },\n {\n path: 'agent',\n describe: 'Agent management',\n },\n ],\n commands: [\n // Primary commands: workspace:*\n {\n path: 'workspace register',\n describe: 'Register this machine with a Platform Gateway.',\n operationType: 'mutate' as const,\n longDescription:\n 'Calls POST /auth/register on the given Gateway URL, receives credentials, ' +\n 'and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.',\n\n handler: './commands/register.js#default',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb workspace:register --gateway http://localhost:4000',\n 'kb workspace:register --gateway https://gateway.kblabs.dev --name my-laptop --workspace ~/projects/my-app',\n ],\n },\n\n {\n path: 'workspace status',\n describe: 'Show Workspace Agent connection status.',\n operationType: 'read' as const,\n longDescription:\n 'Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). ' +\n 'Start the daemon with `kb workspace:start` or `kb-dev start host-agent`.',\n\n handler: './commands/status.js#default',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb workspace:status',\n 'kb workspace:status --json',\n ],\n },\n\n {\n path: 'workspace list',\n describe: 'List all connected Workspace Agents.',\n operationType: 'read' as const,\n longDescription:\n 'Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.',\n\n handler: './commands/list.js#default',\n\n flags: defineCommandFlags(listFlags),\n\n examples: [\n 'kb workspace:list',\n 'kb workspace:list --json',\n 'kb workspace:list --gateway https://gateway.kblabs.dev',\n ],\n },\n\n // Legacy aliases: agent:* (backwards compatible)\n {\n path: 'agent register',\n describe: '[Alias for workspace:register] Register this machine with a Platform Gateway.',\n\n handler: './commands/register.js#default',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb agent:register --gateway http://localhost:4000',\n ],\n },\n\n {\n path: 'agent status',\n describe: '[Alias for workspace:status] Show Workspace Agent connection status.',\n\n handler: './commands/status.js#default',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb agent:status',\n 'kb agent:status --json',\n ],\n },\n ],\n },\n\n capabilities: [],\n permissions: pluginPermissions,\n artifacts: [\n {\n id: 'workspace-agent.config',\n pathTemplate: '~/.kb/agent.json',\n description: 'Workspace Agent credentials and configuration.',\n },\n ],\n};\n\nexport default manifest;\n"]}
@@ -1,4 +1,4 @@
1
- import * as _kb_labs_perm_presets from '@kb-labs/perm-presets';
1
+ import * as _kb_labs_plugin_contracts from '@kb-labs/plugin-contracts';
2
2
 
3
3
  declare const manifest: {
4
4
  schema: string;
@@ -14,13 +14,32 @@ declare const manifest: {
14
14
  optional: string[];
15
15
  };
16
16
  cli: {
17
+ groupMeta: {
18
+ path: string;
19
+ describe: string;
20
+ }[];
17
21
  commands: ({
18
- id: string;
19
- group: string;
22
+ path: string;
23
+ describe: string;
24
+ operationType: "mutate";
25
+ longDescription: string;
26
+ handler: string;
27
+ flags: {
28
+ name: string;
29
+ type: "string" | "boolean" | "number" | "array";
30
+ alias?: string;
31
+ default?: unknown;
32
+ description?: string;
33
+ choices?: string[];
34
+ required?: boolean;
35
+ }[];
36
+ examples: string[];
37
+ } | {
38
+ path: string;
20
39
  describe: string;
40
+ operationType: "read";
21
41
  longDescription: string;
22
42
  handler: string;
23
- handlerPath: string;
24
43
  flags: {
25
44
  name: string;
26
45
  type: "string" | "boolean" | "number" | "array";
@@ -32,11 +51,9 @@ declare const manifest: {
32
51
  }[];
33
52
  examples: string[];
34
53
  } | {
35
- id: string;
36
- group: string;
54
+ path: string;
37
55
  describe: string;
38
56
  handler: string;
39
- handlerPath: string;
40
57
  flags: {
41
58
  name: string;
42
59
  type: "string" | "boolean" | "number" | "array";
@@ -47,11 +64,12 @@ declare const manifest: {
47
64
  required?: boolean;
48
65
  }[];
49
66
  examples: string[];
67
+ operationType?: undefined;
50
68
  longDescription?: undefined;
51
69
  })[];
52
70
  };
53
71
  capabilities: never[];
54
- permissions: _kb_labs_perm_presets.RuntimePermissionSpec;
72
+ permissions: _kb_labs_plugin_contracts.PermissionSpec;
55
73
  artifacts: {
56
74
  id: string;
57
75
  pathTemplate: string;
package/dist/manifest.js CHANGED
@@ -62,7 +62,7 @@ var manifest = {
62
62
  version: "0.2.0",
63
63
  display: {
64
64
  name: "Workspace Agent",
65
- description: "Connect this machine to KB Labs Platform for remote plugin execution.",
65
+ description: "Connect machine to platform for remote execution",
66
66
  tags: ["workspace-agent", "gateway", "cloud", "execution"]
67
67
  },
68
68
  platform: {
@@ -70,15 +70,24 @@ var manifest = {
70
70
  optional: ["logger"]
71
71
  },
72
72
  cli: {
73
+ groupMeta: [
74
+ {
75
+ path: "workspace",
76
+ describe: "Workspace management"
77
+ },
78
+ {
79
+ path: "agent",
80
+ describe: "Agent management"
81
+ }
82
+ ],
73
83
  commands: [
74
84
  // Primary commands: workspace:*
75
85
  {
76
- id: "register",
77
- group: "workspace",
86
+ path: "workspace register",
78
87
  describe: "Register this machine with a Platform Gateway.",
88
+ operationType: "mutate",
79
89
  longDescription: "Calls POST /auth/register on the given Gateway URL, receives credentials, and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.",
80
90
  handler: "./commands/register.js#default",
81
- handlerPath: "./commands/register.js",
82
91
  flags: defineCommandFlags(registerFlags),
83
92
  examples: [
84
93
  "kb workspace:register --gateway http://localhost:4000",
@@ -86,12 +95,11 @@ var manifest = {
86
95
  ]
87
96
  },
88
97
  {
89
- id: "status",
90
- group: "workspace",
98
+ path: "workspace status",
91
99
  describe: "Show Workspace Agent connection status.",
92
- longDescription: "Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). Start the daemon with `kb workspace:start` or `pnpm dev:start:host-agent`.",
100
+ operationType: "read",
101
+ longDescription: "Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). Start the daemon with `kb workspace:start` or `kb-dev start host-agent`.",
93
102
  handler: "./commands/status.js#default",
94
- handlerPath: "./commands/status.js",
95
103
  flags: defineCommandFlags(statusFlags),
96
104
  examples: [
97
105
  "kb workspace:status",
@@ -99,12 +107,11 @@ var manifest = {
99
107
  ]
100
108
  },
101
109
  {
102
- id: "list",
103
- group: "workspace",
110
+ path: "workspace list",
104
111
  describe: "List all connected Workspace Agents.",
112
+ operationType: "read",
105
113
  longDescription: "Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.",
106
114
  handler: "./commands/list.js#default",
107
- handlerPath: "./commands/list.js",
108
115
  flags: defineCommandFlags(listFlags),
109
116
  examples: [
110
117
  "kb workspace:list",
@@ -114,22 +121,18 @@ var manifest = {
114
121
  },
115
122
  // Legacy aliases: agent:* (backwards compatible)
116
123
  {
117
- id: "register",
118
- group: "agent",
124
+ path: "agent register",
119
125
  describe: "[Alias for workspace:register] Register this machine with a Platform Gateway.",
120
126
  handler: "./commands/register.js#default",
121
- handlerPath: "./commands/register.js",
122
127
  flags: defineCommandFlags(registerFlags),
123
128
  examples: [
124
129
  "kb agent:register --gateway http://localhost:4000"
125
130
  ]
126
131
  },
127
132
  {
128
- id: "status",
129
- group: "agent",
133
+ path: "agent status",
130
134
  describe: "[Alias for workspace:status] Show Workspace Agent connection status.",
131
135
  handler: "./commands/status.js#default",
132
- handlerPath: "./commands/status.js",
133
136
  flags: defineCommandFlags(statusFlags),
134
137
  examples: [
135
138
  "kb agent:status",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/flags.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"manifest.js","sourcesContent":["export const registerFlags = {\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (e.g. http://localhost:4000 or https://gateway.example.com)',\n required: true,\n },\n name: {\n type: 'string' as const,\n describe: 'Display name for this host (default: hostname)',\n },\n workspace: {\n type: 'array' as const,\n describe: 'Workspace paths this agent is allowed to access (can specify multiple)',\n string: true,\n },\n namespace: {\n type: 'string' as const,\n describe: 'Namespace ID (default: \"default\")',\n default: 'default',\n },\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const statusFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const listFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (default: from ~/.kb/agent.json or http://localhost:4000)',\n },\n};\n","import { defineCommandFlags, combinePermissions, kbPlatformPreset } from '@kb-labs/sdk';\nimport { registerFlags, statusFlags, listFlags } from './commands/flags.js';\n\nconst pluginPermissions = combinePermissions()\n .with(kbPlatformPreset)\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/**', '~/.kb/**'],\n })\n .withEnv(['HOME', 'USER', 'KB_GATEWAY_URL'])\n .withQuotas({\n timeoutMs: 30000,\n memoryMb: 128,\n })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/host-agent',\n version: '0.2.0',\n\n display: {\n name: 'Workspace Agent',\n description: 'Connect this machine to KB Labs Platform for remote plugin execution.',\n tags: ['workspace-agent', 'gateway', 'cloud', 'execution'],\n },\n\n platform: {\n requires: [],\n optional: ['logger'],\n },\n\n cli: {\n commands: [\n // Primary commands: workspace:*\n {\n id: 'register',\n group: 'workspace',\n describe: 'Register this machine with a Platform Gateway.',\n longDescription:\n 'Calls POST /auth/register on the given Gateway URL, receives credentials, ' +\n 'and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.',\n\n handler: './commands/register.js#default',\n handlerPath: './commands/register.js',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb workspace:register --gateway http://localhost:4000',\n 'kb workspace:register --gateway https://gateway.kblabs.dev --name my-laptop --workspace ~/projects/my-app',\n ],\n },\n\n {\n id: 'status',\n group: 'workspace',\n describe: 'Show Workspace Agent connection status.',\n longDescription:\n 'Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). ' +\n 'Start the daemon with `kb workspace:start` or `pnpm dev:start:host-agent`.',\n\n handler: './commands/status.js#default',\n handlerPath: './commands/status.js',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb workspace:status',\n 'kb workspace:status --json',\n ],\n },\n\n {\n id: 'list',\n group: 'workspace',\n describe: 'List all connected Workspace Agents.',\n longDescription:\n 'Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.',\n\n handler: './commands/list.js#default',\n handlerPath: './commands/list.js',\n\n flags: defineCommandFlags(listFlags),\n\n examples: [\n 'kb workspace:list',\n 'kb workspace:list --json',\n 'kb workspace:list --gateway https://gateway.kblabs.dev',\n ],\n },\n\n // Legacy aliases: agent:* (backwards compatible)\n {\n id: 'register',\n group: 'agent',\n describe: '[Alias for workspace:register] Register this machine with a Platform Gateway.',\n\n handler: './commands/register.js#default',\n handlerPath: './commands/register.js',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb agent:register --gateway http://localhost:4000',\n ],\n },\n\n {\n id: 'status',\n group: 'agent',\n describe: '[Alias for workspace:status] Show Workspace Agent connection status.',\n\n handler: './commands/status.js#default',\n handlerPath: './commands/status.js',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb agent:status',\n 'kb agent:status --json',\n ],\n },\n ],\n },\n\n capabilities: [],\n permissions: pluginPermissions,\n artifacts: [\n {\n id: 'workspace-agent.config',\n pathTemplate: '~/.kb/agent.json',\n description: 'Workspace Agent credentials and configuration.',\n },\n ],\n};\n\nexport default manifest;\n"]}
1
+ {"version":3,"sources":["../src/commands/flags.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"manifest.js","sourcesContent":["export const registerFlags = {\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (e.g. http://localhost:4000 or https://gateway.example.com)',\n required: true,\n },\n name: {\n type: 'string' as const,\n describe: 'Display name for this host (default: hostname)',\n },\n workspace: {\n type: 'array' as const,\n describe: 'Workspace paths this agent is allowed to access (can specify multiple)',\n string: true,\n },\n namespace: {\n type: 'string' as const,\n describe: 'Namespace ID (default: \"default\")',\n default: 'default',\n },\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const statusFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n};\n\nexport const listFlags = {\n json: {\n type: 'boolean' as const,\n describe: 'Output as JSON',\n default: false,\n },\n gateway: {\n type: 'string' as const,\n describe: 'Gateway URL (default: from ~/.kb/agent.json or http://localhost:4000)',\n },\n};\n","import { defineCommandFlags, combinePermissions, kbPlatformPreset } from '@kb-labs/sdk';\nimport { registerFlags, statusFlags, listFlags } from './commands/flags.js';\n\nconst pluginPermissions = combinePermissions()\n .with(kbPlatformPreset)\n .withFs({\n mode: 'readWrite',\n allow: ['.kb/**', '~/.kb/**'],\n })\n .withEnv(['HOME', 'USER', 'KB_GATEWAY_URL'])\n .withQuotas({\n timeoutMs: 30000,\n memoryMb: 128,\n })\n .build();\n\nexport const manifest = {\n schema: 'kb.plugin/3',\n id: '@kb-labs/host-agent',\n version: '0.2.0',\n\n display: {\n name: 'Workspace Agent',\n description: 'Connect machine to platform for remote execution',\n tags: ['workspace-agent', 'gateway', 'cloud', 'execution'],\n },\n\n platform: {\n requires: [],\n optional: ['logger'],\n },\n\n cli: {\n groupMeta: [\n {\n path: 'workspace',\n describe: 'Workspace management',\n },\n {\n path: 'agent',\n describe: 'Agent management',\n },\n ],\n commands: [\n // Primary commands: workspace:*\n {\n path: 'workspace register',\n describe: 'Register this machine with a Platform Gateway.',\n operationType: 'mutate' as const,\n longDescription:\n 'Calls POST /auth/register on the given Gateway URL, receives credentials, ' +\n 'and writes ~/.kb/agent.json. Must be run once before starting the Workspace Agent daemon.',\n\n handler: './commands/register.js#default',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb workspace:register --gateway http://localhost:4000',\n 'kb workspace:register --gateway https://gateway.kblabs.dev --name my-laptop --workspace ~/projects/my-app',\n ],\n },\n\n {\n path: 'workspace status',\n describe: 'Show Workspace Agent connection status.',\n operationType: 'read' as const,\n longDescription:\n 'Connects to the daemon via IPC socket and queries its status (connected, hostId, gatewayUrl, capabilities). ' +\n 'Start the daemon with `kb workspace:start` or `kb-dev start host-agent`.',\n\n handler: './commands/status.js#default',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb workspace:status',\n 'kb workspace:status --json',\n ],\n },\n\n {\n path: 'workspace list',\n describe: 'List all connected Workspace Agents.',\n operationType: 'read' as const,\n longDescription:\n 'Queries the Gateway REST API for all registered hosts and shows their status, capabilities, and last seen time.',\n\n handler: './commands/list.js#default',\n\n flags: defineCommandFlags(listFlags),\n\n examples: [\n 'kb workspace:list',\n 'kb workspace:list --json',\n 'kb workspace:list --gateway https://gateway.kblabs.dev',\n ],\n },\n\n // Legacy aliases: agent:* (backwards compatible)\n {\n path: 'agent register',\n describe: '[Alias for workspace:register] Register this machine with a Platform Gateway.',\n\n handler: './commands/register.js#default',\n\n flags: defineCommandFlags(registerFlags),\n\n examples: [\n 'kb agent:register --gateway http://localhost:4000',\n ],\n },\n\n {\n path: 'agent status',\n describe: '[Alias for workspace:status] Show Workspace Agent connection status.',\n\n handler: './commands/status.js#default',\n\n flags: defineCommandFlags(statusFlags),\n\n examples: [\n 'kb agent:status',\n 'kb agent:status --json',\n ],\n },\n ],\n },\n\n capabilities: [],\n permissions: pluginPermissions,\n artifacts: [\n {\n id: 'workspace-agent.config',\n pathTemplate: '~/.kb/agent.json',\n description: 'Workspace Agent credentials and configuration.',\n },\n ],\n};\n\nexport default manifest;\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/host-agent-entry",
3
3
  "description": "CLI commands for Host Agent — register and status.",
4
- "version": "2.94.0",
4
+ "version": "2.98.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -21,10 +21,10 @@
21
21
  "README.md"
22
22
  ],
23
23
  "dependencies": {
24
- "@kb-labs/sdk": "2.21.2",
25
- "@kb-labs/host-agent-client": "2.94.0",
26
- "@kb-labs/host-agent-contracts": "2.94.0",
27
- "@kb-labs/host-agent-transport": "2.94.0"
24
+ "@kb-labs/host-agent-contracts": "2.98.0",
25
+ "@kb-labs/host-agent-transport": "2.98.0",
26
+ "@kb-labs/sdk": "2.22.0",
27
+ "@kb-labs/host-agent-client": "2.98.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^24.3.3",
@@ -32,8 +32,9 @@
32
32
  "rimraf": "^6.0.1",
33
33
  "tsup": "^8.5.0",
34
34
  "typescript": "^5.6.3",
35
- "vitest": "^3.2.4",
36
- "@kb-labs/devkit": "2.94.0"
35
+ "vitest": "^3.2.6",
36
+ "@kb-labs/devkit": "2.98.0",
37
+ "@kb-labs/shared-testing-e2e": "2.98.0"
37
38
  },
38
39
  "engines": {
39
40
  "node": ">=20.0.0",
@@ -50,6 +51,7 @@
50
51
  "lint": "eslint .",
51
52
  "lint:fix": "eslint . --fix",
52
53
  "test": "vitest run --passWithNoTests",
54
+ "test:cli": "vitest run --config vitest.cli.config.ts --passWithNoTests",
53
55
  "test:watch": "vitest",
54
56
  "type-check": "tsc --noEmit"
55
57
  }