kern-ai 0.1.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.
Files changed (66) hide show
  1. package/README.md +111 -0
  2. package/dist/app.d.ts +2 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +34 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/config.d.ts +12 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +48 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +33 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/init.d.ts +2 -0
  15. package/dist/init.d.ts.map +1 -0
  16. package/dist/init.js +187 -0
  17. package/dist/init.js.map +1 -0
  18. package/dist/interfaces/cli.d.ts +14 -0
  19. package/dist/interfaces/cli.d.ts.map +1 -0
  20. package/dist/interfaces/cli.js +142 -0
  21. package/dist/interfaces/cli.js.map +1 -0
  22. package/dist/interfaces/telegram.d.ts +10 -0
  23. package/dist/interfaces/telegram.d.ts.map +1 -0
  24. package/dist/interfaces/telegram.js +55 -0
  25. package/dist/interfaces/telegram.js.map +1 -0
  26. package/dist/interfaces/types.d.ts +17 -0
  27. package/dist/interfaces/types.d.ts.map +1 -0
  28. package/dist/interfaces/types.js +2 -0
  29. package/dist/interfaces/types.js.map +1 -0
  30. package/dist/runtime.d.ts +22 -0
  31. package/dist/runtime.d.ts.map +1 -0
  32. package/dist/runtime.js +99 -0
  33. package/dist/runtime.js.map +1 -0
  34. package/dist/session.d.ts +21 -0
  35. package/dist/session.d.ts.map +1 -0
  36. package/dist/session.js +102 -0
  37. package/dist/session.js.map +1 -0
  38. package/dist/tools/bash.d.ts +5 -0
  39. package/dist/tools/bash.d.ts.map +1 -0
  40. package/dist/tools/bash.js +30 -0
  41. package/dist/tools/bash.js.map +1 -0
  42. package/dist/tools/edit.d.ts +7 -0
  43. package/dist/tools/edit.d.ts.map +1 -0
  44. package/dist/tools/edit.js +37 -0
  45. package/dist/tools/edit.js.map +1 -0
  46. package/dist/tools/glob.d.ts +5 -0
  47. package/dist/tools/glob.d.ts.map +1 -0
  48. package/dist/tools/glob.js +29 -0
  49. package/dist/tools/glob.js.map +1 -0
  50. package/dist/tools/grep.d.ts +6 -0
  51. package/dist/tools/grep.d.ts.map +1 -0
  52. package/dist/tools/grep.js +38 -0
  53. package/dist/tools/grep.js.map +1 -0
  54. package/dist/tools/index.d.ts +32 -0
  55. package/dist/tools/index.d.ts.map +1 -0
  56. package/dist/tools/index.js +15 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/read.d.ts +6 -0
  59. package/dist/tools/read.d.ts.map +1 -0
  60. package/dist/tools/read.js +36 -0
  61. package/dist/tools/read.js.map +1 -0
  62. package/dist/tools/write.d.ts +5 -0
  63. package/dist/tools/write.d.ts.map +1 -0
  64. package/dist/tools/write.js +22 -0
  65. package/dist/tools/write.js.map +1 -0
  66. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # kern
2
+
3
+ Simple agent runtime. Give any AI agent persistent memory and a Telegram interface.
4
+
5
+ kern pairs with [agent-kernel](https://github.com/oguzbilgic/agent-kernel) — the kernel defines how an agent remembers, kern runs it.
6
+
7
+ ## Quick start
8
+
9
+ ```bash
10
+ npx kern init my-agent
11
+ cd my-agent
12
+ npx kern
13
+ ```
14
+
15
+ The init wizard asks for a provider, API key, and model — then scaffolds an agent with persistent memory.
16
+
17
+ ## What it does
18
+
19
+ - **Runs an AI agent** with tools (bash, file read/write/edit, glob, grep)
20
+ - **Persists conversation** as JSONL — sessions resume where they left off
21
+ - **Streams responses** to the terminal with a live TUI
22
+ - **Reads AGENTS.md** as system prompt — the agent-kernel pattern for stateful agents
23
+ - **Connects to Telegram** (optional) — message your agent from anywhere
24
+
25
+ ## How it works
26
+
27
+ ```
28
+ You (CLI or Telegram)
29
+ → kern runtime
30
+ → Vercel AI SDK (model-agnostic)
31
+ → tools execute (bash, read, write, edit, glob, grep)
32
+ → response streams back
33
+ → conversation saved to .kern/sessions/
34
+ ```
35
+
36
+ The agent's memory lives in the repo — AGENTS.md, IDENTITY.md, KNOWLEDGE.md, knowledge/, notes/. The agent reads and writes these files through tools. Everything is plain text and git-tracked.
37
+
38
+ ## Project structure
39
+
40
+ After `kern init`, your agent directory looks like:
41
+
42
+ ```
43
+ my-agent/
44
+ AGENTS.md # agent kernel — how the agent behaves
45
+ IDENTITY.md # who the agent is
46
+ KNOWLEDGE.md # index of knowledge files
47
+ knowledge/ # mutable state files
48
+ notes/ # daily logs (append-only)
49
+ .kern/
50
+ config.json # model, provider, tools (committed)
51
+ .env # API keys, bot tokens (gitignored)
52
+ sessions/ # conversation history (gitignored)
53
+ ```
54
+
55
+ ## Configuration
56
+
57
+ `.kern/config.json`:
58
+
59
+ ```json
60
+ {
61
+ "model": "anthropic/claude-opus-4",
62
+ "provider": "openrouter",
63
+ "tools": ["bash", "read", "write", "edit", "glob", "grep"],
64
+ "maxSteps": 30
65
+ }
66
+ ```
67
+
68
+ `.kern/.env`:
69
+
70
+ ```
71
+ OPENROUTER_API_KEY=sk-or-...
72
+ TELEGRAM_BOT_TOKEN=...
73
+ ```
74
+
75
+ ## Providers
76
+
77
+ - **openrouter** — any model via OpenRouter (default)
78
+ - **anthropic** — direct Anthropic API
79
+ - **openai** — OpenAI / Azure
80
+
81
+ ## CLI usage
82
+
83
+ ```bash
84
+ kern init <name> # create a new agent
85
+ kern <dir> # run agent in directory
86
+ kern # run agent in current directory
87
+ ```
88
+
89
+ ## Telegram
90
+
91
+ Set `TELEGRAM_BOT_TOKEN` in `.kern/.env` and kern automatically connects via long polling. No public URL needed — works behind NAT.
92
+
93
+ Optional: restrict access with allowed user IDs in `.kern/config.json`:
94
+
95
+ ```json
96
+ {
97
+ "telegram": {
98
+ "allowedUsers": [123456789]
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Built with
104
+
105
+ - [Vercel AI SDK](https://sdk.vercel.ai) — model-agnostic AI layer
106
+ - [grammY](https://grammy.dev) — Telegram bot framework
107
+ - [agent-kernel](https://github.com/oguzbilgic/agent-kernel) — the memory pattern
108
+
109
+ ## License
110
+
111
+ MIT
package/dist/app.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function startApp(agentDir: string): Promise<void>;
2
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAMA,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC9D"}
package/dist/app.js ADDED
@@ -0,0 +1,34 @@
1
+ import { Runtime } from "./runtime.js";
2
+ import { TelegramInterface } from "./interfaces/telegram.js";
3
+ import { CliInterface, dim, bold, cyan } from "./interfaces/cli.js";
4
+ import { loadConfig } from "./config.js";
5
+ export async function startApp(agentDir) {
6
+ const config = await loadConfig(agentDir);
7
+ const runtime = new Runtime(agentDir);
8
+ await runtime.init();
9
+ // Set working directory to agent dir so tools operate there
10
+ process.chdir(agentDir);
11
+ // Pick interface: Telegram if token set, otherwise CLI
12
+ let iface;
13
+ const telegramToken = process.env.TELEGRAM_BOT_TOKEN;
14
+ if (telegramToken) {
15
+ const allowedUsers = config.telegram?.allowedUsers || [];
16
+ iface = new TelegramInterface(telegramToken, allowedUsers);
17
+ }
18
+ else {
19
+ iface = new CliInterface();
20
+ }
21
+ const handler = async (msg, onEvent) => {
22
+ return runtime.handleMessage(msg.text, onEvent);
23
+ };
24
+ const w = (s) => process.stdout.write(s + "\n");
25
+ w("");
26
+ w(` ${bold("kern")} ${cyan(agentDir)}`);
27
+ w(` ${"model"} ${dim(config.provider + "/" + config.model)}`);
28
+ w(` ${"session"} ${dim(runtime.getSessionId() || "new")}`);
29
+ w(` ${"tools"} ${dim(config.tools.join(", "))}`);
30
+ w(` ${dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}`);
31
+ w("");
32
+ await iface.start({ onMessage: handler, history: runtime.getMessages() });
33
+ }
34
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,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;AAGzC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,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,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExB,uDAAuD;IACvD,IAAI,KAAgB,CAAC;IACrB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAErD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,YAAY,IAAI,EAAE,CAAC;QACzD,KAAK,GAAG,IAAI,iBAAiB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,OAAO,GAAmB,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QACrD,OAAO,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAExD,CAAC,CAAC,EAAE,CAAC,CAAC;IACN,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzC,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,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,KAAK,GAAG,CAAC,kDAAkD,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,EAAE,CAAC,CAAC;IAEN,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface KernConfig {
2
+ model: string;
3
+ provider: string;
4
+ tools: string[];
5
+ maxSteps: number;
6
+ telegram?: {
7
+ allowedUsers?: number[];
8
+ };
9
+ }
10
+ export declare function loadConfig(agentDir: string): Promise<KernConfig>;
11
+ export declare function loadSystemPrompt(agentDir: string): Promise<string>;
12
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AASD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBtE;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBxE"}
package/dist/config.js ADDED
@@ -0,0 +1,48 @@
1
+ import { readFile } from "fs/promises";
2
+ import { join } from "path";
3
+ import { existsSync } from "fs";
4
+ import { config as loadDotenv } from "dotenv";
5
+ const defaults = {
6
+ model: "claude-sonnet-4-20250514",
7
+ provider: "anthropic",
8
+ tools: ["bash", "read", "write", "edit", "glob", "grep"],
9
+ maxSteps: 30,
10
+ };
11
+ export async function loadConfig(agentDir) {
12
+ // Load .kern/.env
13
+ const envPath = join(agentDir, ".kern", ".env");
14
+ if (existsSync(envPath)) {
15
+ loadDotenv({ path: envPath });
16
+ }
17
+ // Load .kern/config.json
18
+ const configPath = join(agentDir, ".kern", "config.json");
19
+ if (!existsSync(configPath)) {
20
+ return defaults;
21
+ }
22
+ try {
23
+ const raw = await readFile(configPath, "utf-8");
24
+ const userConfig = JSON.parse(raw);
25
+ return { ...defaults, ...userConfig };
26
+ }
27
+ catch {
28
+ return defaults;
29
+ }
30
+ }
31
+ export async function loadSystemPrompt(agentDir) {
32
+ const parts = [];
33
+ // Load AGENTS.md (kernel)
34
+ const agentsPath = join(agentDir, "AGENTS.md");
35
+ if (existsSync(agentsPath)) {
36
+ parts.push(await readFile(agentsPath, "utf-8"));
37
+ }
38
+ // Load IDENTITY.md
39
+ const identityPath = join(agentDir, "IDENTITY.md");
40
+ if (existsSync(identityPath)) {
41
+ parts.push(await readFile(identityPath, "utf-8"));
42
+ }
43
+ if (parts.length === 0) {
44
+ return "You are a helpful AI assistant.";
45
+ }
46
+ return parts.join("\n\n---\n\n");
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +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;AAY9C,MAAM,QAAQ,GAAe;IAC3B,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,WAAW;IACrB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACxD,QAAQ,EAAE,EAAE;CACb,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,kBAAkB;IAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,yBAAyB;IACzB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,0BAA0B;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC/C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,mBAAmB;IACnB,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,iCAAiC,CAAC;IAC3C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env -S node --no-deprecation
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env -S node --no-deprecation
2
+ import { resolve } from "path";
3
+ import { existsSync } from "fs";
4
+ import { startApp } from "./app.js";
5
+ import { runInit } from "./init.js";
6
+ 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
+ }
13
+ else {
14
+ // Determine agent directory
15
+ const agentDir = resolve(args[0] || ".");
16
+ if (!existsSync(agentDir)) {
17
+ console.error(`Directory not found: ${agentDir}`);
18
+ process.exit(1);
19
+ }
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.");
26
+ process.exit(1);
27
+ }
28
+ startApp(agentDir).catch((error) => {
29
+ console.error("Fatal:", error.message);
30
+ process.exit(1);
31
+ });
32
+ }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAC/B,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,4DAA4D;IAC5D,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAE/D,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CACX,qEAAqE,CACtE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function runInit(targetArg?: string): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAmCA,wBAAsB,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiL/D"}
package/dist/init.js ADDED
@@ -0,0 +1,187 @@
1
+ import { mkdir, writeFile } from "fs/promises";
2
+ import { join, resolve } from "path";
3
+ import { existsSync } from "fs";
4
+ import { createInterface } from "readline";
5
+ const rl = createInterface({
6
+ input: process.stdin,
7
+ output: process.stdout,
8
+ });
9
+ function ask(question, defaultValue) {
10
+ const suffix = defaultValue ? ` (${defaultValue})` : "";
11
+ return new Promise((resolve) => {
12
+ rl.question(` ${question}${suffix}: `, (answer) => {
13
+ resolve(answer.trim() || defaultValue || "");
14
+ });
15
+ });
16
+ }
17
+ function print(text) {
18
+ console.log(text);
19
+ }
20
+ const MODEL_DEFAULTS = {
21
+ openrouter: "anthropic/claude-opus-4",
22
+ anthropic: "claude-opus-4-20250514",
23
+ openai: "gpt-4o",
24
+ };
25
+ const API_KEY_LABELS = {
26
+ openrouter: "OPENROUTER_API_KEY",
27
+ anthropic: "ANTHROPIC_API_KEY",
28
+ openai: "OPENAI_API_KEY",
29
+ };
30
+ export async function runInit(targetArg) {
31
+ print("");
32
+ print(" kern init");
33
+ print(" ─────────");
34
+ print("");
35
+ // Agent name
36
+ const name = await ask("Agent name", targetArg);
37
+ if (!name) {
38
+ print(" Name is required.");
39
+ rl.close();
40
+ process.exit(1);
41
+ }
42
+ // Determine directory
43
+ const dir = resolve(targetArg || name);
44
+ if (existsSync(dir) && existsSync(join(dir, "AGENTS.md"))) {
45
+ print(` ${dir} already exists and has AGENTS.md. Skipping scaffold.`);
46
+ rl.close();
47
+ return;
48
+ }
49
+ // Provider
50
+ const provider = await ask("Provider", "openrouter");
51
+ // API key
52
+ const apiKeyLabel = API_KEY_LABELS[provider] || "API_KEY";
53
+ const apiKey = await ask(apiKeyLabel);
54
+ // Model
55
+ const defaultModel = MODEL_DEFAULTS[provider] || "anthropic/claude-opus-4";
56
+ const model = await ask("Model", defaultModel);
57
+ // Telegram bot token (optional)
58
+ const telegramToken = await ask("Telegram bot token (optional)");
59
+ // Allowed Telegram user IDs (optional)
60
+ let allowedUsers = [];
61
+ if (telegramToken) {
62
+ const usersStr = await ask("Allowed Telegram user IDs (comma-separated, optional)");
63
+ if (usersStr) {
64
+ allowedUsers = usersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n));
65
+ }
66
+ }
67
+ rl.close();
68
+ print("");
69
+ print(` Creating ${dir}/...`);
70
+ // Create directories
71
+ await mkdir(dir, { recursive: true });
72
+ await mkdir(join(dir, "knowledge"), { recursive: true });
73
+ await mkdir(join(dir, "notes"), { recursive: true });
74
+ await mkdir(join(dir, ".kern", "sessions"), { recursive: true });
75
+ // AGENTS.md — the kernel
76
+ const agentsMd = `# Agent Kernel
77
+
78
+ You are a stateful agent. You remember things between sessions, learn from past work, and build on what came before. See \`IDENTITY.md\` for who you are specifically.
79
+
80
+ You have no built-in memory between sessions. This repo is how you become stateful — read it to remember, write to it so the next session knows what happened.
81
+
82
+ ## Communication
83
+ - Be terse. No filler, no preamble.
84
+ - Don't ask unnecessary questions — figure it out or just do it.
85
+ - When uncertain about something destructive, state what you'd do and why before doing it.
86
+
87
+ ## Session Protocol
88
+
89
+ ### Start
90
+ - Read \`IDENTITY.md\` to know who you are and where you run.
91
+ - Read \`KNOWLEDGE.md\` to know what state files exist and what they cover.
92
+ - Read the most recent 2-3 daily notes from \`notes/\` to pick up context and open items.
93
+
94
+ ### During
95
+ - Verify state before acting — don't trust notes blindly.
96
+ - Commit and push incrementally. Don't batch unrelated changes.
97
+ - If a file operation could overwrite existing content (rename, move), check git status first.
98
+ - Update today's daily note with what was done, decisions made, and any new open items.
99
+ - Never modify a previous day's note — notes are historical and immutable once the day is over.
100
+
101
+ ## Memory Structure
102
+ Memory files are for you, not your human. Write for your future self.
103
+
104
+ Two kinds of memory, kept separate:
105
+
106
+ **State** (\`knowledge/\`) — facts about how things are right now. Mutable. Update when reality changes. See \`KNOWLEDGE.md\` for index.
107
+
108
+ **Narrative** (\`notes/\`) — what happened, what was tried, what decisions were made, and what's still open. Append-only. Never modify a past day's entry.
109
+
110
+ ## Rules
111
+ - Ignore README.md — it's for humans, not for you
112
+ - After updating any files, commit and push changes to origin
113
+ - Keep files factual and concise — this is reference material, not documentation
114
+ - Update files when things change
115
+ `;
116
+ // IDENTITY.md
117
+ const capitalName = name.charAt(0).toUpperCase() + name.slice(1);
118
+ const identityMd = `# Identity
119
+
120
+ You are ${capitalName}. Ask your human to define your role and responsibilities.
121
+
122
+ ## Home
123
+ - Repo: this directory
124
+ `;
125
+ // KNOWLEDGE.md
126
+ const knowledgeMd = `# Knowledge Index
127
+
128
+ No knowledge files yet. Create files in \`knowledge/\` as you learn about your domain.
129
+ `;
130
+ // .kern/config.json
131
+ const config = {
132
+ model,
133
+ provider,
134
+ tools: ["bash", "read", "write", "edit", "glob", "grep"],
135
+ maxSteps: 30,
136
+ };
137
+ if (allowedUsers.length > 0) {
138
+ config.telegram = { allowedUsers };
139
+ }
140
+ // .kern/.env
141
+ const envLines = [];
142
+ if (apiKey) {
143
+ envLines.push(`${apiKeyLabel}=${apiKey}`);
144
+ }
145
+ else {
146
+ envLines.push(`# ${apiKeyLabel}=`);
147
+ }
148
+ if (telegramToken) {
149
+ envLines.push(`TELEGRAM_BOT_TOKEN=${telegramToken}`);
150
+ }
151
+ else {
152
+ envLines.push(`# TELEGRAM_BOT_TOKEN=`);
153
+ }
154
+ // .gitignore
155
+ const gitignore = `.kern/.env
156
+ .kern/sessions/
157
+ node_modules/
158
+ `;
159
+ // Write all files
160
+ await writeFile(join(dir, "AGENTS.md"), agentsMd);
161
+ print(" + AGENTS.md");
162
+ await writeFile(join(dir, "IDENTITY.md"), identityMd);
163
+ print(` + IDENTITY.md (${capitalName})`);
164
+ await writeFile(join(dir, "KNOWLEDGE.md"), knowledgeMd);
165
+ print(" + KNOWLEDGE.md");
166
+ await writeFile(join(dir, ".kern", "config.json"), JSON.stringify(config, null, 2) + "\n");
167
+ print(" + .kern/config.json");
168
+ await writeFile(join(dir, ".kern", ".env"), envLines.join("\n") + "\n");
169
+ print(" + .kern/.env");
170
+ await writeFile(join(dir, ".gitignore"), gitignore);
171
+ print(" + .gitignore");
172
+ // Git init
173
+ const { execSync } = await import("child_process");
174
+ try {
175
+ execSync("git init", { cwd: dir, stdio: "ignore" });
176
+ execSync("git add -A", { cwd: dir, stdio: "ignore" });
177
+ execSync('git commit -m "initial agent setup"', { cwd: dir, stdio: "ignore" });
178
+ print(" + git init + first commit");
179
+ }
180
+ catch {
181
+ print(" (git init skipped)");
182
+ }
183
+ print("");
184
+ print(` Done. Run: cd ${name} && kern`);
185
+ print("");
186
+ }
187
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Interface, StartOptions } from "./types.js";
2
+ declare const dim: (s: string) => string;
3
+ declare const bold: (s: string) => string;
4
+ declare const cyan: (s: string) => string;
5
+ declare const green: (s: string) => string;
6
+ declare const yellow: (s: string) => string;
7
+ declare const red: (s: string) => string;
8
+ export declare class CliInterface implements Interface {
9
+ private rl;
10
+ start({ onMessage, history }: StartOptions): Promise<void>;
11
+ stop(): Promise<void>;
12
+ }
13
+ export { dim, bold, cyan, green, yellow, red };
14
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/interfaces/cli.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1D,QAAA,MAAM,GAAG,GAAI,GAAG,MAAM,WAAyB,CAAC;AAChD,QAAA,MAAM,IAAI,GAAI,GAAG,MAAM,WAAyB,CAAC;AAEjD,QAAA,MAAM,IAAI,GAAI,GAAG,MAAM,WAA0B,CAAC;AAClD,QAAA,MAAM,KAAK,GAAI,GAAG,MAAM,WAA0B,CAAC;AACnD,QAAA,MAAM,MAAM,GAAI,GAAG,MAAM,WAA0B,CAAC;AACpD,QAAA,MAAM,GAAG,GAAI,GAAG,MAAM,WAA0B,CAAC;AA2CjD,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,EAAE,CAAmD;IAEvD,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAuG1D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,142 @@
1
+ import { createInterface } from "readline";
2
+ // ANSI
3
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
4
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
5
+ const blue = (s) => `\x1b[34m${s}\x1b[0m`;
6
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
7
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
8
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
9
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
10
+ const magenta = (s) => `\x1b[35m${s}\x1b[0m`;
11
+ const TOOL_COLORS = {
12
+ bash: red,
13
+ read: cyan,
14
+ write: green,
15
+ edit: yellow,
16
+ glob: magenta,
17
+ grep: blue,
18
+ };
19
+ const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
20
+ const CLEAR_LINE = "\r\x1b[K";
21
+ class Spinner {
22
+ interval = null;
23
+ frame = 0;
24
+ label = "";
25
+ prefix = "";
26
+ start(label, prefix = "") {
27
+ this.stop();
28
+ this.label = label;
29
+ this.prefix = prefix;
30
+ this.frame = 0;
31
+ this.interval = setInterval(() => {
32
+ const s = SPINNER[this.frame % SPINNER.length];
33
+ process.stdout.write(`${CLEAR_LINE}${this.prefix}${dim(`${s} ${this.label}`)}`);
34
+ this.frame++;
35
+ }, 80);
36
+ }
37
+ stop() {
38
+ if (this.interval) {
39
+ clearInterval(this.interval);
40
+ this.interval = null;
41
+ process.stdout.write(CLEAR_LINE);
42
+ }
43
+ }
44
+ }
45
+ export class CliInterface {
46
+ rl = null;
47
+ async start({ onMessage, history }) {
48
+ this.rl = createInterface({
49
+ input: process.stdin,
50
+ output: process.stdout,
51
+ terminal: false,
52
+ });
53
+ // Show recent history (last 2 exchanges)
54
+ if (history && history.length > 0) {
55
+ const recent = history.slice(-4);
56
+ for (const msg of recent) {
57
+ if (msg.role === "user" && typeof msg.content === "string") {
58
+ const preview = msg.content.length > 80 ? msg.content.slice(0, 80) + "..." : msg.content;
59
+ process.stdout.write(dim(` you: ${preview}\n`));
60
+ }
61
+ else if (msg.role === "assistant") {
62
+ const text = typeof msg.content === "string"
63
+ ? msg.content
64
+ : Array.isArray(msg.content)
65
+ ? msg.content
66
+ .filter((p) => p.type === "text")
67
+ .map((p) => p.text)
68
+ .join("")
69
+ : "";
70
+ if (text) {
71
+ const firstLine = text.split("\n")[0];
72
+ const preview = firstLine.length > 80 ? firstLine.slice(0, 80) + "..." : firstLine;
73
+ process.stdout.write(dim(` bot: ${preview}\n`));
74
+ }
75
+ }
76
+ }
77
+ process.stdout.write(dim(" ───\n"));
78
+ }
79
+ process.stdout.write(green("> "));
80
+ this.rl.on("line", async (text) => {
81
+ if (!text.trim()) {
82
+ process.stdout.write(green("> "));
83
+ return;
84
+ }
85
+ const spinner = new Spinner();
86
+ process.stdout.write("\n");
87
+ spinner.start("thinking...", `${blue("◆")} `);
88
+ let hasText = false;
89
+ let toolCount = 0;
90
+ try {
91
+ await onMessage({ text: text.trim(), userId: "cli", chatId: "cli" }, (event) => {
92
+ switch (event.type) {
93
+ case "text-delta":
94
+ if (!hasText) {
95
+ spinner.stop();
96
+ if (toolCount > 0) {
97
+ process.stdout.write("\n");
98
+ }
99
+ process.stdout.write(`${blue("◆")} `);
100
+ hasText = true;
101
+ }
102
+ process.stdout.write(event.text || "");
103
+ break;
104
+ case "tool-call":
105
+ toolCount++;
106
+ spinner.stop();
107
+ const colorFn = TOOL_COLORS[event.toolName || ""] || yellow;
108
+ process.stdout.write(` ${colorFn(event.toolName || "tool")} ${dim(event.toolDetail || "")}\n`);
109
+ spinner.start("thinking...");
110
+ break;
111
+ case "tool-result":
112
+ break;
113
+ case "finish":
114
+ spinner.stop();
115
+ if (hasText) {
116
+ process.stdout.write(`\n\n${green("> ")}`);
117
+ }
118
+ else {
119
+ process.stdout.write(`${dim("(no response)")}\n\n${green("> ")}`);
120
+ }
121
+ break;
122
+ case "error":
123
+ spinner.stop();
124
+ process.stdout.write(`\n${red(event.error || "Unknown error")}\n\n${green("> ")}`);
125
+ break;
126
+ }
127
+ });
128
+ }
129
+ catch {
130
+ spinner.stop();
131
+ if (!hasText) {
132
+ process.stdout.write(green("> "));
133
+ }
134
+ }
135
+ });
136
+ }
137
+ async stop() {
138
+ this.rl?.close();
139
+ }
140
+ }
141
+ export { dim, bold, cyan, green, yellow, red };
142
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/interfaces/cli.ts"],"names":[],"mappings":"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"}