@swifty.js/larky 0.0.1-alpha

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/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # larky
2
+
3
+ Dual-process CLI coding agent powered by Claude.
4
+
5
+ ## Overview
6
+
7
+ larky is an AI-powered coding agent that runs as a persistent background daemon with multiple front-end interfaces. It uses a plan-act-observe loop driven by Claude (Anthropic) to accomplish user goals through file manipulation, shell commands, and extensible tool integrations.
8
+
9
+ The architecture separates concerns into two processes: a long-lived daemon (larky-core) that manages agent runs, sessions, permissions, and LLM connections, and lightweight client processes (CLI or TUI) that communicate with the daemon over a TCP JSON-RPC protocol.
10
+
11
+ ## Features
12
+
13
+ ### Agent Capabilities
14
+
15
+ - Plan-act-observe loop with configurable step limits (default 20 steps)
16
+ - Built-in tools for file I/O, shell execution, directory listing, note-taking, and task management
17
+ - Subagent spawning for parallel background work (spawn_agent / agent_result)
18
+ - MCP (Model Context Protocol) server integration for third-party tool extensions
19
+ - Agent profiles (planner, executor, reviewer) defined in TOML
20
+ - Skills system with built-in skills (init, orchestrate, review, summarize)
21
+ - Context memory layers: global (~/.larky/context.md), project (.larky/context.md), and session notes
22
+
23
+ ### Session Management
24
+
25
+ - Two session modes: one_shot (single-goal, auto-closing) and chat (multi-turn interactive)
26
+ - Per-run event logs stored in ~/.larky/sessions/{sid}/runs/{runId}/events.jsonl
27
+ - Context compaction (manual /compact or automatic via threshold) for long-running sessions
28
+ - Session notes persistence via note_save tool
29
+
30
+ ### Permission System
31
+
32
+ - Interactive permission prompts for tool invocations
33
+ - Persistent policy file (~/.larky/policy.toml) with four decision types: allow_once, always_allow, deny_once, always_deny
34
+ - Configurable timeout (default 60 seconds)
35
+
36
+ ### Interfaces
37
+
38
+ - CLI with subcommands: ping, run, chat, tui, trace, core start/stop/status, version
39
+ - Terminal UI (TUI) built with Ink and React for interactive sessions
40
+ - JSON-RPC 2.0 TCP protocol for programmatic integration
41
+
42
+ ### Observability
43
+
44
+ - NDJSON trace log (~/.larky/traces/daemon.jsonl) with directional coloring
45
+ - Trace filtering by layer (ipc, event, llm), direction, and run ID
46
+ - Pino-based structured logging with configurable levels
47
+
48
+ ## Architecture
49
+
50
+ ```
51
+ +-----------+ TCP JSON-RPC +------------------+
52
+ | CLI / TUI | <====================> | larky-core |
53
+ | (client) | 127.0.0.1:5520 | (daemon) |
54
+ +-----------+ +-----------------+
55
+ |
56
+ +---------+---------+
57
+ | |
58
+ +-----------+ +------------+
59
+ | Anthropic | | MCP Servers|
60
+ | LLM | | (optional)|
61
+ +-----------+ +------------+
62
+ ```
63
+
64
+ The client spawns a SocketClient that connects to the daemon's SocketServer. Commands flow as JSON-RPC 2.0 requests, while events are pushed via an EventBus through an IpcEventBroadcaster to subscribed clients over the same TCP connection.
65
+
66
+ Agent runs are orchestrated by AgentRunner, which assembles the LLM provider (AnthropicProvider), tool registry, permission manager, MCP tools, and event bus. The AgentLoop drives the plan-act-observe cycle, calling the LLM at each step and invoking tools based on the model's response.
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ # From the monorepo root
72
+ pnpm install
73
+
74
+ # Build the CLI binary
75
+ pnpm --filter @swifty.js/larky build
76
+ ```
77
+
78
+ The bin entry (larky) points to dist/cli/main.js after building.
79
+
80
+ ## Configuration
81
+
82
+ Configuration follows a 5-tier priority chain where later tiers override earlier ones:
83
+
84
+ 1. Built-in defaults (hardcoded)
85
+ 2. Global TOML config (~/.larky/config.toml)
86
+ 3. Project-local TOML (.larky/config.toml)
87
+ 4. dotenv (.env file in current directory)
88
+ 5. Environment variables (LARKY\_ prefix)
89
+
90
+ ### Key Environment Variables
91
+
92
+ | Variable | Default | Description |
93
+ | -------------------------- | ---------------------------- | ------------------------------------------ |
94
+ | ANTHROPIC_API_KEY | (required) | Anthropic API key |
95
+ | ANTHROPIC_BASE_URL | (SDK default) | Override API base URL |
96
+ | LARKY_HOST | 127.0.0.1 | Daemon bind host |
97
+ | LARKY_PORT | 5520 | Daemon bind port |
98
+ | LARKY_LOG_LEVEL | INFO | Log level (DEBUG / INFO / WARN / ERROR) |
99
+ | LARKY_LOG_FILE | ~/.larky/logs/core.log | Log file path |
100
+ | LARKY_MAX_STEPS | 20 | Maximum agent loop steps |
101
+ | LARKY_LLM_DEFAULT_MODEL | claude-sonnet-4-6 | Default LLM model |
102
+ | LARKY_TRACE_ENABLED | true | Enable/disable tracing |
103
+ | LARKY_TRACE_FILE | ~/.larky/traces/daemon.jsonl | Trace file path |
104
+ | LARKY_PERMISSION_TIMEOUT_S | 60 | Permission prompt timeout (seconds) |
105
+ | LARKY_COMPACT_THRESHOLD | 0.0 | Auto-compaction threshold (0.0 = disabled) |
106
+ | LARKY_CONFIG | ~/.larky/config.toml | Path to TOML config file |
107
+
108
+ ### MCP Server Configuration
109
+
110
+ MCP servers are configured in the TOML config file:
111
+
112
+ ```toml
113
+ [[mcp.servers]]
114
+ name = "my-server"
115
+ transport = "stdio"
116
+ command = "npx"
117
+ args = ["-y", "@my/mcp-server"]
118
+ env = { API_KEY = "..." }
119
+ ```
120
+
121
+ ## Usage
122
+
123
+ ### Start the daemon
124
+
125
+ ```bash
126
+ larky core start
127
+ ```
128
+
129
+ ### One-shot task
130
+
131
+ ```bash
132
+ larky run "Summarize the project README"
133
+ ```
134
+
135
+ ### Interactive chat
136
+
137
+ ```bash
138
+ larky chat
139
+ ```
140
+
141
+ ### Terminal UI
142
+
143
+ ```bash
144
+ larky tui
145
+ ```
146
+
147
+ ### Check daemon status
148
+
149
+ ```bash
150
+ larky core status
151
+ larky ping
152
+ ```
153
+
154
+ ### View traces
155
+
156
+ ```bash
157
+ larky trace # All trace records
158
+ larky trace --follow # Tail mode
159
+ larky trace --layer llm # Filter by layer
160
+ larky trace --direction "CORE->LLM" # Filter by direction
161
+ larky trace run-abc123 # Filter by run ID
162
+ ```
163
+
164
+ ### Stop the daemon
165
+
166
+ ```bash
167
+ larky core stop
168
+ ```
169
+
170
+ ### Force-kill all processes
171
+
172
+ ```bash
173
+ node kill.mjs
174
+ ```
175
+
176
+ ## Built-in Tools
177
+
178
+ | Tool | Description |
179
+ | ------------ | ------------------------------ |
180
+ | read_file | Read file contents from disk |
181
+ | write_file | Write content to a file |
182
+ | bash | Execute shell commands |
183
+ | list_dir | List directory entries |
184
+ | note_save | Persist session notes to disk |
185
+ | task_create | Create a tracked task |
186
+ | task_update | Update a task's status |
187
+ | task_list | List all tracked tasks |
188
+ | task_get | Get details of a specific task |
189
+ | spawn_agent | Spawn a background subagent |
190
+ | agent_result | Retrieve a subagent's result |
191
+
192
+ ## Wire Protocol
193
+
194
+ The daemon communicates with clients over TCP loopback using NDJSON (newline-delimited JSON). Commands follow JSON-RPC 2.0 format, while events use a kind=event envelope pushed from server to client. See WIRE_PROTOCOL.md for the full specification of all commands, events, and error codes.
package/RUNBOOK.md ADDED
@@ -0,0 +1,281 @@
1
+ # Larky RUNBOOK
2
+
3
+ Operations and troubleshooting guide for the Larky daemon.
4
+
5
+ ---
6
+
7
+ ## Daemon Lifecycle
8
+
9
+ ### Start the Daemon
10
+
11
+ ```bash
12
+ larky core start # Start in background
13
+ pnpm dev:core # Start in foreground (development)
14
+ ```
15
+
16
+ The daemon listens on `127.0.0.1:5520` by default. It creates a PID file at `~/.larky/larky-core.pid`.
17
+
18
+ ### Check Daemon Status
19
+
20
+ ```bash
21
+ larky core status
22
+ larky ping
23
+ # → pong server=0.0.1 uptime=1234ms latency=2ms
24
+ ```
25
+
26
+ ### Stop the Daemon
27
+
28
+ ```bash
29
+ larky core stop # Graceful shutdown (SIGTERM)
30
+ kill "$(cat ~/.larky/larky-core.pid)" # Manual fallback
31
+ ```
32
+
33
+ On shutdown, the daemon:
34
+
35
+ 1. Aborts all running agent runs via `AbortController`
36
+ 2. Waits up to 5 seconds for runs to settle
37
+ 3. Closes all MCP server connections
38
+ 4. Stops the TCP server
39
+ 5. Flushes the trace writer
40
+
41
+ ### Port Conflict Resolution
42
+
43
+ ```bash
44
+ # Check what's using the port
45
+ lsof -i :5520
46
+
47
+ # Use a different port
48
+ LARKY_PORT=8000 larky core start
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Configuration
54
+
55
+ ### 5-Tier Priority Chain (later tiers override earlier ones)
56
+
57
+ 1. **Built-in defaults** (hardcoded)
58
+ 2. **Global TOML** (`~/.larky/config.toml`)
59
+ 3. **Project-local TOML** (`.larky/config.toml`)
60
+ 4. **dotenv** (`.env` file in current directory)
61
+ 5. **Environment variables** (`LARKY_*` prefix)
62
+
63
+ ### TOML Validation
64
+
65
+ Unknown keys and type mismatches cause immediate exit with a descriptive error:
66
+
67
+ ```
68
+ Config error: Unknown [core] keys: hostname
69
+ Config error: core.port must be an integer
70
+ Config error: compaction.auto_threshold must be between 0 and 1
71
+ ```
72
+
73
+ ### Environment Variables
74
+
75
+ | Variable | Default | Description |
76
+ | --------------------------------- | ------------------------------ | ----------------------------------------------------- |
77
+ | `ANTHROPIC_API_KEY` | (required) | Anthropic API key |
78
+ | `ANTHROPIC_BASE_URL` | (SDK default) | Override API base URL |
79
+ | `LARKY_CONFIG` | `~/.larky/config.toml` | Path to TOML config file |
80
+ | `LARKY_HOST` | `127.0.0.1` | Daemon bind host |
81
+ | `LARKY_PORT` | `5520` | Daemon bind port |
82
+ | `LARKY_LOG_LEVEL` | `INFO` | Log level (DEBUG / INFO / WARN / ERROR) |
83
+ | `LARKY_LOG_FILE` | `~/.larky/logs/core.log` | Log file path |
84
+ | `LARKY_LOG_FORMAT` | `text` | Log format (text / json) |
85
+ | `LARKY_MAX_STEPS` | `20` | Maximum agent loop steps |
86
+ | `LARKY_LLM_DEFAULT_MODEL` | `claude-sonnet-4-6` | Default LLM model |
87
+ | `LARKY_TRACE_ENABLED` | `true` | Enable/disable tracing |
88
+ | `LARKY_TRACE_FILE` | `~/.larky/traces/daemon.jsonl` | Trace file path |
89
+ | `LARKY_TRACE_INCLUDE_LLM_PAYLOAD` | `true` | Include full LLM payloads in traces |
90
+ | `LARKY_PERMISSION_TIMEOUT_S` | `60` | Permission prompt timeout (seconds) |
91
+ | `LARKY_COMPACT_THRESHOLD` | `0.0` | Auto-compaction threshold (0.0 = disabled, 0.8 = 80%) |
92
+ | `LARKY_COMPACT_TOOL_LIMIT` | `8000` | Tool result truncation limit (chars) |
93
+ | `LARKY_COMPACT_TOOL_KEEP` | `4000` | Tool result keep size (chars) |
94
+
95
+ ---
96
+
97
+ ## Error Codes
98
+
99
+ ### Session Errors
100
+
101
+ | Code | Name | Cause | Resolution |
102
+ | ------ | ---------------------- | ---------------------------------- | ------------------------------------------ |
103
+ | -32010 | SESSION_NOT_FOUND | Session ID does not exist | Create a new session with `session.create` |
104
+ | -32011 | SESSION_CLOSED | Session is already closed | Create a new session |
105
+ | -32012 | SESSION_BUSY | Another message is being processed | Wait for the current run to finish |
106
+ | -32020 | PROVIDER_NOT_AVAILABLE | No LLM provider configured | Set `ANTHROPIC_API_KEY` |
107
+ | -32021 | COMPACTION_FAILED | LLM-driven compaction failed | Retry `/compact` or check API key |
108
+
109
+ ### JSON-RPC Standard Errors
110
+
111
+ | Code | Name | Cause |
112
+ | ------ | ---------------- | -------------------------------------- |
113
+ | -32700 | PARSE_ERROR | Malformed JSON in request line |
114
+ | -32600 | INVALID_REQUEST | JSON-RPC envelope validation failed |
115
+ | -32601 | METHOD_NOT_FOUND | Unknown method name |
116
+ | -32602 | INVALID_PARAMS | Parameter validation failed (ZodError) |
117
+ | -32603 | INTERNAL_ERROR | Unhandled exception in handler |
118
+
119
+ ---
120
+
121
+ ## Troubleshooting
122
+
123
+ ### Connection Refused
124
+
125
+ ```
126
+ error: core not running (127.0.0.1:5520)
127
+ ```
128
+
129
+ The daemon is not running. Start it with `larky core start` or `pnpm dev:core`.
130
+
131
+ ### Permission Timeout
132
+
133
+ If a permission prompt is not answered within `LARKY_PERMISSION_TIMEOUT_S` (default 60s), the tool invocation fails with `permission_denied` and decision `timeout`. The agent receives an error and may retry or choose an alternative approach.
134
+
135
+ To resolve:
136
+
137
+ - Increase `LARKY_PERMISSION_TIMEOUT_S` for longer prompts
138
+ - Respond to permission prompts promptly in the TUI
139
+ - Use `always_allow` to pre-approve trusted tools
140
+
141
+ ### MCP Server Startup Failure
142
+
143
+ MCP server failures are non-fatal — the daemon starts without the failed server's tools. Check the log for:
144
+
145
+ ```
146
+ mcp: server 'my-server' failed to start, skipping
147
+ ```
148
+
149
+ Common causes:
150
+
151
+ - `command` not found or not executable
152
+ - MCP server process exits immediately
153
+ - Network unreachable for TCP transport
154
+ - Protocol version mismatch
155
+
156
+ Debug with:
157
+
158
+ ```bash
159
+ LARKY_LOG_LEVEL=DEBUG larky core start
160
+ # Watch for "mcp stderr:" lines in the log
161
+ ```
162
+
163
+ ### LLM API Errors
164
+
165
+ The Anthropic provider retries up to 3 times on transient network errors (ECONNRESET, ECONNREFUSED, ETIMEDOUT, EPIPE, EAI_AGAIN) with 1s/2s/4s backoff. After exhausting retries, the run fails with `llm_error`.
166
+
167
+ Common causes:
168
+
169
+ - Invalid API key → `ANTHROPIC_API_KEY` not set or expired
170
+ - Rate limiting → Wait and retry
171
+ - Network issues → Check connectivity to Anthropic API
172
+
173
+ ---
174
+
175
+ ## Tracing
176
+
177
+ The trace log is written to `~/.larky/traces/daemon.jsonl` in NDJSON format.
178
+
179
+ ### Trace Directions
180
+
181
+ | Direction | Color | Meaning |
182
+ | ------------- | ------- | ------------------------------------------- |
183
+ | `CLIENT→CORE` | cyan | Client sent a command to the daemon |
184
+ | `CORE→CLIENT` | yellow | Daemon sent a response or event to a client |
185
+ | `CORE` | green | Internal daemon operation |
186
+ | `CORE→LLM` | magenta | LLM API request |
187
+ | `LLM→CORE` | blue | LLM API response |
188
+
189
+ ### Trace Layers
190
+
191
+ | Layer | Description |
192
+ | ------- | ------------------------------- |
193
+ | `ipc` | JSON-RPC commands and responses |
194
+ | `event` | EventBus pub/sub events |
195
+ | `llm` | LLM API interactions |
196
+
197
+ ### Trace Kinds
198
+
199
+ | Kind | Layer | Description |
200
+ | -------------- | ----- | ---------------------------- |
201
+ | `command` | ipc | Incoming JSON-RPC request |
202
+ | `response` | ipc | Successful JSON-RPC response |
203
+ | `error` | ipc | JSON-RPC error response |
204
+ | `push` | ipc | Event pushed to subscriber |
205
+ | `event` | event | Internal EventBus event |
206
+ | `api_call` | llm | LLM API request |
207
+ | `api_response` | llm | LLM API response |
208
+
209
+ ### Using `larky trace`
210
+
211
+ ```bash
212
+ larky trace # View all trace records
213
+ larky trace --follow # Tail mode (live updates)
214
+ larky trace --raw # Raw NDJSON output (for piping)
215
+ larky trace --layer llm # Filter by layer (ipc / event / llm)
216
+ larky trace --direction CORE→LLM # Filter by direction
217
+ larky trace run-abc123 # Filter by run ID
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Session and Compaction
223
+
224
+ ### Session Modes
225
+
226
+ - `one_shot`: Single-goal execution. Session closes automatically after the agent completes.
227
+ - `chat`: Multi-turn interactive sessions. Messages persist to `thread.jsonl` across turns.
228
+
229
+ ### Manual Compaction
230
+
231
+ In the TUI, type `/compact` to trigger context compaction. This:
232
+
233
+ 1. Sends the full conversation history to the LLM for summarization
234
+ 2. Replaces the thread with `[summary, acknowledgment]`
235
+ 3. Backs up the original thread to `thread_<timestamp>.jsonl.bak`
236
+ 4. Writes a summary file to `summary_<timestamp>.md`
237
+
238
+ ### Auto-Compaction
239
+
240
+ Set `LARKY_COMPACT_THRESHOLD` (or `compaction.auto_threshold` in TOML) to a value between 0.0 and 1.0. When the context usage percentage exceeds this threshold after a tool-use step, compaction triggers automatically.
241
+
242
+ - `0.0` (default): Auto-compaction disabled — use manual `/compact`
243
+ - `0.8`: Compact when context reaches 80% of the model's window
244
+
245
+ ### Context Waterline
246
+
247
+ The TUI status bar shows the current context percentage. The color changes based on usage:
248
+
249
+ - `< 70%`: Normal (dim)
250
+ - `70%–85%`: Warning (yellow)
251
+ - `> 85%`: Critical (red) — compaction recommended
252
+
253
+ ---
254
+
255
+ ## Data Directories
256
+
257
+ | Path | Purpose |
258
+ | --------------------------------------- | --------------------------------------------------------------------- |
259
+ | `~/.larky/config.toml` | Global configuration |
260
+ | `~/.larky/policy.toml` | Persistent permission policies |
261
+ | `~/.larky/sessions/` | Session data: `meta.json`, `thread.jsonl`, `notes.md`, `summary_*.md` |
262
+ | `~/.larky/sessions/{sid}/runs/{runId}/` | Per-run event logs (`events.jsonl`) |
263
+ | `~/.larky/traces/daemon.jsonl` | Trace log (NDJSON) |
264
+ | `~/.larky/logs/core.log` | Application log (Pino) |
265
+ | `~/.larky/context.md` | Global context injected into agent system prompts |
266
+ | `~/.larky/larky-core.pid` | Daemon PID file |
267
+ | `.larky/config.toml` | Project-local configuration |
268
+ | `.larky/context.md` | Project-local context |
269
+
270
+ ---
271
+
272
+ ## Development
273
+
274
+ ```bash
275
+ pnpm typecheck # tsc --noEmit
276
+ pnpm lint # eslint --fix
277
+ pnpm test # vitest run
278
+ pnpm format # oxfmt --write
279
+ pnpm qa # All of the above combined
280
+ pnpm doc # Regenerate WIRE_PROTOCOL.md
281
+ ```