kern-ai 0.2.0 → 0.3.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/KERN.md CHANGED
@@ -6,11 +6,11 @@ You are running inside kern, an agent runtime with a single persistent session s
6
6
  Messages may include context metadata:
7
7
  `[via <interface>, <channel>, user: <id>]`
8
8
 
9
- The same person may reach you from different channels (e.g. telegram and cli). No metadata means CLI. Pay attention to who is talking — different users may have different relationships with you.
9
+ Every message includes metadata. The same person may reach you from different channels (e.g. telegram and tui). Pay attention to who is talking — different users may have different relationships with you.
10
10
 
11
11
  ### Adapting to the interface
12
+ - **TUI / terminal**: Your human is at the keyboard. You can be detailed and use formatting.
12
13
  - **Telegram / Slack DM**: Keep responses short and conversational. No one wants a wall of text on their phone.
13
- - **CLI / terminal**: You can be more detailed and use formatting.
14
14
  - **Slack channels**: Others can see — be professional, stay on topic.
15
15
 
16
16
  ### Cross-channel awareness
package/README.md CHANGED
@@ -19,11 +19,10 @@ kern pairs with [agent-kernel](https://github.com/oguzbilgic/agent-kernel) — t
19
19
 
20
20
  ```bash
21
21
  npx kern-ai init my-agent
22
- cd my-agent
23
- npx kern-ai
22
+ npx kern-ai start my-agent
24
23
  ```
25
24
 
26
- The init wizard asks for a provider, API key, and model — then scaffolds a ready-to-run agent.
25
+ The init wizard asks for a provider, API key, and model — then scaffolds and starts your agent.
27
26
 
28
27
  ## How it works
29
28
 
@@ -38,7 +37,7 @@ Every interface feeds into the same session. The agent reads and writes its own
38
37
 
39
38
  ## Agent structure
40
39
 
41
- After `kern-ai init`, your agent directory looks like:
40
+ After `kern init`, your agent directory looks like:
42
41
 
43
42
  ```
44
43
  my-agent/
@@ -48,13 +47,25 @@ my-agent/
48
47
  knowledge/ # mutable state files
49
48
  notes/ # daily logs (append-only)
50
49
  .kern/
51
- config.json # model, provider, tools (committed)
50
+ config.json # model, provider, toolScope (committed)
52
51
  .env # API keys, bot tokens (gitignored)
53
52
  sessions/ # conversation history (gitignored)
54
53
  ```
55
54
 
56
55
  Everything the agent needs is in this folder. Move it, zip it, clone it — the agent comes with it.
57
56
 
57
+ ## CLI
58
+
59
+ ```bash
60
+ kern init <name> # create a new agent
61
+ kern start [name|path] # start agents (all if no name)
62
+ kern stop [name] # stop agents (all if no name)
63
+ kern list # show all agents
64
+ kern run <name|path> # run in foreground (dev/debug)
65
+ ```
66
+
67
+ Agents auto-register when you init, start, or run them. `kern list` shows every agent kern knows about.
68
+
58
69
  ## Configuration
59
70
 
60
71
  `.kern/config.json`:
@@ -63,7 +74,7 @@ Everything the agent needs is in this folder. Move it, zip it, clone it — the
63
74
  {
64
75
  "model": "anthropic/claude-opus-4",
65
76
  "provider": "openrouter",
66
- "tools": ["bash", "read", "write", "edit", "glob", "grep"],
77
+ "toolScope": "full",
67
78
  "maxSteps": 30
68
79
  }
69
80
  ```
@@ -75,20 +86,18 @@ OPENROUTER_API_KEY=sk-or-...
75
86
  TELEGRAM_BOT_TOKEN=...
76
87
  ```
77
88
 
78
- ## Providers
89
+ ### Tool scopes
90
+
91
+ - **full** — bash, read, write, edit, glob, grep, webfetch, kern
92
+ - **write** — read, write, edit, glob, grep, webfetch, kern
93
+ - **read** — read, glob, grep, webfetch, kern
94
+
95
+ ### Providers
79
96
 
80
97
  - **openrouter** — any model via OpenRouter (default)
81
98
  - **anthropic** — direct Anthropic API
82
99
  - **openai** — OpenAI / Azure
83
100
 
84
- ## CLI
85
-
86
- ```bash
87
- npx kern-ai init <name> # create a new agent
88
- npx kern-ai <dir> # run agent in directory
89
- npx kern-ai # run in current directory
90
- ```
91
-
92
101
  ## Telegram
93
102
 
94
103
  Set `TELEGRAM_BOT_TOKEN` in `.kern/.env` and kern connects via long polling. No public URL needed — works behind NAT.
package/dist/app.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare function startApp(agentDir: string): Promise<void>;
1
+ export declare function startApp(agentDir: string, forceCli?: boolean): Promise<void>;
2
2
  //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAQA,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C9D"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAUA,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwGhF"}
package/dist/app.js CHANGED
@@ -3,30 +3,62 @@ import { TelegramInterface } from "./interfaces/telegram.js";
3
3
  import { CliInterface, dim, bold, cyan } from "./interfaces/cli.js";
4
4
  import { loadConfig } from "./config.js";
5
5
  import { readFile } from "fs/promises";
6
- import { join } from "path";
7
- export async function startApp(agentDir) {
6
+ import { join, basename } from "path";
7
+ import { registerAgent, setPort } from "./registry.js";
8
+ import { AgentServer } from "./server.js";
9
+ export async function startApp(agentDir, forceCli = false) {
8
10
  const config = await loadConfig(agentDir);
9
11
  const runtime = new Runtime(agentDir);
10
12
  await runtime.init();
11
- // Set working directory to agent dir so tools operate there
13
+ const agentName = basename(agentDir);
14
+ await registerAgent(agentName, agentDir);
12
15
  process.chdir(agentDir);
13
- // Pick interface: Telegram if token set, otherwise CLI
14
- let iface;
16
+ // Start HTTP server
17
+ const server = new AgentServer();
18
+ // Handler for messages from any channel
19
+ const handleMessage = async (text, userId, iface, channel) => {
20
+ // Inject context metadata for all channels
21
+ const context = `[via ${iface}${channel ? `, ${channel}` : ""}, user: ${userId}]\n${text}`;
22
+ // Broadcast the incoming message to all SSE clients
23
+ server.broadcast({
24
+ type: "incoming",
25
+ text,
26
+ fromInterface: iface,
27
+ fromUserId: userId,
28
+ fromChannel: channel,
29
+ });
30
+ await runtime.handleMessage(context, (event) => {
31
+ // Broadcast all events to SSE clients
32
+ server.broadcast(event);
33
+ });
34
+ };
35
+ server.setMessageHandler(handleMessage);
36
+ const port = await server.start();
37
+ await setPort(agentName, port);
38
+ // Start Telegram if configured and not forced CLI
15
39
  const telegramToken = process.env.TELEGRAM_BOT_TOKEN;
16
- if (telegramToken) {
40
+ if (!forceCli && telegramToken) {
17
41
  const allowedUsers = config.telegram?.allowedUsers || [];
18
- iface = new TelegramInterface(telegramToken, allowedUsers);
19
- }
20
- else {
21
- iface = new CliInterface();
42
+ const telegram = new TelegramInterface(telegramToken, allowedUsers);
43
+ await telegram.start({
44
+ onMessage: async (msg, onEvent) => {
45
+ const context = `[via ${msg.interface}${msg.channel ? `, ${msg.channel}` : ""}, user: ${msg.userId}]\n${msg.text}`;
46
+ // Broadcast incoming to SSE clients
47
+ server.broadcast({
48
+ type: "incoming",
49
+ text: msg.text,
50
+ fromInterface: msg.interface,
51
+ fromUserId: msg.userId,
52
+ fromChannel: msg.channel,
53
+ });
54
+ return runtime.handleMessage(context, (event) => {
55
+ onEvent(event);
56
+ server.broadcast(event);
57
+ });
58
+ },
59
+ });
22
60
  }
23
- const handler = async (msg, onEvent) => {
24
- // Inject context so the model knows who/where
25
- const context = msg.interface !== "cli"
26
- ? `[via ${msg.interface}${msg.channel ? `, ${msg.channel}` : ""}, user: ${msg.userId}]\n${msg.text}`
27
- : msg.text;
28
- return runtime.handleMessage(context, onEvent);
29
- };
61
+ // Print header
30
62
  const w = (s) => process.stdout.write(s + "\n");
31
63
  let version = "unknown";
32
64
  try {
@@ -39,8 +71,31 @@ export async function startApp(agentDir) {
39
71
  w(` ${"model"} ${dim(config.provider + "/" + config.model)}`);
40
72
  w(` ${"session"} ${dim(runtime.getSessionId() || "new")}`);
41
73
  w(` ${"tools"} ${dim(config.toolScope)}`);
74
+ w(` ${"port"} ${dim(String(port))}`);
42
75
  w(` ${dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}`);
43
76
  w("");
44
- await iface.start({ onMessage: handler, history: runtime.getMessages() });
77
+ // If forceCli, start CLI interface connected to same runtime
78
+ if (forceCli) {
79
+ const cli = new CliInterface();
80
+ await cli.start({
81
+ onMessage: async (msg, onEvent) => {
82
+ const context = msg.text;
83
+ return runtime.handleMessage(context, (event) => {
84
+ onEvent(event);
85
+ server.broadcast(event);
86
+ });
87
+ },
88
+ history: runtime.getMessages(),
89
+ });
90
+ }
91
+ // Graceful shutdown
92
+ process.on("SIGTERM", () => {
93
+ server.stop();
94
+ process.exit(0);
95
+ });
96
+ process.on("SIGINT", () => {
97
+ server.stop();
98
+ process.exit(0);
99
+ });
45
100
  }
46
101
  //# sourceMappingURL=app.js.map
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -4,6 +4,7 @@ export interface KernConfig {
4
4
  provider: string;
5
5
  toolScope: ToolScope;
6
6
  maxSteps: number;
7
+ maxContextTokens: number;
7
8
  telegram?: {
8
9
  allowedUsers?: number[];
9
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAeD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAE3D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBtE;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C5F"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAgBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAE3D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBtE;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA6C5F"}
package/dist/config.js CHANGED
@@ -12,6 +12,7 @@ const defaults = {
12
12
  provider: "anthropic",
13
13
  toolScope: "full",
14
14
  maxSteps: 30,
15
+ maxContextTokens: 40000,
15
16
  };
16
17
  export function getToolsForScope(scope) {
17
18
  return TOOL_SCOPES[scope] || TOOL_SCOPES.full;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function startAgent(nameOrPath?: string): Promise<void>;
2
+ export declare function stopAgent(name?: string): Promise<void>;
3
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAoEA,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCnE;AA6BD,wBAAsB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5D"}
package/dist/daemon.js ADDED
@@ -0,0 +1,148 @@
1
+ import { spawn } from "child_process";
2
+ import { basename } from "path";
3
+ import { existsSync } from "fs";
4
+ import { mkdir } from "fs/promises";
5
+ import { join } from "path";
6
+ import { openSync } from "fs";
7
+ import { findAgent, loadRegistry, registerAgent, setPid, isProcessRunning } from "./registry.js";
8
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
9
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
10
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
11
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
12
+ async function startOne(name, path) {
13
+ // Check if already running
14
+ const existing = await findAgent(name);
15
+ if (existing?.pid && isProcessRunning(existing.pid)) {
16
+ console.log(` ${green("●")} ${bold(name)} already running ${dim(`(pid ${existing.pid})`)}`);
17
+ return;
18
+ }
19
+ if (!existsSync(path)) {
20
+ console.log(` ${red("●")} ${bold(name)} path not found: ${path}`);
21
+ return;
22
+ }
23
+ // Ensure log directory
24
+ const logDir = join(path, ".kern", "logs");
25
+ await mkdir(logDir, { recursive: true });
26
+ const logFile = join(logDir, "kern.log");
27
+ const logFd = openSync(logFile, "a");
28
+ // Find the kern entry point
29
+ const kernBin = join(import.meta.dirname, "index.js");
30
+ // Fork detached process using kern run
31
+ const child = spawn("node", ["--no-deprecation", kernBin, "run", path], {
32
+ detached: true,
33
+ stdio: ["ignore", logFd, logFd],
34
+ cwd: path,
35
+ });
36
+ child.unref();
37
+ const pid = child.pid;
38
+ await registerAgent(name, path);
39
+ await setPid(name, pid);
40
+ // Wait and verify the process stays alive
41
+ await new Promise((resolve) => setTimeout(resolve, 2000));
42
+ if (isProcessRunning(pid)) {
43
+ console.log(` ${green("●")} ${bold(name)} started ${dim(`(pid ${pid})`)}`);
44
+ }
45
+ else {
46
+ await setPid(name, null);
47
+ console.log(` ${red("●")} ${bold(name)} failed to start`);
48
+ // Show last few lines of log
49
+ try {
50
+ const { readFile } = await import("fs/promises");
51
+ const log = await readFile(logFile, "utf-8");
52
+ const lines = log.trim().split("\n").slice(-5);
53
+ for (const line of lines) {
54
+ console.log(` ${dim(line)}`);
55
+ }
56
+ }
57
+ catch { }
58
+ }
59
+ }
60
+ export async function startAgent(nameOrPath) {
61
+ if (nameOrPath) {
62
+ // Try registry first
63
+ let agent = await findAgent(nameOrPath);
64
+ if (!agent) {
65
+ // Check if it's a directory path
66
+ const { resolve } = await import("path");
67
+ const dir = resolve(nameOrPath);
68
+ if (existsSync(dir) && (existsSync(join(dir, ".kern")) || existsSync(join(dir, "AGENTS.md")))) {
69
+ const name = basename(dir);
70
+ await registerAgent(name, dir);
71
+ agent = { name, path: dir, pid: null, addedAt: new Date().toISOString() };
72
+ }
73
+ }
74
+ if (!agent) {
75
+ console.error(`Agent not found: ${nameOrPath}`);
76
+ console.error("Use an agent name from 'kern status' or a path to an agent directory.");
77
+ process.exit(1);
78
+ return;
79
+ }
80
+ console.log("");
81
+ await startOne(agent.name, agent.path);
82
+ console.log("");
83
+ }
84
+ else {
85
+ // Start all registered agents
86
+ const agents = await loadRegistry();
87
+ if (agents.length === 0) {
88
+ console.error("No agents registered. Run 'kern init <name>' first.");
89
+ process.exit(1);
90
+ return;
91
+ }
92
+ console.log("");
93
+ console.log(` ${bold("starting all agents")}`);
94
+ console.log("");
95
+ for (const agent of agents) {
96
+ await startOne(agent.name, agent.path);
97
+ }
98
+ console.log("");
99
+ }
100
+ }
101
+ async function stopOne(name) {
102
+ const agent = await findAgent(name);
103
+ if (!agent) {
104
+ console.log(` ${dim("●")} ${bold(name)} not found`);
105
+ return;
106
+ }
107
+ if (!agent.pid) {
108
+ console.log(` ${dim("●")} ${bold(name)} not running`);
109
+ return;
110
+ }
111
+ if (!isProcessRunning(agent.pid)) {
112
+ console.log(` ${dim("●")} ${bold(name)} not running ${dim("(stale pid cleared)")}`);
113
+ await setPid(name, null);
114
+ return;
115
+ }
116
+ try {
117
+ process.kill(agent.pid, "SIGTERM");
118
+ await setPid(name, null);
119
+ console.log(` ${red("●")} ${bold(name)} stopped ${dim(`(was pid ${agent.pid})`)}`);
120
+ }
121
+ catch (e) {
122
+ console.error(` Failed to stop ${name}: ${e.message}`);
123
+ }
124
+ }
125
+ export async function stopAgent(name) {
126
+ if (name) {
127
+ console.log("");
128
+ await stopOne(name);
129
+ console.log("");
130
+ }
131
+ else {
132
+ // Stop all
133
+ const agents = await loadRegistry();
134
+ if (agents.length === 0) {
135
+ console.log("No agents registered.");
136
+ process.exit(0);
137
+ return;
138
+ }
139
+ console.log("");
140
+ console.log(` ${bold("stopping all agents")}`);
141
+ console.log("");
142
+ for (const agent of agents) {
143
+ await stopOne(agent.name);
144
+ }
145
+ console.log("");
146
+ }
147
+ }
148
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,31 +3,169 @@ import { resolve } from "path";
3
3
  import { existsSync } from "fs";
4
4
  import { startApp } from "./app.js";
5
5
  import { runInit } from "./init.js";
6
+ import { showStatus } from "./status.js";
7
+ import { startAgent, stopAgent } from "./daemon.js";
8
+ import { findAgent, loadRegistry } from "./registry.js";
9
+ import { readFile } from "fs/promises";
10
+ import { join } from "path";
6
11
  const args = process.argv.slice(2);
7
- if (args[0] === "init") {
8
- runInit(args[1]).catch((error) => {
9
- console.error("Error:", error.message);
10
- process.exit(1);
11
- });
12
+ const cmd = args[0];
13
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
14
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
15
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
16
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
17
+ async function showHelp() {
18
+ let version = "unknown";
19
+ try {
20
+ const pkg = JSON.parse(await readFile(join(import.meta.dirname, "..", "package.json"), "utf-8"));
21
+ version = pkg.version;
22
+ }
23
+ catch { }
24
+ const w = (s) => process.stdout.write(s + "\n");
25
+ w("");
26
+ w(` ${bold("kern")} ${dim("v" + version)}`);
27
+ w(` ${dim("One agent. One folder. One continuous conversation.")}`);
28
+ w("");
29
+ w(` ${yellow("Commands")}`);
30
+ w(` ${cyan("kern init")} ${dim("<name>")} create or configure an agent`);
31
+ w(` ${cyan("kern start")} ${dim("[name|path]")} start agents`);
32
+ w(` ${cyan("kern stop")} ${dim("[name]")} stop agents`);
33
+ w(` ${cyan("kern restart")} ${dim("[name]")} restart agents`);
34
+ w(` ${cyan("kern list")} show all agents`);
35
+ w(` ${cyan("kern remove")} ${dim("<name>")} unregister an agent`);
36
+ w(` ${cyan("kern tui")} ${dim("[name]")} interactive chat`);
37
+ w("");
12
38
  }
13
- else {
14
- // Determine agent directory
15
- const agentDir = resolve(args[0] || ".");
16
- if (!existsSync(agentDir)) {
17
- console.error(`Directory not found: ${agentDir}`);
39
+ async function resolveAgentDir(nameOrPath) {
40
+ if (nameOrPath) {
41
+ // Check registry
42
+ const agent = await findAgent(nameOrPath);
43
+ if (agent)
44
+ return agent.path;
45
+ // Check path
46
+ const dir = resolve(nameOrPath);
47
+ if (existsSync(dir) && (existsSync(join(dir, ".kern")) || existsSync(join(dir, "AGENTS.md")))) {
48
+ return dir;
49
+ }
50
+ console.error(`Agent not found: ${nameOrPath}`);
18
51
  process.exit(1);
19
52
  }
20
- // Check for .kern/ or AGENTS.md to verify it's an agent dir
21
- const hasKernDir = existsSync(resolve(agentDir, ".kern"));
22
- const hasAgentsMd = existsSync(resolve(agentDir, "AGENTS.md"));
23
- if (!hasKernDir && !hasAgentsMd) {
24
- console.error(`Not an agent directory: ${agentDir}`);
25
- console.error("Run 'kern init' to set up a new agent, or point to an existing one.");
53
+ // No arg auto-select
54
+ const agents = await loadRegistry();
55
+ if (agents.length === 0) {
56
+ console.error("No agents registered. Run 'kern init <name>' first.");
26
57
  process.exit(1);
27
58
  }
28
- startApp(agentDir).catch((error) => {
29
- console.error("Fatal:", error.message);
30
- process.exit(1);
59
+ if (agents.length === 1) {
60
+ return agents[0].path;
61
+ }
62
+ // Multiple agents — prompt to select
63
+ const { select } = await import("@inquirer/prompts");
64
+ return select({
65
+ message: "Select agent",
66
+ choices: agents.map((a) => ({ name: a.name, value: a.path })),
31
67
  });
32
68
  }
69
+ async function main() {
70
+ if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") {
71
+ await showHelp();
72
+ process.exit(0);
73
+ }
74
+ if (cmd === "init") {
75
+ await runInit(args[1]);
76
+ return;
77
+ }
78
+ if (cmd === "list" || cmd === "ls" || cmd === "status") {
79
+ await showStatus();
80
+ process.exit(0);
81
+ }
82
+ if (cmd === "start") {
83
+ await startAgent(args[1]);
84
+ process.exit(0);
85
+ }
86
+ if (cmd === "stop") {
87
+ await stopAgent(args[1]);
88
+ process.exit(0);
89
+ }
90
+ if (cmd === "restart") {
91
+ await stopAgent(args[1]);
92
+ await new Promise((r) => setTimeout(r, 500));
93
+ await startAgent(args[1]);
94
+ process.exit(0);
95
+ }
96
+ if (cmd === "remove" || cmd === "rm") {
97
+ const name = args[1];
98
+ if (!name) {
99
+ console.error("Usage: kern remove <name>");
100
+ process.exit(1);
101
+ }
102
+ const { removeAgent, findAgent, isProcessRunning } = await import("./registry.js");
103
+ const { stopAgent } = await import("./daemon.js");
104
+ const agent = await findAgent(name);
105
+ if (!agent) {
106
+ console.error(`Agent not found: ${name}`);
107
+ process.exit(1);
108
+ }
109
+ if (agent.pid && isProcessRunning(agent.pid)) {
110
+ await stopAgent(name);
111
+ }
112
+ await removeAgent(name);
113
+ console.log(` Removed ${name}`);
114
+ process.exit(0);
115
+ }
116
+ if (cmd === "tui") {
117
+ const { connectTui } = await import("./tui.js");
118
+ const { findAgent, loadRegistry } = await import("./registry.js");
119
+ const { startAgent } = await import("./daemon.js");
120
+ let agentName = args[1];
121
+ // Auto-select if no arg
122
+ if (!agentName) {
123
+ const agents = await loadRegistry();
124
+ if (agents.length === 0) {
125
+ console.error("No agents registered. Run 'kern init <name>' first.");
126
+ process.exit(1);
127
+ }
128
+ else if (agents.length === 1) {
129
+ agentName = agents[0].name;
130
+ }
131
+ else {
132
+ const { select } = await import("@inquirer/prompts");
133
+ agentName = await select({
134
+ message: "Select agent",
135
+ choices: agents.map((a) => ({ name: a.name, value: a.name })),
136
+ });
137
+ }
138
+ }
139
+ // Check if running, auto-start if not
140
+ let agent = await findAgent(agentName);
141
+ if (!agent) {
142
+ console.error(`Agent not found: ${agentName}`);
143
+ process.exit(1);
144
+ }
145
+ const { isProcessRunning } = await import("./registry.js");
146
+ if (!agent.pid || !isProcessRunning(agent.pid)) {
147
+ await startAgent(agentName);
148
+ // Reload to get the port
149
+ agent = await findAgent(agentName);
150
+ }
151
+ if (!agent?.port) {
152
+ console.error(`Cannot determine port for ${agentName}. Is it running?`);
153
+ process.exit(1);
154
+ }
155
+ await connectTui(agent.port, agentName);
156
+ return;
157
+ }
158
+ if (cmd === "run") {
159
+ const agentDir = await resolveAgentDir(args[1]);
160
+ await startApp(agentDir);
161
+ return;
162
+ }
163
+ console.error(`Unknown command: ${cmd}`);
164
+ await showHelp();
165
+ process.exit(1);
166
+ }
167
+ main().catch((error) => {
168
+ console.error("Fatal:", error.message);
169
+ process.exit(1);
170
+ });
33
171
  //# sourceMappingURL=index.js.map