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 +2 -2
- package/README.md +24 -15
- package/dist/app.d.ts +1 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +73 -18
- package/dist/app.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +148 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.js +157 -19
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +238 -65
- package/dist/init.js.map +1 -1
- package/dist/registry.d.ts +15 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +81 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +47 -1
- package/dist/runtime.js.map +1 -1
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +120 -0
- package/dist/server.js.map +1 -0
- package/dist/status.d.ts +2 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +65 -0
- package/dist/status.js.map +1 -0
- package/dist/tools/kern.d.ts +6 -1
- package/dist/tools/kern.d.ts.map +1 -1
- package/dist/tools/kern.js +36 -5
- package/dist/tools/kern.js.map +1 -1
- package/dist/tui.d.ts +2 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +199 -0
- package/dist/tui.js.map +1 -0
- package/package.json +2 -1
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
"
|
|
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
|
-
|
|
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":"
|
|
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
|
-
|
|
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
|
-
|
|
13
|
+
const agentName = basename(agentDir);
|
|
14
|
+
await registerAgent(agentName, agentDir);
|
|
12
15
|
process.chdir(agentDir);
|
|
13
|
-
//
|
|
14
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"AAAA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAE,QAAQ,GAAG,KAAK;IAC/D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExB,oBAAoB;IACpB,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAEjC,wCAAwC;IACxC,MAAM,aAAa,GAAG,KAAK,EAAE,IAAY,EAAE,MAAc,EAAE,KAAa,EAAE,OAAe,EAAE,EAAE;QAC3F,2CAA2C;QAC3C,MAAM,OAAO,GAAG,QAAQ,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,MAAM,MAAM,IAAI,EAAE,CAAC;QAE3F,oDAAoD;QACpD,MAAM,CAAC,SAAS,CAAC;YACf,IAAI,EAAE,UAAiB;YACvB,IAAI;YACJ,aAAa,EAAE,KAAK;YACpB,UAAU,EAAE,MAAM;YAClB,WAAW,EAAE,OAAO;SACrB,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,KAAkB,EAAE,EAAE;YAC1D,sCAAsC;YACtC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAExC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAClC,MAAM,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAE/B,kDAAkD;IAClD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACrD,IAAI,CAAC,QAAQ,IAAI,aAAa,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,YAAY,IAAI,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QACpE,MAAM,QAAQ,CAAC,KAAK,CAAC;YACnB,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;gBAChC,MAAM,OAAO,GAAG,QAAQ,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAEnH,oCAAoC;gBACpC,MAAM,CAAC,SAAS,CAAC;oBACf,IAAI,EAAE,UAAiB;oBACvB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,aAAa,EAAE,GAAG,CAAC,SAAS;oBAC5B,UAAU,EAAE,GAAG,CAAC,MAAM;oBACtB,WAAW,EAAE,GAAG,CAAC,OAAO;iBACzB,CAAC,CAAC;gBAEH,OAAO,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,KAAkB,EAAE,EAAE;oBAC3D,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,eAAe;IACf,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,IAAI,OAAO,GAAG,SAAS,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjG,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,CAAC,CAAC,EAAE,CAAC,CAAC;IACN,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,KAAK,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,KAAK,SAAS,KAAK,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,KAAK,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,KAAK,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,KAAK,GAAG,CAAC,kDAAkD,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,EAAE,CAAC,CAAC;IAEN,6DAA6D;IAC7D,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,GAAG,CAAC,KAAK,CAAC;YACd,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;gBAChC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;gBACzB,OAAO,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,KAAkB,EAAE,EAAE;oBAC3D,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -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;
|
|
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
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
//
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|