@kb-labs/host-agent-entry 2.109.0 → 2.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/list.d.ts +13 -1
- package/dist/commands/list.js +5 -5
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/register.d.ts +4 -1
- package/dist/commands/register.js +9 -9
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/status.d.ts +7 -1
- package/dist/commands/status.js +2 -3
- package/dist/commands/status.js.map +1 -1
- package/package.json +4 -4
package/dist/commands/list.d.ts
CHANGED
|
@@ -9,6 +9,18 @@ type ListInput = {
|
|
|
9
9
|
gateway?: string;
|
|
10
10
|
flags?: ListInput;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
interface HostEntry {
|
|
13
|
+
hostId: string;
|
|
14
|
+
name: string;
|
|
15
|
+
status: string;
|
|
16
|
+
capabilities: string[];
|
|
17
|
+
hostType?: string;
|
|
18
|
+
lastSeen: number;
|
|
19
|
+
connections: string[];
|
|
20
|
+
}
|
|
21
|
+
type ListResult = {
|
|
22
|
+
hosts: HostEntry[];
|
|
23
|
+
};
|
|
24
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, ListInput, ListResult>;
|
|
13
25
|
|
|
14
26
|
export { _default as default };
|
package/dist/commands/list.js
CHANGED
|
@@ -49,19 +49,19 @@ var list_default = defineCommand({
|
|
|
49
49
|
hosts = body.hosts;
|
|
50
50
|
} else {
|
|
51
51
|
handleError(ctx, new Error(`Failed to list hosts: HTTP ${res.status}`), input.json);
|
|
52
|
-
return {
|
|
52
|
+
return { ok: false, error: `Failed to list hosts: HTTP ${res.status}`, result: { hosts: [] } };
|
|
53
53
|
}
|
|
54
54
|
} catch (err) {
|
|
55
55
|
handleError(ctx, new Error(`Cannot reach Gateway at ${gatewayUrl}: ${err instanceof Error ? err.message : String(err)}`), input.json);
|
|
56
|
-
return {
|
|
56
|
+
return { ok: false, error: `Cannot reach Gateway at ${gatewayUrl}`, result: { hosts: [] } };
|
|
57
57
|
}
|
|
58
58
|
if (input.json) {
|
|
59
59
|
ctx.ui?.json?.({ hosts });
|
|
60
|
-
return {
|
|
60
|
+
return { ok: true, result: { hosts } };
|
|
61
61
|
}
|
|
62
62
|
if (hosts.length === 0) {
|
|
63
63
|
ctx.ui?.info?.("No Workspace Agents connected.");
|
|
64
|
-
return {
|
|
64
|
+
return { ok: true, result: { hosts: [] } };
|
|
65
65
|
}
|
|
66
66
|
const ago = (ts) => {
|
|
67
67
|
const sec = Math.floor((Date.now() - ts) / 1e3);
|
|
@@ -86,7 +86,7 @@ var list_default = defineCommand({
|
|
|
86
86
|
)
|
|
87
87
|
}]
|
|
88
88
|
});
|
|
89
|
-
return {
|
|
89
|
+
return { ok: true, result: { hosts } };
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/list.ts"],"names":[],"mappings":";;;;;;
|
|
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, type CommandResult } 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 = { hosts: HostEntry[] };\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<CommandResult<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 { ok: false, error: `Failed to list hosts: HTTP ${res.status}`, result: { 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 { ok: false, error: `Cannot reach Gateway at ${gatewayUrl}`, result: { hosts: [] } };\n }\n\n if (input.json) {\n ctx.ui?.json?.({ hosts });\n return { ok: true, result: { hosts } };\n }\n\n if (hosts.length === 0) {\n ctx.ui?.info?.('No Workspace Agents connected.');\n return { ok: true, result: { 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 { ok: true, result: { hosts } };\n },\n },\n});\n"]}
|
|
@@ -9,6 +9,9 @@ interface RegisterFlags {
|
|
|
9
9
|
json?: boolean;
|
|
10
10
|
'dry-run'?: boolean;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
type RegisterResult = {
|
|
13
|
+
configPath?: string;
|
|
14
|
+
};
|
|
15
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<RegisterFlags>, RegisterResult>;
|
|
13
16
|
|
|
14
17
|
export { _default as default };
|
|
@@ -37,17 +37,17 @@ var register_default = defineCommand({
|
|
|
37
37
|
}
|
|
38
38
|
if (!pathStat?.isDirectory()) {
|
|
39
39
|
validationError(ctx, `Workspace path does not exist or is not a directory: ${resolved}`, void 0, flags.json);
|
|
40
|
-
return {
|
|
40
|
+
return { ok: false, error: `Workspace path does not exist or is not a directory: ${resolved}` };
|
|
41
41
|
}
|
|
42
42
|
workspacePaths.push(resolved);
|
|
43
43
|
}
|
|
44
44
|
if (!gatewayUrl) {
|
|
45
45
|
validationError(ctx, "--gateway is required", "Usage: kb workspace:register --gateway http://localhost:4000", flags.json);
|
|
46
|
-
return {
|
|
46
|
+
return { ok: false, error: "--gateway is required" };
|
|
47
47
|
}
|
|
48
48
|
if (!gatewayUrl.startsWith("http://") && !gatewayUrl.startsWith("https://")) {
|
|
49
49
|
validationError(ctx, "Invalid gateway URL \u2014 must start with http:// or https://", void 0, flags.json);
|
|
50
|
-
return {
|
|
50
|
+
return { ok: false, error: "Invalid gateway URL" };
|
|
51
51
|
}
|
|
52
52
|
ctx.ui?.info?.(`Registering with Gateway: ${gatewayUrl}`);
|
|
53
53
|
let res;
|
|
@@ -59,29 +59,29 @@ var register_default = defineCommand({
|
|
|
59
59
|
});
|
|
60
60
|
} catch (err) {
|
|
61
61
|
handleError(ctx, err instanceof Error ? new Error(`Failed to reach Gateway: ${err.message}`) : err, flags.json);
|
|
62
|
-
return {
|
|
62
|
+
return { ok: false, error: err instanceof Error ? `Failed to reach Gateway: ${err.message}` : String(err) };
|
|
63
63
|
}
|
|
64
64
|
if (!res.ok) {
|
|
65
65
|
const rawBody = await res.text().catch(() => "");
|
|
66
66
|
const body = rawBody.slice(0, 200).replace(/[\r\n]/g, " ");
|
|
67
67
|
handleError(ctx, new Error(`Gateway returned ${res.status}: ${body}`), flags.json);
|
|
68
|
-
return {
|
|
68
|
+
return { ok: false, error: `Gateway returned ${res.status}: ${body}` };
|
|
69
69
|
}
|
|
70
70
|
let data;
|
|
71
71
|
try {
|
|
72
72
|
data = await res.json();
|
|
73
73
|
} catch {
|
|
74
74
|
handleError(ctx, new Error("Gateway response is not valid JSON"), flags.json);
|
|
75
|
-
return {
|
|
75
|
+
return { ok: false, error: "Gateway response is not valid JSON" };
|
|
76
76
|
}
|
|
77
77
|
if (!data.clientId || !data.clientSecret || !data.hostId) {
|
|
78
78
|
handleError(ctx, new Error("Gateway response is missing required fields (clientId, clientSecret, hostId)"), flags.json);
|
|
79
|
-
return {
|
|
79
|
+
return { ok: false, error: "Gateway response is missing required fields" };
|
|
80
80
|
}
|
|
81
81
|
const SECRET_PATTERN = /^[A-Za-z0-9_\-+/=]{16,}$/;
|
|
82
82
|
if (typeof data.clientSecret !== "string" || !SECRET_PATTERN.test(data.clientSecret)) {
|
|
83
83
|
handleError(ctx, new Error("Gateway returned an invalid client secret (unexpected format)"), flags.json);
|
|
84
|
-
return {
|
|
84
|
+
return { ok: false, error: "Gateway returned an invalid client secret" };
|
|
85
85
|
}
|
|
86
86
|
const kbDir = join(homedir(), ".kb");
|
|
87
87
|
await mkdir(kbDir, { recursive: true });
|
|
@@ -117,7 +117,7 @@ var register_default = defineCommand({
|
|
|
117
117
|
hint: "Next: start the daemon with `kb-dev start host-agent` or `kb workspace:start`."
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
|
-
return {
|
|
120
|
+
return { ok: true, result: { configPath } };
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/register.ts"],"names":[],"mappings":";;;;;;AAwBA,IAAO,mBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,oBAAA;AAAA,EACJ,WAAA,EAAa,+CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,MAAA,CAAO,IAAA,EAAuB,KAAA,EAAgC;AAClE,MAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,MAAA,MAAM,cAAc,KAAA,CAAM,OAAA,IAAW,EAAA,EAAI,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC1D,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,gBAAA;AAC3B,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,CAAA,sCAAA,EAAyC,UAAA,IAAc,WAAW,CAAA,CAAA;AAAA,QAC3E,UAAA,EAAY;AAAA,UACV,EAAE,IAAA,EAAM,QAAA,EAAmB,QAAA,EAAU,mBAAA,EAAqB,SAAS,EAAE,IAAA,EAAM,OAAA,EAAS,UAAA,EAAW,EAAE;AAAA,UACjG,EAAE,MAAM,QAAA,EAAmB,QAAA,EAAU,QAAQ,OAAA,EAAS,EAAE,IAAA,EAAM,kBAAA,EAAmB;AAAE;AACrF,OACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAyD;AAC3F,MAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,MAAA,MAAM,cAAc,KAAA,CAAM,OAAA,IAAW,EAAA,EAAI,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC1D,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,IAAQ,QAAA,EAAS;AACpC,MAAA,MAAM,WAAA,GAAc,MAAM,SAAA,IAAa,SAAA;AACvC,MAAA,MAAM,eAAe,KAAA,CAAM,SAAA;AAC3B,MAAA,MAAM,QAAA,GAAW,YAAA,GACZ,KAAA,CAAM,OAAA,CAAQ,YAAY,CAAA,GAAI,YAAA,GAAe,CAAC,YAAiC,CAAA,GAChF,CAAC,OAAA,CAAQ,KAAK,CAAA;AAGlB,MAAA,MAAM,iBAA2B,EAAC;AAClC,MAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,QAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,SAAA,CAAU,CAAC,CAAC,CAAA;AACrC,QAAA,IAAI,QAAA,GAAoD,IAAA;AACxD,QAAA,IAAI;AAAE,UAAA,QAAA,GAAW,MAAM,KAAK,QAAQ,CAAA;AAAA,QAAG,CAAA,CAAA,MAAQ;AAAA,QAAyB;AACxE,QAAA,IAAI,CAAC,QAAA,EAAU,WAAA,EAAY,EAAG;AAC5B,UAAA,eAAA,CAAgB,KAAK,CAAA,qDAAA,EAAwD,QAAQ,CAAA,CAAA,EAAI,MAAA,EAAW,MAAM,IAAI,CAAA;AAC9G,UAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,QACvB;AACA,QAAA,cAAA,CAAe,KAAK,QAAQ,CAAA;AAAA,MAC9B;AAEA,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,eAAA,CAAgB,GAAA,EAAK,uBAAA,EAAyB,8DAAA,EAAgE,KAAA,CAAM,IAAI,CAAA;AACxH,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAGA,MAAA,IAAI,CAAC,WAAW,UAAA,CAAW,SAAS,KAAK,CAAC,UAAA,CAAW,UAAA,CAAW,UAAU,CAAA,EAAG;AAC3E,QAAA,eAAA,CAAgB,GAAA,EAAK,gEAAA,EAA6D,MAAA,EAAW,KAAA,CAAM,IAAI,CAAA;AACvG,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,CAAA,0BAAA,EAA6B,UAAU,CAAA,CAAE,CAAA;AAGxD,MAAA,IAAI,GAAA;AACJ,MAAA,IAAI;AACF,QAAA,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,cAAA,CAAA,EAAkB;AAAA,UAC/C,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,UAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAM,WAAA,EAAa,YAAA,EAAc,CAAC,YAAA,EAAc,KAAA,EAAO,WAAA,EAAa,QAAA,EAAU,OAAO,GAAG;AAAA,SAChH,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,WAAA,CAAY,GAAA,EAAK,GAAA,YAAe,KAAA,GAAQ,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA,GAAI,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AAC9G,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,UAAU,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC/C,QAAA,MAAM,IAAA,GAAO,QAAQ,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,CAAE,OAAA,CAAQ,WAAW,GAAG,CAAA;AACzD,QAAA,WAAA,CAAY,GAAA,EAAK,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA;AACjF,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,MAAM,IAAI,IAAA,EAAK;AAAA,MACxB,CAAA,CAAA,MAAQ;AACN,QAAA,WAAA,CAAY,KAAK,IAAI,KAAA,CAAM,oCAAoC,CAAA,EAAG,MAAM,IAAI,CAAA;AAC5E,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAEA,MAAA,IAAI,CAAC,KAAK,QAAA,IAAY,CAAC,KAAK,YAAA,IAAgB,CAAC,KAAK,MAAA,EAAQ;AACxD,QAAA,WAAA,CAAY,KAAK,IAAI,KAAA,CAAM,8EAA8E,CAAA,EAAG,MAAM,IAAI,CAAA;AACtH,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAGA,MAAA,MAAM,cAAA,GAAiB,0BAAA;AACvB,MAAA,IAAI,OAAO,KAAK,YAAA,KAAiB,QAAA,IAAY,CAAC,cAAA,CAAe,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA,EAAG;AACpF,QAAA,WAAA,CAAY,KAAK,IAAI,KAAA,CAAM,+DAA+D,CAAA,EAAG,MAAM,IAAI,CAAA;AACvG,QAAA,OAAO,EAAE,UAAU,CAAA,EAAE;AAAA,MACvB;AAGA,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,EAAQ,EAAG,KAAK,CAAA;AACnC,MAAA,MAAM,KAAA,CAAM,KAAA,EAAO,EAAE,SAAA,EAAW,MAAM,CAAA;AACtC,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,EAAO,YAAY,CAAA;AAE3C,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,cAAc,IAAA,CAAK,YAAA;AAAA,QACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,UAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA,EAAU,OAAA;AAAA,QACV,cAAA;AAAA,QACA,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,YAAA;AAAA,UACN,SAAA,EAAW;AAAA;AACb,OACF;AAEA,MAAA,MAAM,SAAA,CAAU,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAEjF,MAAA,IAAI,MAAM,IAAA,EAAM;AACd,QAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,KAAK,MAAA,EAAQ,QAAA,EAAU,IAAA,CAAK,QAAA,EAAU,CAAA;AAAA,MAC7E,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,EAAA,EAAI,UAAU,4BAAA,EAA8B;AAAA,UAC9C,UAAU,CAAC;AAAA,YACT,KAAA,EAAO;AAAA,cACL,CAAA,YAAA,EAAe,KAAK,MAAM,CAAA,CAAA;AAAA,cAC1B,CAAA,YAAA,EAAe,KAAK,QAAQ,CAAA,CAAA;AAAA,cAC5B,eAAe,UAAU,CAAA,CAAA;AAAA,cACzB,eAAe,WAAW,CAAA,CAAA;AAAA,cAC1B,CAAA,YAAA,EAAe,cAAA,CAAe,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,cACxC,eAAe,UAAU,CAAA;AAAA;AAC3B,WACD,CAAA;AAAA,UACD,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,EAAE,QAAA,EAAU,CAAA,EAAG,UAAA,EAAW;AAAA,IACnC;AAAA;AAEJ,CAAC","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"]}
|
|
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, type CommandResult } 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 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<CommandResult<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 { ok: false, error: `Workspace path does not exist or is not a directory: ${resolved}` };\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 { ok: false, error: '--gateway is required' };\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 { ok: false, error: 'Invalid gateway URL' };\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 { ok: false, error: err instanceof Error ? `Failed to reach Gateway: ${err.message}` : String(err) };\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 { ok: false, error: `Gateway returned ${res.status}: ${body}` };\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 { ok: false, error: 'Gateway response is not valid JSON' };\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 { ok: false, error: 'Gateway response is missing required fields' };\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 { ok: false, error: 'Gateway returned an invalid client secret' };\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 { ok: true, result: { configPath } };\n },\n },\n});\n"]}
|
|
@@ -8,6 +8,12 @@ type StatusInput = {
|
|
|
8
8
|
json?: boolean;
|
|
9
9
|
flags?: StatusInput;
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
type StatusResult = {
|
|
12
|
+
running: boolean;
|
|
13
|
+
connected?: boolean;
|
|
14
|
+
hostId?: string;
|
|
15
|
+
gatewayUrl?: string;
|
|
16
|
+
};
|
|
17
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, StatusInput, StatusResult>;
|
|
12
18
|
|
|
13
19
|
export { _default as default };
|
package/dist/commands/status.js
CHANGED
|
@@ -24,11 +24,10 @@ var status_default = defineCommand({
|
|
|
24
24
|
} else {
|
|
25
25
|
ctx.ui?.info?.("Workspace Agent is not running. Start with: kb-dev start host-agent");
|
|
26
26
|
}
|
|
27
|
-
return {
|
|
27
|
+
return { ok: true, result: { running: false } };
|
|
28
28
|
}
|
|
29
29
|
const statusLabel = ipcStatus.connected ? "connected" : ipcStatus.reconnecting ? "reconnecting..." : "disconnected";
|
|
30
30
|
const result = {
|
|
31
|
-
exitCode: 0,
|
|
32
31
|
running: true,
|
|
33
32
|
connected: ipcStatus.connected,
|
|
34
33
|
hostId: ipcStatus.hostId,
|
|
@@ -47,7 +46,7 @@ var status_default = defineCommand({
|
|
|
47
46
|
}]
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
|
-
return result;
|
|
49
|
+
return { ok: true, result };
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;AAqBA,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,EAA6D;AAC/F,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,EAAA,EAAI,IAAA,EAAM,QAAQ,EAAE,OAAA,EAAS,OAAM,EAAE;AAAA,MAChD;AAEA,MAAA,MAAM,cAAc,SAAA,CAAU,SAAA,GAC1B,WAAA,GACA,SAAA,CAAU,eACR,iBAAA,GACA,cAAA;AAEN,MAAA,MAAM,MAAA,GAAuB;AAAA,QAC3B,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,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAO;AAAA,IAC5B;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, type CommandResult } 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 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<CommandResult<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 { ok: true, result: { running: false } };\n }\n\n const statusLabel = ipcStatus.connected\n ? 'connected'\n : ipcStatus.reconnecting\n ? 'reconnecting...'\n : 'disconnected';\n\n const result: StatusResult = {\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 { ok: true, result };\n },\n },\n});\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.
|
|
4
|
+
"version": "2.111.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"type-check": "tsc --noEmit"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@kb-labs/host-agent-client": "^2.
|
|
36
|
-
"@kb-labs/host-agent-contracts": "^2.
|
|
37
|
-
"@kb-labs/host-agent-transport": "^2.
|
|
35
|
+
"@kb-labs/host-agent-client": "^2.111.0",
|
|
36
|
+
"@kb-labs/host-agent-contracts": "^2.111.0",
|
|
37
|
+
"@kb-labs/host-agent-transport": "^2.111.0",
|
|
38
38
|
"@kb-labs/sdk": "workspace:*"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|