heyio 0.1.18 → 0.1.19

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 CHANGED
@@ -4,7 +4,7 @@ A personal AI assistant daemon built on the GitHub Copilot SDK. IO runs 24/7 on
4
4
 
5
5
  [![CI](https://github.com/michaeljolley/io/actions/workflows/ci.yml/badge.svg)](https://github.com/michaeljolley/io/actions/workflows/ci.yml)
6
6
  ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
7
- ![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)
7
+ ![Node.js](https://img.shields.io/badge/node-%3E%3D22-brightgreen)
8
8
 
9
9
  ## ✨ Features
10
10
 
@@ -15,13 +15,15 @@ A personal AI assistant daemon built on the GitHub Copilot SDK. IO runs 24/7 on
15
15
  - **Skills** — modular skill system; install from git repos or the [skills.sh](https://skills.sh) registry
16
16
  - **Adaptive Sessions** — infinite sessions with automatic context compaction
17
17
  - **Worker Agents** — delegated task execution through specialized agent sessions
18
+ - **GitHub Integration** — create, list, view, and comment on issues and PRs via the `github` tool
19
+ - **Smart Model Routing** — automatically selects the best model for each task based on complexity
18
20
  - **Self-Updating** — checks for updates and can apply them automatically
19
21
 
20
22
  ## 📋 Prerequisites
21
23
 
22
- - **Node.js** >= 18
24
+ - **Node.js** >= 22
23
25
  - **GitHub Copilot subscription** — IO uses the Copilot SDK, which requires an active Copilot license
24
- - **GitHub CLI** (`gh`) — authenticated via `gh auth login`
26
+ - **GitHub CLI** (`gh`) — required for the `github` tool (issue/PR management). Install from [cli.github.com](https://cli.github.com/) and authenticate with `gh auth login`
25
27
 
26
28
  ## 🚀 Quick Start
27
29
 
@@ -54,6 +56,33 @@ io --daemon
54
56
  io --self-edit
55
57
  ```
56
58
 
59
+ ### Headless Server (systemd)
60
+
61
+ To run IO as a background service on a headless server:
62
+
63
+ 1. Authenticate the Copilot SDK: `copilot login`
64
+ 2. Authenticate the GitHub CLI: `gh auth login`
65
+ 3. Create a systemd service file at `/etc/systemd/system/io.service`:
66
+
67
+ ```ini
68
+ [Unit]
69
+ Description=IO Personal Assistant
70
+ After=network-online.target
71
+ Wants=network-online.target
72
+
73
+ [Service]
74
+ Type=simple
75
+ ExecStart=/usr/bin/env io --daemon
76
+ Restart=always
77
+ RestartSec=10
78
+ Environment=NODE_ENV=production
79
+
80
+ [Install]
81
+ WantedBy=multi-user.target
82
+ ```
83
+
84
+ 4. Enable and start: `systemctl enable --now io`
85
+
57
86
  ## 💬 CLI Usage
58
87
 
59
88
  | Command | Description |
@@ -80,7 +109,17 @@ IO stores its configuration at `~/.io/config.json`. The setup wizard (`io setup`
80
109
  "telegramUserId": 123456789,
81
110
 
82
111
  // Enable self-edit mode by default
83
- "selfEdit": false
112
+ "selfEdit": false,
113
+
114
+ // Default model for the orchestrator
115
+ "defaultModel": "claude-sonnet-4.6",
116
+
117
+ // Model tiers for squad agents (ranked preference lists)
118
+ "modelTiers": {
119
+ "high": ["claude-opus-4.7", "claude-opus-4.6"],
120
+ "medium": ["claude-sonnet-4.6", "gpt-5.5", "claude-opus-4.5"],
121
+ "low": ["claude-haiku-4.5", "gpt-5.4-mini"]
122
+ }
84
123
  }
85
124
  ```
86
125
 
@@ -160,6 +199,7 @@ src/
160
199
  │ ├── orchestrator.ts # Main session management
161
200
  │ ├── agents.ts # Worker agent sessions
162
201
  │ ├── tools.ts # Tool definitions
202
+ │ ├── model-router.ts # Complexity-based model selection
163
203
  │ ├── skills.ts # Skills loader
164
204
  │ └── system-message.ts # System prompt builder
165
205
  ├── store/
@@ -2,6 +2,7 @@ import { randomUUID } from "crypto";
2
2
  import { execSync } from "child_process";
3
3
  import { readFileSync, writeFileSync, readdirSync, statSync, existsSync, mkdirSync, } from "fs";
4
4
  import { join, dirname, resolve } from "path";
5
+ import { homedir } from "os";
5
6
  import { defineTool, approveAll } from "@github/copilot-sdk";
6
7
  import { z } from "zod";
7
8
  import { getClient } from "./client.js";
@@ -154,6 +155,7 @@ function buildAgentTools(squadSlug) {
154
155
  timeout: (timeout_secs ?? 60) * 1000,
155
156
  maxBuffer: 1024 * 1024,
156
157
  cwd: working_dir,
158
+ env: { ...process.env, HOME: process.env.HOME || homedir() },
157
159
  });
158
160
  const output = result.trim();
159
161
  if (output.length > 8000) {
@@ -3,6 +3,14 @@ import { z } from "zod";
3
3
  import { execSync } from "child_process";
4
4
  import { readFileSync, writeFileSync, readdirSync, statSync, existsSync, mkdirSync } from "fs";
5
5
  import { join, dirname, resolve } from "path";
6
+ import { homedir } from "os";
7
+ // Ensure child processes have HOME set (systemd services often don't)
8
+ function shellEnv() {
9
+ const env = { ...process.env };
10
+ if (!env.HOME)
11
+ env.HOME = homedir();
12
+ return env;
13
+ }
6
14
  export function createTools(deps) {
7
15
  const wikiRead = defineTool("wiki_read", {
8
16
  description: "Read a page from IO's knowledge base wiki. Path is relative to the wiki root (e.g., 'pages/preferences/editor.md').",
@@ -129,6 +137,7 @@ export function createTools(deps) {
129
137
  timeout: (timeout_secs ?? 60) * 1000,
130
138
  maxBuffer: 1024 * 1024,
131
139
  cwd: working_dir,
140
+ env: shellEnv(),
132
141
  });
133
142
  const output = result.trim();
134
143
  if (output.length > 8000) {
@@ -219,6 +228,7 @@ export function createTools(deps) {
219
228
  encoding: "utf-8",
220
229
  timeout: 60_000,
221
230
  maxBuffer: 1024 * 1024,
231
+ env: shellEnv(),
222
232
  });
223
233
  const output = result.trim();
224
234
  if (output.length > 8000) {
@@ -331,6 +341,7 @@ export function createTools(deps) {
331
341
  encoding: "utf-8",
332
342
  timeout: 30_000,
333
343
  maxBuffer: 1024 * 1024,
344
+ env: shellEnv(),
334
345
  });
335
346
  const output = result.trim();
336
347
  if (output.length > 8000) {
@@ -521,6 +532,7 @@ export function createTools(deps) {
521
532
  encoding: "utf-8",
522
533
  timeout: 30_000,
523
534
  maxBuffer: 1024 * 1024,
535
+ env: shellEnv(),
524
536
  }).trim();
525
537
  if (result.length > 8000) {
526
538
  return result.slice(0, 8000) + "\n\n[…truncated]";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyio",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "IO — a personal AI assistant built on the GitHub Copilot SDK",
5
5
  "bin": {
6
6
  "io": "dist/index.js"