@aitne-sh/aitne 0.1.1 → 0.1.2
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 +1010 -277
- package/package.json +39 -22
- package/scripts/check-redaction-coverage.mjs +0 -0
- package/scripts/message-discipline-digest.mjs +0 -0
- package/scripts/remint-roadmap-ids.mjs +0 -0
package/README.md
CHANGED
|
@@ -1,357 +1,964 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# Aitne
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Always on. Always yours.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**A local-first, proactive personal AI agent that runs continuously on your own machine — and gets smarter about *you* every day.**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Architecture
|
|
9
|
+
[](https://www.npmjs.com/package/@aitne-sh/aitne)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
[](https://nodejs.org)
|
|
12
|
+
[](#platform-support)
|
|
13
|
+
[](#multi-backend)
|
|
16
14
|
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @aitne-sh/aitne@latest
|
|
17
|
+
aitne start
|
|
17
18
|
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The concept
|
|
25
|
+
|
|
26
|
+
ChatGPT and Claude are *reactive* — they wait for you to type. **Aitne is proactive.** It's a tiny daemon that lives on your laptop, watches your calendar, mail, repos and notes, and acts on its own — drafting your morning plan at 04:00, surfacing the email you forgot, nudging you about the PR your teammate is waiting on, and weaving everything into a Markdown journal you actually own.
|
|
27
|
+
|
|
28
|
+
```mermaid
|
|
29
|
+
flowchart LR
|
|
30
|
+
subgraph WORLD["Your digital life"]
|
|
31
|
+
direction TB
|
|
32
|
+
W1["💬 Messages"]
|
|
33
|
+
W2["📅 Calendar"]
|
|
34
|
+
W3["📧 Mail"]
|
|
35
|
+
W4["📦 Git"]
|
|
36
|
+
W5["📓 Notes"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph LOCAL["💻 Your laptop — Aitne"]
|
|
40
|
+
direction TB
|
|
41
|
+
DAEMON["⚙️ Daemon<br/>(always-on)"]
|
|
42
|
+
BRAIN["🧠 Your AI<br/>(Claude · Codex · Gemini)"]
|
|
43
|
+
MEMORY["📝 Markdown memory<br/>(plain files you own)"]
|
|
44
|
+
DAEMON <--> BRAIN
|
|
45
|
+
BRAIN <--> MEMORY
|
|
46
|
+
DAEMON <--> MEMORY
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
YOU["📱 You<br/>Slack · Telegram · Discord<br/>WhatsApp · Web chat"]
|
|
50
|
+
|
|
51
|
+
WORLD <--> DAEMON
|
|
52
|
+
DAEMON <--> YOU
|
|
34
53
|
```
|
|
35
54
|
|
|
36
|
-
|
|
55
|
+
Three things make Aitne different:
|
|
56
|
+
|
|
57
|
+
| | |
|
|
58
|
+
|---|---|
|
|
59
|
+
| 🌱 **It compounds.** | Every day, every DM, every reaction emoji shapes the agent's understanding of *you*. After a month it sounds like you. After a year it knows what you forgot last quarter. |
|
|
60
|
+
| 🗣️ **You manage it in plain language.** | "Don't ping me before 9am." "Remember my partner's birthday." "Stop running hourly checks on weekends." Aitne maps your words to settings, schedules, and profile updates — automatically. |
|
|
61
|
+
| 🔌 **It rides on what you already have.** | Your Claude Code skills, your Codex config, your Gemini settings, your custom MCP servers — Aitne loads them into every session. No re-configuring. No re-buying. |
|
|
37
62
|
|
|
38
63
|
---
|
|
39
64
|
|
|
40
|
-
##
|
|
65
|
+
## A day with Aitne (live demo)
|
|
41
66
|
|
|
42
|
-
|
|
67
|
+
> A real walkthrough of one user's Tuesday.
|
|
43
68
|
|
|
44
|
-
|
|
69
|
+
**04:00 — While you sleep.** Aitne reads yesterday's handoff, your calendar for today, the last 24 hours of mail across 4 accounts, new commits in 3 repos, and the 7 pending observations from Notion. It generates `today.md` and queues a Morning Briefing DM for after quiet hours end.
|
|
45
70
|
|
|
46
|
-
|
|
71
|
+
**07:30 — Slack DM lands as you grab coffee:**
|
|
72
|
+
> Good morning. 3 things to flag:
|
|
73
|
+
> • **Sarah's PR (#487)** needs your review — she's been blocked since Friday
|
|
74
|
+
> • **Sales call with Acme @ 14:00** — leaving home by 13:25 (12-min commute)
|
|
75
|
+
> • **IRS reminder from Friday** — deadline is *tomorrow*
|
|
76
|
+
>
|
|
77
|
+
> Today: 2 meetings, 4 tasks. Light day. Reply `end` to close, or just talk to me.
|
|
47
78
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
**09:15 — You DM Aitne:** *"Tell Sarah I'll review by 11. And book lunch with Mark on Thursday — somewhere near his office."*
|
|
80
|
+
Aitne drafts the Slack reply to Sarah, finds 3 lunch slots Thursday, checks Mark's last 5 lunch venues from your Notion `people.md`, suggests Tartine. You confirm. Done.
|
|
81
|
+
|
|
82
|
+
**11:30 — Hourly check fires.** A new commit in your repo modified the API contract you're about to ship. Aitne adds a note to `Agent Notes` on `today.md` and DMs once: *"⚠️ Heads up — `auth.ts:84` was just changed by @Yuki. Want me to summarize the diff?"*
|
|
83
|
+
|
|
84
|
+
**13:45 — Calendar approach.** *"Sales call in 15 min. Acme is the warm lead from last Tuesday — they mentioned wanting webhook integration. Brief is in `projects/acme.md`."*
|
|
85
|
+
|
|
86
|
+
**15:45 — You forward a hotel confirmation email to Aitne.** It extracts dates, address, confirmation number into `travel_bookings`, saves the PDF to `~/.personal-agent/context/receipts/2026/05/`, and adds the trip to next week's morning briefing.
|
|
87
|
+
|
|
88
|
+
**18:00 — Evening review.** Aitne notices you didn't reply to two emails from this morning. They get carried to tomorrow's `today.md`. It also sees you wrote *"shorter please"* twice today, classifies that as a tone-class signal, and silently shortens its replies going forward.
|
|
89
|
+
|
|
90
|
+
**Friday 18:30 — Weekly review.**
|
|
91
|
+
> Week of 2026-05-04: shipped 3 PRs, 2 deferred. Open loops: hotel cancellation, Acme follow-up. Focus next week: launch prep. Heads up: you've worked past 22:00 every day this week — should I clear Friday afternoon?
|
|
92
|
+
|
|
93
|
+
That's a normal Tuesday. The point isn't any single trick — it's that **all of this happens without you opening an app.**
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## What you can do with it
|
|
98
|
+
|
|
99
|
+
A non-exhaustive list. Click any group to expand.
|
|
100
|
+
|
|
101
|
+
<details>
|
|
102
|
+
<summary><b>📅 Time, calendar, travel</b></summary>
|
|
103
|
+
|
|
104
|
+
- Auto-generate `today.md` every morning with your real schedule
|
|
105
|
+
- 15-min approach reminders for every calendar event, with travel time pre-computed via Google Maps
|
|
106
|
+
- "Find me a 30-min slot with Sarah and Mark next week" — Aitne checks freebusy across calendars
|
|
107
|
+
- Auto-extract flight, hotel, restaurant, train confirmations from email into a structured travel timeline
|
|
108
|
+
- Surface tomorrow's itinerary in the morning briefing
|
|
109
|
+
- "What time should I leave for my next meeting?" — answers with live traffic
|
|
110
|
+
</details>
|
|
111
|
+
|
|
112
|
+
<details>
|
|
113
|
+
<summary><b>📧 Mail across all your accounts</b></summary>
|
|
114
|
+
|
|
115
|
+
- Unified inbox across Gmail, Outlook, Yahoo, iCloud, and any IMAP server
|
|
116
|
+
- Local FTS5 full-text search across **every** account ("find emails about acme last quarter")
|
|
117
|
+
- Auto-classify, label, and archive (Gmail)
|
|
118
|
+
- Draft replies in your style ("draft a polite no to this conference invite")
|
|
119
|
+
- Forwarded receipts → auto-extracted to a structured `receipts` table tagged with category, vendor, amount
|
|
120
|
+
- Daily digest of unread mail in the morning briefing
|
|
121
|
+
</details>
|
|
122
|
+
|
|
123
|
+
<details>
|
|
124
|
+
<summary><b>📓 Knowledge: Obsidian, Notion, your own notes</b></summary>
|
|
125
|
+
|
|
126
|
+
- Use your existing Obsidian vault as Aitne's primary memory store — wiki-links keep working
|
|
127
|
+
- Append to your daily note via the official Obsidian CLI
|
|
128
|
+
- Full Notion page & database CRUD — query, create, update, archive
|
|
129
|
+
- "Summarize what I wrote about this project last month" — across vault layers
|
|
130
|
+
- Auto-link new notes to existing concepts ("this is related to your `agent-architecture.md` from March")
|
|
131
|
+
</details>
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary><b>📦 Code, Git, GitHub</b></summary>
|
|
135
|
+
|
|
136
|
+
- Local Git: `git log`, `git diff`, `git show` exposed via daemon proxy
|
|
137
|
+
- GitHub: PR lists, comments, issues, webhook receivers
|
|
138
|
+
- Per-repo cron triggers — "every Monday at 09:00, summarize merged PRs into `projects/<repo>.md`"
|
|
139
|
+
- "Why did this build break?" — agent reads CI status + diff + traces
|
|
140
|
+
- Auto-detect when a coworker modified a file you're about to ship
|
|
141
|
+
</details>
|
|
142
|
+
|
|
143
|
+
<details>
|
|
144
|
+
<summary><b>✅ Tasks, projects, life admin</b></summary>
|
|
145
|
+
|
|
146
|
+
- Unified task view across GitHub Issues, mail-derived TODOs, and your own `today.md`
|
|
147
|
+
- Per-project Markdown files with auto-maintained status, deadlines, and people
|
|
148
|
+
- Long-term roadmap with quarterly milestones
|
|
149
|
+
- "Carry this to tomorrow" — handoff between today.md, daily/, weekly/, monthly/
|
|
150
|
+
- Auto-detect recurring chores and set up reminders
|
|
151
|
+
</details>
|
|
152
|
+
|
|
153
|
+
<details>
|
|
154
|
+
<summary><b>📚 Reading, learning, lifestyle</b></summary>
|
|
155
|
+
|
|
156
|
+
- Import Kindle highlights, build a reading-taste profile
|
|
157
|
+
- Friday book recommendation DM based on your taste
|
|
158
|
+
- Receipts auto-organized by month into your Obsidian vault
|
|
159
|
+
- Travel itinerary roll-up surfaced before each trip
|
|
160
|
+
</details>
|
|
161
|
+
|
|
162
|
+
<details>
|
|
163
|
+
<summary><b>🤖 Self-management & automation</b></summary>
|
|
164
|
+
|
|
165
|
+
- Tell it to remember things in plain language ("I'm allergic to nuts")
|
|
166
|
+
- Tell it to forget things ("delete that note about my old job")
|
|
167
|
+
- Tell it to change schedules ("don't run hourly checks on weekends")
|
|
168
|
+
- Tell it to change tone ("be more concise, no preamble")
|
|
169
|
+
- Custom routines on any cron schedule with free-form prompts
|
|
170
|
+
- Self-scheduled wakeups — agent decides when to check on something
|
|
171
|
+
</details>
|
|
172
|
+
|
|
173
|
+
<details>
|
|
174
|
+
<summary><b>🔧 Run your own tools</b></summary>
|
|
175
|
+
|
|
176
|
+
- Bring your own MCP servers — they materialize into every session
|
|
177
|
+
- Bring your own Claude Code skills — they show up wherever the agent runs
|
|
178
|
+
- Bring your own Codex / Gemini config — Aitne reads it on session init
|
|
179
|
+
- Custom skills via the `/api/skills` endpoint — drop a `SKILL.md` and it's live
|
|
180
|
+
</details>
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## How Aitne accumulates knowledge about you
|
|
185
|
+
|
|
186
|
+
Every signal Aitne sees flows through the same pipeline: capture → short-term → long-term → injected back into every future conversation.
|
|
187
|
+
|
|
188
|
+
```mermaid
|
|
189
|
+
flowchart TB
|
|
190
|
+
subgraph SOURCES["📥 Sources"]
|
|
191
|
+
direction LR
|
|
192
|
+
S1["💬 messages"]
|
|
193
|
+
S2["📅 calendar"]
|
|
194
|
+
S3["📧 mail"]
|
|
195
|
+
S4["📦 git/github"]
|
|
196
|
+
S5["📓 obsidian/notion"]
|
|
197
|
+
S6["✋ you editing<br/>files by hand"]
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
OB["⚙️ Observers & adapters<br/>(WebSocket · IDLE · polling)"]
|
|
201
|
+
|
|
202
|
+
subgraph SHORT["🟡 Short-term memory"]
|
|
203
|
+
direction LR
|
|
204
|
+
ST1[("SQLite<br/>observations<br/>messages<br/>actions")]
|
|
205
|
+
ST2["today.md<br/>(working view,<br/>always injected)"]
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
subgraph LONG["🟢 Long-term memory (Markdown)"]
|
|
209
|
+
direction TB
|
|
210
|
+
LT1["user/profile.md<br/>work · expertise<br/>people · goals"]
|
|
211
|
+
LT2["projects/*.md<br/>roadmap.md"]
|
|
212
|
+
LT3["daily/YYYY-MM-DD.md<br/>↓<br/>weekly/YYYY-Www.md<br/>↓<br/>monthly/YYYY-MM.md"]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
AI(("🧠 Next session<br/>(any backend,<br/>any platform)"))
|
|
216
|
+
|
|
217
|
+
SOURCES --> OB
|
|
218
|
+
OB --> ST1
|
|
219
|
+
ST1 -- "hourly check<br/>aggregates" --> ST2
|
|
220
|
+
ST2 -- "evening review<br/>condenses" --> LT3
|
|
221
|
+
ST2 -- "patterns identified" --> LT1
|
|
222
|
+
ST2 -- "project-tagged<br/>updates" --> LT2
|
|
223
|
+
LT3 -- "Friday roll-up" --> LT3
|
|
224
|
+
LT3 -- "month-end roll-up" --> LT3
|
|
225
|
+
|
|
226
|
+
LT1 -. "always injected" .-> AI
|
|
227
|
+
ST2 -. "always injected" .-> AI
|
|
228
|
+
LT2 -. "morning + evening" .-> AI
|
|
229
|
+
LT3 -. "recalled when relevant" .-> AI
|
|
63
230
|
```
|
|
64
231
|
|
|
65
|
-
|
|
232
|
+
**Key properties:**
|
|
66
233
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
nvm install 22
|
|
72
|
-
nvm use 22
|
|
73
|
-
node --version
|
|
234
|
+
- **Plain Markdown.** You can `cat`, `vim`, `obsidian`, or `cp` any of these files. There is no proprietary format. Uninstall and the memory is still yours.
|
|
235
|
+
- **Layered retention.** `today.md` rotates to `yesterday.md` once per agent-day. `daily/` files are persistent by design (synthesized journal). `weekly/` is pruned after 1 year (the monthly review rolls it up). `agent/journal.md` keeps the most recent ~12 weekly + 24 monthly sections. SQLite-backed history (messages, agent_actions, dm_conversation_log) is pruned after 90 days.
|
|
236
|
+
- **Always-injected context.** Every session starts with `user/profile.md` + `rules/management.md` + `today.md` already loaded — the agent never has to "search for context."
|
|
237
|
+
- **You can always intervene.** Edit any file by hand. The agent picks up your changes on the next routine.
|
|
74
238
|
|
|
75
|
-
|
|
76
|
-
npm install -g pnpm
|
|
239
|
+
---
|
|
77
240
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
241
|
+
## Compounding intelligence
|
|
242
|
+
|
|
243
|
+
The longer you use it, the better it gets. Not because the model improves — because *the context does*.
|
|
244
|
+
|
|
245
|
+
```mermaid
|
|
246
|
+
graph LR
|
|
247
|
+
D1["📆 <b>Day 1</b><br/>Empty profile<br/>Generic answers<br/>Asks who's Sarah"]
|
|
248
|
+
W1["📅 <b>Week 1</b><br/>Calendar synced<br/>People dictionary<br/>Mail patterns ID'd"]
|
|
249
|
+
M1["🌙 <b>Month 1</b><br/>Profile auto-filled<br/>Tone matches you<br/>Recurring tasks tracked"]
|
|
250
|
+
M3["📈 <b>Month 3</b><br/>Full project map<br/>Knows your peers<br/>Proactive nudges"]
|
|
251
|
+
Y1["🎯 <b>Year 1</b><br/>Anticipates needs<br/>Recalls Q1 context<br/>You can't go back"]
|
|
252
|
+
|
|
253
|
+
D1 -->|implicit feedback| W1
|
|
254
|
+
W1 -->|evening review| M1
|
|
255
|
+
M1 -->|project tracking| M3
|
|
256
|
+
M3 -->|long-term memory| Y1
|
|
81
257
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
258
|
+
style D1 fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
|
|
259
|
+
style W1 fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
|
|
260
|
+
style M1 fill:#dbeafe,stroke:#3b82f6,stroke-width:2px
|
|
261
|
+
style M3 fill:#dcfce7,stroke:#22c55e,stroke-width:2px
|
|
262
|
+
style Y1 fill:#dcfce7,stroke:#22c55e,stroke-width:3px
|
|
86
263
|
```
|
|
87
264
|
|
|
88
|
-
|
|
265
|
+
### The implicit feedback loop
|
|
89
266
|
|
|
90
|
-
|
|
267
|
+
Every interaction shapes Aitne's understanding of you, *implicitly*. No buttons. No surveys. Just talk to it.
|
|
91
268
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
node --version # v22.x.x
|
|
99
|
-
|
|
100
|
-
# 2. pnpm
|
|
101
|
-
npm install -g pnpm
|
|
102
|
-
pnpm --version # 10.x.x
|
|
103
|
-
|
|
104
|
-
# 3. Claude Code CLI
|
|
105
|
-
npm install -g @anthropic-ai/claude-code
|
|
106
|
-
claude --version
|
|
269
|
+
```mermaid
|
|
270
|
+
flowchart LR
|
|
271
|
+
A["📨 Pre-Action<br/>read user/profile.md<br/>inject preferences"] --> B["🤖 Action<br/>generate response<br/>in your style"]
|
|
272
|
+
B --> C["👁️ Post-Action<br/>Signal Detector logs:<br/>· ignored notifications<br/>(no reply within 30 min)<br/>· correction phrases<br/>(shorter, in Japanese, …)"]
|
|
273
|
+
C --> D["🌆 Evening Review<br/>raw signals → character<br/>or → user/profile.md<br/>Learned Context"]
|
|
274
|
+
D --> A
|
|
107
275
|
```
|
|
108
276
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
277
|
+
The Signal Detector (`packages/daemon/src/core/signal-detector.ts`) appends raw entries to `user/profile.md`'s `## Raw Signals` section via the Context File API. The Evening Review (`routine.evening_review`, default `medium` tier — Sonnet) interprets the raw signals on the next pass and clears them.
|
|
278
|
+
|
|
279
|
+
**Tone-class signals** (corrections like "be shorter", "no preamble") → updates the `character` runtime-config field, applied to the system prompt across all backends.
|
|
280
|
+
**Attribute-class signals** (durable facts like "I'm allergic to nuts", "my partner's name is Mei") → updates `user/profile.md` Learned Context.
|
|
113
281
|
|
|
114
|
-
|
|
282
|
+
The Evening Review enforces the line between these: a signal like "I prefer concise replies" is *tone* (goes to character). A signal like "my flight is on Friday" is *attribute* (goes to profile).
|
|
115
283
|
|
|
116
284
|
---
|
|
117
285
|
|
|
118
|
-
|
|
286
|
+
## Talk to it like a person
|
|
119
287
|
|
|
120
|
-
|
|
121
|
-
git clone https://github.com/your-org/aitne.git aitne
|
|
122
|
-
cd aitne
|
|
123
|
-
pnpm install
|
|
124
|
-
```
|
|
288
|
+
Aitne has a dedicated set of management skills — `management-task-register`, `management-task-modify`, `management-task-stop`, `management-policy`, `user-profile`, `user-interview`. **You don't poke through 80 settings panels — you tell it.**
|
|
125
289
|
|
|
126
|
-
|
|
290
|
+
| You say (in any language) | Aitne does |
|
|
291
|
+
|---|---|
|
|
292
|
+
| *"Don't run the hourly check on weekends"* | Patches `hourlyCheckActiveStartHour/EndHour` per weekday |
|
|
293
|
+
| *"Stop pinging me about Slack after 9pm"* | Updates `quietHoursStart/End` and per-platform notify policy |
|
|
294
|
+
| *"Always check Sarah's calendar before scheduling with her"* | Adds a rule to `rules/management.md` |
|
|
295
|
+
| *"Remember my partner's birthday is March 14"* | Appends to `user/profile.md` Learned Context |
|
|
296
|
+
| *"I prefer concise replies — no preamble"* | Updates `character` field |
|
|
297
|
+
| *"Move all my React work into one project file"* | Refactors `projects/*.md` and re-indexes |
|
|
298
|
+
| *"Cancel tomorrow's morning briefing"* | Removes the agent_schedule row |
|
|
299
|
+
| *"Forget what I said about my old job"* | Surgically edits `user/work.md` |
|
|
300
|
+
| *"Email me a summary every Friday at 5pm"* | Creates a recurring schedule with a free-form prompt |
|
|
301
|
+
| *"Switch to Codex for code reviews from now on"* | Updates `process_backend_config` mapping |
|
|
302
|
+
|
|
303
|
+
Behind the scenes, the agent maps natural language to one of:
|
|
304
|
+
- `PATCH /api/config` — runtime config (~80 keys)
|
|
305
|
+
- `PUT /api/context/*` — Markdown memory (locked, validated, snapshotted)
|
|
306
|
+
- `DELETE /api/schedule/:id` / `POST /api/recurring-schedules` — scheduling
|
|
307
|
+
- `PATCH /api/config/character` — tone
|
|
308
|
+
- `POST /api/triggers` — cron-driven custom routines (automation triggers)
|
|
309
|
+
|
|
310
|
+
Every change is journaled to `agent_actions` with `source_kind=user_directive`. You can audit what was changed and when via `aitne audit`.
|
|
127
311
|
|
|
128
312
|
---
|
|
129
313
|
|
|
130
|
-
|
|
314
|
+
## Bring your own harness (BYOH)
|
|
131
315
|
|
|
132
|
-
|
|
133
|
-
# macOS / Linux
|
|
134
|
-
cp .env.example .env
|
|
316
|
+
Already invested in Claude Code skills? Custom MCP servers? A polished `~/.codex/config.toml`? **Aitne loads them all.** No re-configuring. No re-buying. No vendor lock.
|
|
135
317
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
318
|
+
```mermaid
|
|
319
|
+
flowchart LR
|
|
320
|
+
subgraph YOUR["🔵 Your existing setup"]
|
|
321
|
+
direction TB
|
|
322
|
+
Y1["~/.claude/<br/>· skills<br/>· slash commands<br/>· MCP servers"]
|
|
323
|
+
Y2["~/.codex/<br/>· config<br/>· plugins"]
|
|
324
|
+
Y3["~/.gemini/<br/>· config<br/>· tools"]
|
|
325
|
+
Y4["Custom MCP servers<br/>(your data sources,<br/>internal tools)"]
|
|
326
|
+
end
|
|
139
327
|
|
|
140
|
-
|
|
328
|
+
subgraph AITNE_SKILLS["🟡 Aitne's built-ins"]
|
|
329
|
+
direction TB
|
|
330
|
+
A1["23 skills<br/>(Calendar, Mail, Notion,<br/>Roadmap, Schedule, ...)"]
|
|
331
|
+
A2["Per-event task flows<br/>(morning, hourly,<br/>DM, mention, ...)"]
|
|
332
|
+
A3["Persona MD<br/>(per-backend)"]
|
|
333
|
+
end
|
|
141
334
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
335
|
+
SESS["📦 Per-session workdir<br/>~/.personal-agent/agent-sessions/<id>/<br/>CLAUDE.md · AGENTS.md · GEMINI.md<br/>+ .claude/skills/ · .codex/skills/<br/>+ MCP config materialized"]
|
|
336
|
+
|
|
337
|
+
RUN["🚀 Backend runs with<br/><b>your full toolkit + Aitne's</b>"]
|
|
338
|
+
|
|
339
|
+
YOUR --> SESS
|
|
340
|
+
AITNE_SKILLS --> SESS
|
|
341
|
+
SESS --> RUN
|
|
342
|
+
|
|
343
|
+
style YOUR fill:#dbeafe,stroke:#3b82f6
|
|
344
|
+
style AITNE_SKILLS fill:#fef3c7,stroke:#f59e0b
|
|
345
|
+
style SESS fill:#dcfce7,stroke:#22c55e
|
|
346
|
+
style RUN fill:#fae8ff,stroke:#a855f7
|
|
146
347
|
```
|
|
147
348
|
|
|
148
|
-
|
|
349
|
+
### What this means in practice
|
|
350
|
+
|
|
351
|
+
| You already have… | In Aitne it just works |
|
|
352
|
+
|---|---|
|
|
353
|
+
| A Claude Code MCP server connected to your company's internal API | Every Aitne session can use it. No code changes. |
|
|
354
|
+
| Custom slash commands you built for `/review` or `/test` | They're available in every Aitne-spawned Claude Code session. |
|
|
355
|
+
| A polished `AGENTS.md` for your Codex setup | Aitne layers its persona on top, keeping your config intact. |
|
|
356
|
+
| Your Gemini auth + project preferences | Inherited automatically. |
|
|
357
|
+
| Skills you wrote for `~/.claude/skills/` | Imported on demand. |
|
|
149
358
|
|
|
359
|
+
### The growth flywheel
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
Claude Code / Codex / Gemini ships a new feature
|
|
363
|
+
↓
|
|
364
|
+
New connectors, plugins, MCP servers, skills appear
|
|
365
|
+
↓
|
|
366
|
+
The backend Aitne controls gets more capable
|
|
367
|
+
↓
|
|
368
|
+
You get those capabilities in Aitne — with zero config change
|
|
150
369
|
```
|
|
151
|
-
|
|
370
|
+
|
|
371
|
+
Aitne is a *proxy* over the AI runtimes you already use. As they grow, you grow.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Multi-platform, multi-app
|
|
376
|
+
|
|
377
|
+
One agent, every surface.
|
|
378
|
+
|
|
379
|
+
```mermaid
|
|
380
|
+
flowchart TB
|
|
381
|
+
subgraph IN["📥 Input surfaces"]
|
|
382
|
+
direction LR
|
|
383
|
+
I1["💬 Slack DM/mention"]
|
|
384
|
+
I2["📲 Telegram"]
|
|
385
|
+
I3["🎮 Discord"]
|
|
386
|
+
I4["💚 WhatsApp"]
|
|
387
|
+
I5["🌐 Web dashboard chat"]
|
|
388
|
+
I6["✋ Manual file edits"]
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
subgraph SVC["🔌 Connected apps"]
|
|
392
|
+
direction TB
|
|
393
|
+
SV1["📅 Google Calendar"]
|
|
394
|
+
SV2["📧 Gmail · Outlook · Yahoo · iCloud · IMAP"]
|
|
395
|
+
SV3["📓 Notion · Obsidian"]
|
|
396
|
+
SV4["📦 GitHub · local Git"]
|
|
397
|
+
SV5["🗺️ Google Maps"]
|
|
398
|
+
SV6["🔧 Custom MCP servers"]
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
AITNE(("🧠 Aitne"))
|
|
402
|
+
|
|
403
|
+
IN --> AITNE
|
|
404
|
+
AITNE <--> SVC
|
|
405
|
+
|
|
406
|
+
subgraph OUT["📤 Output surfaces"]
|
|
407
|
+
direction LR
|
|
408
|
+
O1["💬 Same DM channel"]
|
|
409
|
+
O2["📋 today.md<br/>updates"]
|
|
410
|
+
O3["📅 Calendar<br/>actions"]
|
|
411
|
+
O4["📧 Drafted emails"]
|
|
412
|
+
O5["🔔 Proactive<br/>notifications"]
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
AITNE --> OUT
|
|
152
416
|
```
|
|
153
417
|
|
|
418
|
+
**One conversation, every channel.** A morning brief delivered to Slack, a follow-up via WhatsApp, an email draft from the dashboard — Aitne carries the same context across all of them.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Highlights
|
|
423
|
+
|
|
424
|
+
| | |
|
|
425
|
+
|---|---|
|
|
426
|
+
| 🌅 **Proactive routines** | Morning · evening · weekly · monthly · hourly observation sweep |
|
|
427
|
+
| 💬 **Reactive on every chat platform** | Slack · Telegram · Discord · WhatsApp · Web dashboard |
|
|
428
|
+
| 🧠 **Multi-backend brain** | Claude (Opus 4.7 / Sonnet 4.6 / Haiku 4.5) · Codex CLI · Gemini CLI |
|
|
429
|
+
| 📝 **MD-centric memory** | Plain Markdown you own — `today.md` · `roadmap.md` · `projects/*` · `daily/` · `weekly/` · `monthly/` |
|
|
430
|
+
| 🔌 **23 built-in skills** | Calendar, mail, Notion, Obsidian, schedule, roadmap, receipts, travel, reading, … |
|
|
431
|
+
| 🛡️ **Triple safety model** | SDK permission hooks · daemon API risk tiers · absolute-block layer |
|
|
432
|
+
| 🪪 **Local-first & private** | Binds to `127.0.0.1`. No telemetry. Secrets in OS Keychain. Zero cloud state. |
|
|
433
|
+
| 🧰 **Production tooling** | Background daemon · `aitne doctor` · cost analytics · auth health monitor with auto-recovery |
|
|
434
|
+
| 🌍 **Speak any language** | The LLM handles it — talk to Aitne in Japanese, English, German, anything. |
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Table of contents
|
|
439
|
+
|
|
440
|
+
1. [Quick start](#quick-start)
|
|
441
|
+
2. [Setup guide](#setup-guide)
|
|
442
|
+
3. [CLI reference](#cli-reference)
|
|
443
|
+
4. [Architecture](#architecture)
|
|
444
|
+
5. [Memory layout](#memory-layout)
|
|
445
|
+
6. [Multi-backend](#multi-backend)
|
|
446
|
+
7. [Integrations](#integrations)
|
|
447
|
+
8. [Safety model](#safety-model)
|
|
448
|
+
9. [Cost & quotas](#cost--quotas)
|
|
449
|
+
10. [Configuration](#configuration)
|
|
450
|
+
11. [Platform support](#platform-support)
|
|
451
|
+
12. [Troubleshooting](#troubleshooting)
|
|
452
|
+
13. [Development](#development)
|
|
453
|
+
14. [FAQ](#faq)
|
|
454
|
+
15. [License](#license)
|
|
455
|
+
|
|
154
456
|
---
|
|
155
457
|
|
|
156
|
-
|
|
458
|
+
## Quick start
|
|
459
|
+
|
|
460
|
+
### 1. Install
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
npm install -g @aitne-sh/aitne@latest
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
This installs the `aitne` CLI globally with the daemon, dashboard, and built-in agent assets.
|
|
467
|
+
|
|
468
|
+
### 2. Bring at least one AI backend
|
|
469
|
+
|
|
470
|
+
Aitne is the nervous system; you bring the brain. Install **at least one** of:
|
|
157
471
|
|
|
158
472
|
```bash
|
|
159
|
-
|
|
473
|
+
# Claude Code (recommended — full features, server-side advisor support)
|
|
474
|
+
npm install -g @anthropic-ai/claude-code
|
|
475
|
+
|
|
476
|
+
# OpenAI Codex CLI
|
|
477
|
+
npm install -g @openai/codex
|
|
478
|
+
|
|
479
|
+
# Google Gemini CLI
|
|
480
|
+
npm install -g @google/gemini-cli
|
|
160
481
|
```
|
|
161
482
|
|
|
162
|
-
|
|
483
|
+
Login once with each CLI you intend to use — Aitne auto-detects them.
|
|
163
484
|
|
|
164
|
-
|
|
485
|
+
### 3. Start
|
|
165
486
|
|
|
166
487
|
```bash
|
|
167
|
-
|
|
488
|
+
aitne start
|
|
168
489
|
```
|
|
169
490
|
|
|
170
|
-
|
|
491
|
+
The daemon (`:8321`) and dashboard (`:3000`) launch in the background and your browser opens to the setup wizard.
|
|
492
|
+
|
|
493
|
+
### 4. Confirm
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
aitne status
|
|
497
|
+
```
|
|
171
498
|
|
|
172
499
|
```
|
|
173
|
-
Aitne v0.1.
|
|
500
|
+
Aitne v0.1.1
|
|
174
501
|
Daemon running pid 12345 uptime 0:00:12 port 8321
|
|
175
502
|
Dashboard running pid 12346 uptime 0:00:11 port 3000
|
|
503
|
+
Today's spend $0.04
|
|
504
|
+
Next scheduled routine.morning_routine in 6h 12m
|
|
176
505
|
```
|
|
177
506
|
|
|
178
|
-
|
|
507
|
+
That's it. Open `http://localhost:3000` and finish the wizard.
|
|
179
508
|
|
|
180
509
|
---
|
|
181
510
|
|
|
182
|
-
|
|
511
|
+
## Setup guide
|
|
183
512
|
|
|
184
|
-
|
|
513
|
+
### Prerequisites
|
|
185
514
|
|
|
186
|
-
|
|
515
|
+
| Requirement | Version | Why |
|
|
516
|
+
|---|---|---|
|
|
517
|
+
| **Node.js** | ≥ 22.0.0 | Daemon runtime (LTS) |
|
|
518
|
+
| **At least one AI backend** | — | Claude Code, Codex CLI, or Gemini CLI |
|
|
519
|
+
| **OS Keychain** | macOS / libsecret on Linux / DPAPI on Windows | Secret storage (file-based fallback available) |
|
|
187
520
|
|
|
188
|
-
|
|
189
|
-
# Inside the repo directory:
|
|
190
|
-
npm link
|
|
521
|
+
### Step 1 — Install Aitne
|
|
191
522
|
|
|
192
|
-
|
|
193
|
-
aitne
|
|
523
|
+
```bash
|
|
524
|
+
npm install -g @aitne-sh/aitne@latest
|
|
194
525
|
```
|
|
195
526
|
|
|
196
|
-
|
|
527
|
+
> Want to hack on the source? See [Development](#development).
|
|
197
528
|
|
|
198
|
-
|
|
199
|
-
# Find the directory
|
|
200
|
-
npm config get prefix
|
|
201
|
-
# e.g. /usr/local or /Users/you/.npm-global
|
|
529
|
+
### Step 2 — Install at least one backend CLI
|
|
202
530
|
|
|
203
|
-
|
|
204
|
-
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc
|
|
205
|
-
source ~/.zshrc
|
|
206
|
-
```
|
|
531
|
+
#### Claude Code (recommended)
|
|
207
532
|
|
|
208
|
-
|
|
533
|
+
```bash
|
|
534
|
+
npm install -g @anthropic-ai/claude-code
|
|
535
|
+
claude --version
|
|
536
|
+
claude auth login --claudeai # uses your Claude subscription
|
|
537
|
+
```
|
|
209
538
|
|
|
210
|
-
|
|
211
|
-
# Inside the repo directory:
|
|
212
|
-
npm link
|
|
539
|
+
#### OpenAI Codex CLI
|
|
213
540
|
|
|
214
|
-
|
|
215
|
-
|
|
541
|
+
```bash
|
|
542
|
+
npm install -g @openai/codex
|
|
543
|
+
codex --version
|
|
544
|
+
codex login --device-auth # device-flow OAuth
|
|
216
545
|
```
|
|
217
546
|
|
|
218
|
-
|
|
547
|
+
#### Google Gemini CLI
|
|
219
548
|
|
|
220
|
-
```
|
|
221
|
-
npm
|
|
222
|
-
|
|
549
|
+
```bash
|
|
550
|
+
npm install -g @google/gemini-cli
|
|
551
|
+
gemini --version
|
|
552
|
+
# OAuth handled automatically on first use
|
|
223
553
|
```
|
|
224
554
|
|
|
225
|
-
|
|
555
|
+
You can install all three. Per-process tier routing lets you mix-and-match: Sonnet for hourly checks, Opus for the morning routine, Codex for code-heavy tasks, Gemini for free-tier summarization.
|
|
226
556
|
|
|
227
|
-
|
|
557
|
+
### Step 3 — Launch and run the wizard
|
|
228
558
|
|
|
229
|
-
|
|
559
|
+
```bash
|
|
560
|
+
aitne start
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Aitne builds (if needed), launches both processes, and opens `http://localhost:3000/setup`. The wizard walks through:
|
|
230
564
|
|
|
231
|
-
|
|
565
|
+
1. **Backend** — default backend (Claude / Codex / Gemini)
|
|
566
|
+
2. **Vault mode** — plain (`~/.personal-agent/context/`) or your existing Obsidian vault
|
|
567
|
+
3. **Execution mode** — *Safe* (strict) or *Allow* (relaxed for plugins/MCP). Absolute-block layer holds in both.
|
|
568
|
+
4. **Google** — OAuth for Gmail and Calendar (optional)
|
|
569
|
+
5. **Messaging platforms** — Slack, Telegram, Discord, WhatsApp (optional)
|
|
570
|
+
6. **Integrations** — `direct` / `delegated` / `disabled` per service
|
|
571
|
+
7. **Character** — free-form 1,000-char tone & style description
|
|
232
572
|
|
|
233
|
-
|
|
573
|
+
After the wizard, every option has a settings page in the sidebar.
|
|
234
574
|
|
|
235
|
-
|
|
236
|
-
2. **Vault mode** — choose a plain filesystem context directory or point to your Obsidian vault.
|
|
237
|
-
3. **Execution mode** — Safe (strict permission checks) vs. Allow (enables plugins and MCP servers). Destructive ops are blocked in both modes.
|
|
238
|
-
4. **Google** — connect Gmail and Google Calendar via OAuth if needed.
|
|
239
|
-
5. **Integrations** — Mail, Notion, GitHub, messaging platforms (Slack, Telegram, Discord, WhatsApp).
|
|
575
|
+
### Step 4 — Verify
|
|
240
576
|
|
|
241
|
-
|
|
577
|
+
```bash
|
|
578
|
+
aitne status # PIDs, uptime, integrations, today's spend
|
|
579
|
+
aitne doctor # 8-point install diagnostic
|
|
580
|
+
aitne logs -f # tail the daemon log
|
|
581
|
+
```
|
|
242
582
|
|
|
243
583
|
---
|
|
244
584
|
|
|
245
585
|
## CLI reference
|
|
246
586
|
|
|
247
|
-
All commands work both as `aitne <cmd>` (after `npm link`) and as `pnpm <cmd>` (from inside the repo).
|
|
248
|
-
|
|
249
587
|
### Lifecycle
|
|
250
588
|
|
|
251
|
-
| Command |
|
|
252
|
-
|
|
253
|
-
| `aitne start [--no-open]` | Build if stale,
|
|
254
|
-
| `aitne stop` | Graceful shutdown (SIGTERM → SIGKILL after 10 s) |
|
|
255
|
-
| `aitne restart [--clean-context]` | Stop then start
|
|
256
|
-
| `aitne status` | PIDs, uptime, integrations, today's spend, last action, next scheduled item |
|
|
257
|
-
| `aitne logs [-f] [-n N] [-d]` | Tail daemon log
|
|
258
|
-
| `aitne dev` | Foreground mode
|
|
259
|
-
| `aitne build` |
|
|
589
|
+
| Command | What it does |
|
|
590
|
+
|---|---|
|
|
591
|
+
| `aitne start [--no-open]` | Build if stale, launch daemon + dashboard in background. Opens browser unless `--no-open`. |
|
|
592
|
+
| `aitne stop` | Graceful shutdown (SIGTERM → SIGKILL after 10 s). |
|
|
593
|
+
| `aitne restart [--clean-context]` | Stop then start. `--clean-context` wipes `context/` after a tarball backup. |
|
|
594
|
+
| `aitne status` | PIDs, uptime, integrations, today's spend, last action, next scheduled item. |
|
|
595
|
+
| `aitne logs [-f] [-n N] [-d]` | Tail the daemon log. `-d` = dashboard log. `-f` = follow. `-n N` = last N lines. |
|
|
596
|
+
| `aitne dev` | Foreground mode (full stdio, useful for debugging). |
|
|
597
|
+
| `aitne build` | Force a build (skip the mtime gate). |
|
|
260
598
|
|
|
261
599
|
### Operations
|
|
262
600
|
|
|
263
|
-
| Command |
|
|
264
|
-
|
|
265
|
-
| `aitne setup` |
|
|
266
|
-
| `aitne open` | Open the dashboard in your browser |
|
|
267
|
-
| `aitne doctor` |
|
|
268
|
-
| `aitne audit [
|
|
269
|
-
| `aitne version [--json]` |
|
|
270
|
-
| `aitne update [--check]` | Print the npm command to upgrade
|
|
271
|
-
| `aitne uninstall [--keep-data\|--wipe-data]` | Stop
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
|
279
|
-
|
|
|
280
|
-
|
|
|
601
|
+
| Command | What it does |
|
|
602
|
+
|---|---|
|
|
603
|
+
| `aitne setup` | Re-open the dashboard `/setup` wizard. Auto-starts the daemon if needed. |
|
|
604
|
+
| `aitne open` | Open the dashboard in your browser. |
|
|
605
|
+
| `aitne doctor` | 8-point install diagnostic. |
|
|
606
|
+
| `aitne audit [flags]` | Read the agent action log directly from SQLite. |
|
|
607
|
+
| `aitne version [--json]` | Version, Node, install path, last build time. |
|
|
608
|
+
| `aitne update [--check]` | Print the npm command to upgrade. `--check` makes one network call. |
|
|
609
|
+
| `aitne uninstall [--keep-data\|--wipe-data]` | Stop the daemon and offer to wipe `~/.personal-agent`. |
|
|
610
|
+
| `aitne help [cmd]` | Help (or per-command help). |
|
|
611
|
+
|
|
612
|
+
### `aitne audit` flags
|
|
613
|
+
|
|
614
|
+
| Flag | Default | Description |
|
|
615
|
+
|---|---|---|
|
|
616
|
+
| `--since <duration>` | `24h` | Time window (e.g. `1h`, `7d`, `2026-04-20`). |
|
|
617
|
+
| `--type <pattern>` | — | `action_type` filter (`%` for LIKE matching). |
|
|
618
|
+
| `--result <value>` | — | `success` / `failed` / `partial` / `skipped`. |
|
|
619
|
+
| `--backend <name>` | — | `claude` / `codex` / `gemini`. |
|
|
620
|
+
| `--limit <N>` | 50 | Row cap. |
|
|
621
|
+
| `--detail` | off | Expand the `detail` JSON column under each row. |
|
|
622
|
+
| `--json` | off | Machine-readable JSON output. |
|
|
623
|
+
|
|
624
|
+
### `aitne doctor` checks
|
|
625
|
+
|
|
626
|
+
1. Node version ≥ 22.0.0
|
|
627
|
+
2. Daemon port (`PA_API_PORT`, default 8321) is bindable
|
|
628
|
+
3. Dashboard port (`PA_DASHBOARD_PORT`, default 3000) is bindable
|
|
629
|
+
4. OS secret store usable (`security` / `secret-tool` / `PA_MASTER_PASSWORD`)
|
|
630
|
+
5. At least one backend CLI (`claude`, `codex`, or `gemini`) responds to `--version`
|
|
631
|
+
6. `~/.personal-agent` exists and is writable
|
|
632
|
+
7. `better-sqlite3` native binding loads
|
|
633
|
+
8. `agent-assets/skills/` is reachable
|
|
281
634
|
|
|
282
635
|
---
|
|
283
636
|
|
|
284
|
-
##
|
|
637
|
+
## Architecture
|
|
285
638
|
|
|
286
|
-
|
|
639
|
+
```mermaid
|
|
640
|
+
flowchart TB
|
|
641
|
+
subgraph PLAT["📱 Input platforms"]
|
|
642
|
+
direction LR
|
|
643
|
+
P1[Slack]
|
|
644
|
+
P2[Telegram]
|
|
645
|
+
P3[Discord]
|
|
646
|
+
P4[WhatsApp]
|
|
647
|
+
P5[Dashboard]
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
subgraph DAEMON["⚙️ Aitne daemon (Hono :8321)"]
|
|
651
|
+
direction TB
|
|
652
|
+
EB[EventBus<br/>priority heap]
|
|
653
|
+
DI[Dispatcher<br/>semaphore: 2 reactive +<br/>3 autonomous]
|
|
654
|
+
BR[BackendRouter<br/>ProcessKey → tier → backend<br/>+ fallback]
|
|
655
|
+
AC[Agent Core<br/>IAgentCore interface]
|
|
656
|
+
OB[Observers<br/>Git · GitHub · Obsidian ·<br/>Notion · Calendar · Mail]
|
|
657
|
+
SC[Scheduler<br/>node-cron + agent_schedule]
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
subgraph BACKENDS["🧠 AI runtimes"]
|
|
661
|
+
direction LR
|
|
662
|
+
BC[Claude Code SDK]
|
|
663
|
+
BX[Codex CLI subprocess]
|
|
664
|
+
BG[Gemini CLI subprocess]
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
subgraph DATA["💾 Local data"]
|
|
668
|
+
direction LR
|
|
669
|
+
SQL[(SQLite<br/>WAL + FTS5)]
|
|
670
|
+
MD["📝 Markdown memory<br/>~/.personal-agent/context/"]
|
|
671
|
+
KC[OS Keychain]
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
PLAT --> EB
|
|
675
|
+
SC --> EB
|
|
676
|
+
OB --> SQL
|
|
677
|
+
SQL -- "hourly check pulls" --> EB
|
|
678
|
+
EB --> DI
|
|
679
|
+
DI --> BR
|
|
680
|
+
BR --> AC
|
|
681
|
+
AC --> BC
|
|
682
|
+
AC --> BX
|
|
683
|
+
AC --> BG
|
|
684
|
+
AC <-->|curl localhost API| DAEMON
|
|
685
|
+
DAEMON <--> SQL
|
|
686
|
+
DAEMON <--> MD
|
|
687
|
+
DAEMON <--> KC
|
|
688
|
+
```
|
|
287
689
|
|
|
288
|
-
|
|
690
|
+
### Two execution paths
|
|
289
691
|
|
|
290
|
-
|
|
692
|
+
**Reactive path** — owner DMs/mentions, cron routines, calendar approach events, scheduled tasks
|
|
693
|
+
→ Event source → EventBus → Dispatcher → BackendRouter → Agent → output to user
|
|
291
694
|
|
|
292
|
-
|
|
695
|
+
**Polling path** — Obsidian, Git, GitHub, Notion, Calendar, Mail change detection
|
|
696
|
+
→ Observer → `observations` table (UPSERT, with `actor='user'|'agent'`)
|
|
697
|
+
… time passes …
|
|
698
|
+
→ Hourly cron → Dispatcher.triggerHourlyCheck → agent reads pending → updates today.md / roadmap.md → notifies if needed
|
|
293
699
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
700
|
+
The `AgentWriteTracker` prevents agent → observer → agent loops by tagging the agent's own writes so the hourly check filters them out.
|
|
701
|
+
|
|
702
|
+
### Repo layout
|
|
297
703
|
|
|
298
|
-
# Windows (PowerShell)
|
|
299
|
-
netstat -ano | findstr :8321
|
|
300
704
|
```
|
|
705
|
+
packages/
|
|
706
|
+
├── daemon/ # Hono server, EventBus, Dispatcher, BackendRouter, observers, SQLite layer, integration SDK wrappers
|
|
707
|
+
├── dashboard/ # Next.js 16 + React 19 + Tailwind 4 + shadcn/ui
|
|
708
|
+
└── shared/ # Types, Zod schemas, ProcessKey enum, branding constants
|
|
301
709
|
|
|
302
|
-
|
|
710
|
+
agent-assets/ # Read by the daemon at session-init time
|
|
711
|
+
├── agent-profiles/ # Persona MD per backend (CLAUDE.md / AGENTS.md / GEMINI.md)
|
|
712
|
+
├── skills/ # 23 built-in skills (Context API, Calendar, Mail, …)
|
|
713
|
+
├── task-flows/ # Per-event prompt templates (one per event type)
|
|
714
|
+
└── templates/ # Scaffold MD copied to context/ on first run
|
|
303
715
|
|
|
304
|
-
|
|
716
|
+
bin/aitne.mjs # CLI entry — lifecycle + ops
|
|
717
|
+
scripts/ # Build/run helpers and per-command modules
|
|
718
|
+
docs/design/ # Architecture & design docs (v4.16) — source of truth
|
|
719
|
+
```
|
|
305
720
|
|
|
306
|
-
|
|
721
|
+
---
|
|
307
722
|
|
|
308
|
-
|
|
723
|
+
## Memory layout
|
|
309
724
|
|
|
310
|
-
|
|
311
|
-
aitne stop
|
|
312
|
-
# macOS / Linux
|
|
313
|
-
rm ~/.personal-agent/data/personal_agent.db*
|
|
314
|
-
# Windows (PowerShell)
|
|
315
|
-
Remove-Item "$env:USERPROFILE\.personal-agent\data\personal_agent.db*"
|
|
725
|
+
Everything the agent writes lives under `PA_DATA_DIR` (default `~/.personal-agent`):
|
|
316
726
|
|
|
317
|
-
|
|
727
|
+
```
|
|
728
|
+
~/.personal-agent/
|
|
729
|
+
├── context/ # Markdown memory — edit any file by hand at any time
|
|
730
|
+
│ ├── _index.md # Navigation hub
|
|
731
|
+
│ ├── today.md # Today's working view (always injected)
|
|
732
|
+
│ ├── yesterday.md # Daemon-rotated archive
|
|
733
|
+
│ ├── roadmap.md # Long-term goals (Morning + Evening injection)
|
|
734
|
+
│ ├── context-index.md # Auto-maintained index
|
|
735
|
+
│ ├── user/
|
|
736
|
+
│ │ ├── profile.md # ~600 tokens, always injected
|
|
737
|
+
│ │ ├── people.md # Relationship dictionary
|
|
738
|
+
│ │ ├── work.md, expertise.md, personal.md, goals.md
|
|
739
|
+
│ ├── rules/ # Policy files (management, redaction, journal)
|
|
740
|
+
│ ├── routines/ # Per-cadence checklist rulebooks
|
|
741
|
+
│ ├── dossiers/ # Carry-forward state per routine
|
|
742
|
+
│ ├── projects/ # One file per active project + Obsidian Bases view
|
|
743
|
+
│ ├── daily/<YYYY-MM-DD>.md # Synthesized daily journal (90 d retention)
|
|
744
|
+
│ ├── weekly/<YYYY-Www>.md # Weekly review (1 yr)
|
|
745
|
+
│ ├── monthly/<YYYY-MM>.md # Monthly review (3 yr)
|
|
746
|
+
│ ├── inbox/ # Optional paste bucket
|
|
747
|
+
│ └── agent/
|
|
748
|
+
│ ├── journal.md # Private agent self-reflection
|
|
749
|
+
│ └── scratch/ # 48-h TTL temp files
|
|
750
|
+
├── data/personal_agent.db # SQLite (WAL + FTS5)
|
|
751
|
+
├── logs/{daemon,dashboard}.log
|
|
752
|
+
├── prompts/ # Editable prompt templates
|
|
753
|
+
├── attachments/ # Chat attachments
|
|
754
|
+
├── agent-sessions/<id>/ # Per-session backend workdir
|
|
755
|
+
├── secrets/ # File-fallback secret store (`<name>.enc`); empty when OS keychain is used
|
|
756
|
+
└── run/ # PID files for daemon + dashboard
|
|
318
757
|
```
|
|
319
758
|
|
|
320
|
-
###
|
|
759
|
+
### Always-injected context
|
|
321
760
|
|
|
322
|
-
|
|
761
|
+
Every session starts with `user/profile.md` + `rules/management.md` + `today.md` injected. The agent never has to "search for context."
|
|
323
762
|
|
|
324
|
-
###
|
|
763
|
+
### Write chokepoint
|
|
325
764
|
|
|
326
|
-
|
|
765
|
+
Context-MD writes go through `curl http://localhost:8321/api/context/<path>` rather than the SDK's `Edit`/`Write` tools. This is enforced by skill instructions plus the absolute-block path globs that deny SDK writes to secret paths (`.env`, `~/.ssh`, `~/.aws`, `~/.personal-agent/secrets/**`, …). Routing context writes through the daemon API gives a single chokepoint for locks (`today.md` write lock), frontmatter validation, and snapshots (30-day `md_file_snapshots` retention).
|
|
327
766
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
767
|
+
---
|
|
768
|
+
|
|
769
|
+
## Multi-backend
|
|
770
|
+
|
|
771
|
+
Aitne abstracts three AI runtimes behind a single `IAgentCore` interface:
|
|
772
|
+
|
|
773
|
+
| Backend | Implementation | Session resume | Strengths |
|
|
774
|
+
|---|---|---|---|
|
|
775
|
+
| **Claude Code** | `@anthropic-ai/claude-agent-sdk` | ✅ Full session resume | Best for routines, deep context, server-side advisor |
|
|
776
|
+
| **Codex CLI** | OpenAI Codex CLI subprocess + JSONL stream | New session each time | Best for code-heavy tasks, fast iteration |
|
|
777
|
+
| **Gemini CLI** | Google Gemini CLI subprocess + JSONL stream | New session each time | Best for free-tier, large-context summarization |
|
|
778
|
+
|
|
779
|
+
### Per-process tier routing
|
|
780
|
+
|
|
781
|
+
Every kind of work has a `ProcessKey` mapped to a tier (`lite` / `medium` / `high`) and a backend. For Claude, those tiers map to Haiku 4.5 / Sonnet 4.6 / Opus 4.7.
|
|
782
|
+
|
|
783
|
+
| ProcessKey | Default tier | What runs there |
|
|
784
|
+
|---|---|---|
|
|
785
|
+
| `routine.morning_routine_initial` | **high** | First-day plan generation (one-shot, sets up profile) |
|
|
786
|
+
| `routine.morning_routine` | medium | Daily plan generation — the highest-value recurring process |
|
|
787
|
+
| `routine.evening_review` | medium | Today wrap-up |
|
|
788
|
+
| `routine.weekly_review`, `routine.monthly_review` | medium | Cadence summaries |
|
|
789
|
+
| `routine.hourly_check` | medium | Observation aggregation |
|
|
790
|
+
| `routine.hourly_check.triage` | lite | Stage 2 triage gate (escalate vs log-only) |
|
|
791
|
+
| `message.dm`, `message.mention` | medium | DM and channel response |
|
|
792
|
+
| `dashboard.chat` | medium | Web chat |
|
|
793
|
+
| `dashboard.docs_qa` | medium (tier-locked) | Docs panel — never burns Opus quota |
|
|
794
|
+
| `agent.task`, `agent.dm_task` | medium | Scheduled wakeups |
|
|
795
|
+
| `knowledge.import` | high | One-shot knowledge ingestion |
|
|
796
|
+
| `calendar.change`, `gmail_classify` | lite | Polling-derived events |
|
|
797
|
+
| `git.*`, `github.*` (event triage) | lite | Git/GitHub event triage |
|
|
798
|
+
| `delegated_task` | lite | Delegated subprocess task mode |
|
|
799
|
+
| `observation.summarize` | lite | Per-observation classification |
|
|
800
|
+
|
|
801
|
+
Configure each ProcessKey's backend & tier from the dashboard `/settings/models` page. The router fails over to a fallback backend automatically on `BackendQuotaError` or `BackendDecisiveFailure`.
|
|
331
802
|
|
|
332
803
|
---
|
|
333
804
|
|
|
334
|
-
##
|
|
805
|
+
## Integrations
|
|
335
806
|
|
|
336
|
-
|
|
807
|
+
### Messaging
|
|
808
|
+
|
|
809
|
+
| Platform | Library | Mode | Setup |
|
|
337
810
|
|---|---|---|---|
|
|
338
|
-
|
|
|
339
|
-
|
|
|
340
|
-
|
|
|
341
|
-
|
|
|
342
|
-
|
|
|
811
|
+
| Slack | `@slack/bolt` | Socket Mode (WebSocket) | Bot + App tokens |
|
|
812
|
+
| Telegram | `telegraf` | Long polling | Bot token |
|
|
813
|
+
| Discord | `discord.js` | Gateway | Bot token |
|
|
814
|
+
| WhatsApp | `baileys` | QR pairing | Scan QR from dashboard |
|
|
815
|
+
| Web Dashboard | Hono SSE | Always on | None |
|
|
816
|
+
|
|
817
|
+
### Mail (multi-provider, unified API)
|
|
818
|
+
|
|
819
|
+
| Provider | Auth | Features |
|
|
820
|
+
|---|---|---|
|
|
821
|
+
| **Gmail** | `googleapis` OAuth2 | Read · send · drafts · labels · IMAP IDLE · classifier |
|
|
822
|
+
| **Outlook** | `@azure/msal-node` Graph API | Read · send · drafts · folders |
|
|
823
|
+
| **Yahoo** | IMAP + OAuth2 | Read · send |
|
|
824
|
+
| **iCloud** | IMAP + app password | Read · send |
|
|
825
|
+
| **Generic IMAP** | username + password | Read |
|
|
826
|
+
|
|
827
|
+
Local FTS5 full-text search runs across **every** account via `GET /api/mail/search?q=...`.
|
|
828
|
+
|
|
829
|
+
### Knowledge & docs
|
|
830
|
+
|
|
831
|
+
- **Obsidian** — read directly via `Read`; write via the official Obsidian CLI 1.12+ (`obsidian create`, `obsidian append`, `obsidian daily:append`, …); chokidar watches the vault for user edits
|
|
832
|
+
- **Notion** — `@notionhq/client` REST API; full page + database CRUD
|
|
833
|
+
- **Custom MCP servers** — register via `/api/mcp/servers`, materialized into the per-session workdir so backends use them transparently
|
|
834
|
+
|
|
835
|
+
### Code
|
|
836
|
+
|
|
837
|
+
- **Git** (local) — daemon proxies `git log`, `git diff`, `git show`; cron-driven repository observer; `automation_triggers` table fires LLM prompts on `cron.daily` / `cron.weekly`
|
|
838
|
+
- **GitHub** — `@octokit/rest` + webhooks; PR list & comment, issue ops, HMAC-SHA256 signature verification at `POST /webhook/github`
|
|
839
|
+
|
|
840
|
+
### Calendar & travel
|
|
841
|
+
|
|
842
|
+
- **Google Calendar** — full event CRUD, freebusy, calendar list, 15-min approaching reminders
|
|
843
|
+
- **Google Maps** — Directions API for travel-time estimation tied to calendar events
|
|
844
|
+
|
|
845
|
+
### Lifestyle
|
|
846
|
+
|
|
847
|
+
- **Receipts** — auto-extracts PDF/image attachments from Gmail with category detection
|
|
848
|
+
- **Travel bookings** — auto-extracts flight, hotel, restaurant, train confirmations
|
|
849
|
+
- **Reading** — Kindle My Clippings importer; reading-taste profile; weekly book recommendations
|
|
850
|
+
|
|
851
|
+
### Integration delegation modes
|
|
852
|
+
|
|
853
|
+
Each integration runs in one of three modes:
|
|
854
|
+
|
|
855
|
+
| Mode | Auth held by | Setup cost | Capabilities |
|
|
856
|
+
|---|---|---|---|
|
|
857
|
+
| **`direct`** | Daemon (OAuth in OS Keychain) | 5–6 vendor-console steps | Full feature set |
|
|
858
|
+
| **`delegated`** | Backend's connector | None | Reduced (whatever the connector exposes) |
|
|
859
|
+
| **`disabled`** | — | — | Off |
|
|
860
|
+
|
|
861
|
+
Delegated mode lets you skip OAuth setup entirely if your backend already has a connector for the service. Aitne handles `same-backend` (no daemon hop) and `cross-backend` (daemon spawns a one-shot subprocess of the delegated backend) transparently.
|
|
862
|
+
|
|
863
|
+
---
|
|
864
|
+
|
|
865
|
+
## Safety model
|
|
866
|
+
|
|
867
|
+
Aitne uses three independent safety layers that hold in **every** execution mode:
|
|
868
|
+
|
|
869
|
+
### Layer 1 — SDK permission model
|
|
870
|
+
|
|
871
|
+
```typescript
|
|
872
|
+
// strict (Safe) mode — packages/daemon/src/core/backends/claude-code-core.ts
|
|
873
|
+
permissionMode: "dontAsk"
|
|
874
|
+
allowedTools: ["Read", "Glob", "Grep", "Write", "Edit", "Skill",
|
|
875
|
+
"Bash(curl *)", "Bash(git *)", "Bash(jq *)"]
|
|
876
|
+
disallowedTools: DEFAULT_DISALLOWED_TOOLS // ALWAYS_DISALLOWED + chmod/chown/git --force/reset --hard/clean
|
|
877
|
+
// Write/Edit on secret paths (.env, ~/.ssh, ~/.aws, ~/.personal-agent/secrets, …)
|
|
878
|
+
// are blocked by path-glob entries in the absolute-block layer.
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### Layer 1.5 — PreToolUse hooks
|
|
343
882
|
|
|
344
|
-
|
|
883
|
+
Every `curl` invocation has its destination URL parsed and checked. Anything that isn't `http://localhost:8321` is denied. Variable expansion (`$URL`) is resolved before the check.
|
|
345
884
|
|
|
346
|
-
|
|
885
|
+
### Layer 2 — Daemon API risk tiers
|
|
886
|
+
|
|
887
|
+
| Tier | Examples | Auth required |
|
|
888
|
+
|---|---|---|
|
|
889
|
+
| **Autonomous** | `GET /api/context/*`, `POST /api/notify`, `POST /api/schedule` | None (localhost only) |
|
|
890
|
+
| **ReadSensitive** | `GET /api/observations`, `GET /api/calendar/events`, `GET /api/mail/search` | `X-Read-Token` or Bearer |
|
|
891
|
+
| **Approve** | `PATCH /api/config`, `POST /api/setup/*`, `POST /api/system/factory-reset`, `POST /api/triggers`, `/api/repositories`, `/api/mcp/servers` | Bearer |
|
|
892
|
+
|
|
893
|
+
### Absolute-block layer (`ALWAYS_DISALLOWED_TOOLS`)
|
|
894
|
+
|
|
895
|
+
Hard-blocked in **both Safe and Allow** modes. Even `bypassPermissions` cannot widen past this:
|
|
896
|
+
|
|
897
|
+
- Recursive delete: `rm -rf *`, `rm -r *`
|
|
898
|
+
- Privilege escalation: `sudo *`, `doas *`, `su *`
|
|
899
|
+
- Pipe-to-shell RCE: `curl * | sh`, `wget * | bash`, `bash <(...)`
|
|
900
|
+
- Platform secret CLI: `security *`, `secret-tool *`, `cmdkey *`
|
|
901
|
+
- Secret file reads/writes: `.env`, `~/.ssh/**`, `~/.gnupg/**`, `~/.aws/**`, `~/.config/gcloud/**`
|
|
902
|
+
- Daemon-managed secrets: `~/.personal-agent/secrets/**`, `~/.personal-agent/whatsapp/auth/**`
|
|
903
|
+
|
|
904
|
+
### Other guarantees
|
|
905
|
+
|
|
906
|
+
- **Localhost-only API** — daemon binds to `127.0.0.1` only
|
|
907
|
+
- **Bearer token** — required for all Approve-tier endpoints
|
|
908
|
+
- **Webhook HMAC** — GitHub webhooks verified with `X-Hub-Signature-256`
|
|
909
|
+
- **No automated financial transactions** — never trade, transfer, or pay
|
|
910
|
+
- **No automated social posting** — never post publicly on your behalf
|
|
911
|
+
- **Single-owner only** — group chats and multi-user channels are filtered at the adapter layer
|
|
912
|
+
- **Auth Health Monitor** — hourly probe of every backend's auth state, with grace periods, escalating DMs, and auto-recovery flows for Claude / Codex / Gemini
|
|
913
|
+
|
|
914
|
+
---
|
|
915
|
+
|
|
916
|
+
## Cost & quotas
|
|
917
|
+
|
|
918
|
+
### Built-in controls
|
|
919
|
+
|
|
920
|
+
| Control | Default | Configurable |
|
|
921
|
+
|---|---|---|
|
|
922
|
+
| `maxConcurrentSessions` (autonomous) | 3 | yes |
|
|
923
|
+
| `maxReactiveSessions` (DMs) | 2 | yes |
|
|
924
|
+
| `executeTimeoutMinutes` (per-execute watchdog) | 60 | yes |
|
|
925
|
+
| `autonomousDailyCostCapUsd` | null (alert-only) | yes |
|
|
926
|
+
| `autonomousMonthlyCostCapUsd` | null (alert-only) | yes |
|
|
927
|
+
| Per-ProcessKey `maxBudgetUsd` (in `process_backend_config`) | per-row, set from `/settings/models` | yes |
|
|
928
|
+
| `delegated_task` `maxBudgetUsd` hard cap | $0.50 | no (compile-time) |
|
|
929
|
+
|
|
930
|
+
### Typical day's spend
|
|
931
|
+
|
|
932
|
+
```
|
|
933
|
+
04:00 Morning Routine (Opus / Sonnet) ~$0.15
|
|
934
|
+
07:00 Morning Briefing (Sonnet) ~$0.03
|
|
935
|
+
09:00 Hourly Check (Sonnet) ~$0.05
|
|
936
|
+
12:00 Hourly Check (Sonnet) ~$0.03
|
|
937
|
+
12:55 DM response (Opus) ~$0.10
|
|
938
|
+
18:00 Evening Review (Sonnet) ~$0.15
|
|
939
|
+
─────────────────────────────────────────────────
|
|
940
|
+
Total ~$0.51
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
If you're on a Claude / Codex / Gemini subscription, none of this hits a metered API key — it consumes your subscription quota directly. Quota exhaustion is detected, dedupe-notified once per 2-hour window, and the next hourly tick retries automatically.
|
|
347
944
|
|
|
348
945
|
---
|
|
349
946
|
|
|
350
947
|
## Configuration
|
|
351
948
|
|
|
352
|
-
`.env` is
|
|
949
|
+
`.env` is **bootstrap-only**. Everything else is editable from the dashboard at runtime — or via natural-language DMs to the agent.
|
|
353
950
|
|
|
354
|
-
|
|
951
|
+
### `.env` (bootstrap)
|
|
952
|
+
|
|
953
|
+
```bash
|
|
954
|
+
PA_DATA_DIR=~/.personal-agent # macOS / Linux
|
|
955
|
+
# PA_DATA_DIR=C:\Users\You\.personal-agent # Windows
|
|
956
|
+
PA_API_PORT=8321
|
|
957
|
+
PA_DASHBOARD_PORT=3000
|
|
958
|
+
PA_LOG_LEVEL=info # trace | debug | info | warn | error
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### Pre-seeding messaging via env (optional)
|
|
355
962
|
|
|
356
963
|
```bash
|
|
357
964
|
# Slack
|
|
@@ -373,92 +980,218 @@ PA_GIT_REPOS='["/path/to/repo1"]'
|
|
|
373
980
|
PA_GITHUB_REPOS='["owner/repo"]'
|
|
374
981
|
```
|
|
375
982
|
|
|
376
|
-
Google
|
|
983
|
+
Google services (Gmail, Calendar) and Notion are connected via OAuth from the dashboard `/connections` page after first launch — no env vars required.
|
|
984
|
+
|
|
985
|
+
### Runtime settings
|
|
986
|
+
|
|
987
|
+
The dashboard `/settings` tree exposes ~80 runtime keys. The headline ones:
|
|
988
|
+
|
|
989
|
+
- **Schedule** — `timezone`, `dayBoundaryHour`, hourly check window & interval, cron schedules
|
|
990
|
+
- **Notifications** — `quietHoursStart/End`, `maxNotificationsPerHour`, `maxNotificationsPerDay`, `batchIntervalMinutes`
|
|
991
|
+
- **Sessions** — `sessionTimeoutDmMinutes`, `historyInjectionMaxMessages`, `historyInjectionMaxTokens`
|
|
992
|
+
- **Safety** — execution mode per backend, `disallowedTools` overrides
|
|
993
|
+
- **Models** — per-ProcessKey backend + tier, advisor on/off, advisor model
|
|
994
|
+
- **Cost** — daily / monthly soft caps with 80% and 100% alerts
|
|
995
|
+
- **Mail** — provider list, poll interval, IMAP IDLE on/off
|
|
996
|
+
- **Character** — 1,000-char free-form tone description
|
|
997
|
+
|
|
998
|
+
…or just DM the agent: *"Don't run hourly checks on weekends."*
|
|
377
999
|
|
|
378
1000
|
---
|
|
379
1001
|
|
|
380
|
-
##
|
|
1002
|
+
## Platform support
|
|
381
1003
|
|
|
382
|
-
|
|
1004
|
+
| Concern | macOS | Linux | Windows |
|
|
1005
|
+
|---|---|---|---|
|
|
1006
|
+
| **Secret storage** | Keychain (`security`) | `secret-tool` (libsecret) → AES file fallback | DPAPI via `powershell.exe` → AES file fallback |
|
|
1007
|
+
| **Folder picker** | `osascript` | `zenity` / `kdialog` / `yad` | `System.Windows.Forms.FolderBrowserDialog` |
|
|
1008
|
+
| **Process tree kill** | POSIX process group | POSIX process group | `taskkill /T /F` |
|
|
1009
|
+
| **Log tailing (`-f`)** | Built-in Node tailer | Built-in Node tailer | Built-in Node tailer (no `tail` binary needed) |
|
|
1010
|
+
| **Console windows** | n/a | n/a | Background spawns hide the console window |
|
|
1011
|
+
|
|
1012
|
+
### WSL
|
|
1013
|
+
|
|
1014
|
+
GNOME Keyring / D-Bus are typically unavailable. Aitne falls back to the encrypted file store. Set:
|
|
383
1015
|
|
|
1016
|
+
```bash
|
|
1017
|
+
export PA_MASTER_PASSWORD='use-a-long-random-string'
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
### Linux secret-tool
|
|
1021
|
+
|
|
1022
|
+
```bash
|
|
1023
|
+
sudo apt-get install libsecret-tools # Debian / Ubuntu
|
|
1024
|
+
sudo dnf install libsecret # Fedora
|
|
1025
|
+
sudo pacman -S libsecret # Arch
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
### Windows long paths
|
|
1029
|
+
|
|
1030
|
+
If `npm install` fails with `ENAMETOOLONG`, run from elevated PowerShell and reboot:
|
|
1031
|
+
|
|
1032
|
+
```powershell
|
|
1033
|
+
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
|
|
1034
|
+
-Name "LongPathsEnabled" -Value 1
|
|
384
1035
|
```
|
|
385
|
-
~/.personal-agent/
|
|
386
|
-
├── context/ # Agent memory — edit any file by hand at any time
|
|
387
|
-
│ ├── context-index.md # Living index of every context file (auto-maintained)
|
|
388
|
-
│ ├── today.md # Today's plan + agent log
|
|
389
|
-
│ ├── roadmap.md # Long-term goals and upcoming milestones
|
|
390
|
-
│ ├── user/
|
|
391
|
-
│ │ ├── profile.md # Your profile (background, preferences, style)
|
|
392
|
-
│ │ ├── people.md # People the agent should know about
|
|
393
|
-
│ │ └── … # goals.md, expertise.md, personal.md, work.md
|
|
394
|
-
│ ├── rules/ # Policy files (agent + user co-authored)
|
|
395
|
-
│ ├── routines/ # Per-cadence checklist rulebooks
|
|
396
|
-
│ ├── dossiers/ # Per-routine carry-forward state
|
|
397
|
-
│ ├── daily/ # Synthesized daily journals (YYYY-MM-DD.md)
|
|
398
|
-
│ ├── projects/ # One file per active project
|
|
399
|
-
│ ├── weekly/ # Weekly review archives
|
|
400
|
-
│ └── monthly/ # Monthly review archives
|
|
401
|
-
├── data/
|
|
402
|
-
│ └── personal_agent.db # SQLite: sessions, schedule, observations, cost
|
|
403
|
-
├── logs/
|
|
404
|
-
│ ├── daemon.log
|
|
405
|
-
│ └── dashboard.log
|
|
406
|
-
└── bin/
|
|
407
|
-
└── auth.token # Bearer token for dashboard API access
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
The agent reads and writes `context/` exclusively through the daemon API. You can edit any file by hand at any time; the agent picks up changes on the next routine run.
|
|
411
1036
|
|
|
412
1037
|
---
|
|
413
1038
|
|
|
414
|
-
##
|
|
1039
|
+
## Troubleshooting
|
|
1040
|
+
|
|
1041
|
+
### `aitne start` says "dist not found"
|
|
1042
|
+
|
|
1043
|
+
The build did not complete. Run `aitne build` and check for TypeScript errors.
|
|
1044
|
+
|
|
1045
|
+
### Port already in use
|
|
1046
|
+
|
|
1047
|
+
Change `PA_API_PORT` in `.env`. To find the conflicting process:
|
|
415
1048
|
|
|
1049
|
+
```bash
|
|
1050
|
+
# macOS / Linux
|
|
1051
|
+
lsof -i :8321
|
|
1052
|
+
|
|
1053
|
+
# Windows
|
|
1054
|
+
netstat -ano | findstr :8321
|
|
416
1055
|
```
|
|
417
|
-
packages/
|
|
418
|
-
├── daemon/ # Node.js daemon — event bus, scheduler, adapters, API (Hono)
|
|
419
|
-
├── dashboard/ # Next.js 16 + React 19 + Tailwind 4 + shadcn/ui
|
|
420
|
-
└── shared/ # Types, Zod schemas, date utilities (no runtime deps)
|
|
421
1056
|
|
|
422
|
-
|
|
423
|
-
├── agent-profiles/ # Agent persona definitions (per-backend: CLAUDE.md / AGENTS.md / GEMINI.md)
|
|
424
|
-
├── skills/ # Built-in skill docs (Context API, Calendar, Gmail, MCP, roadmap, …)
|
|
425
|
-
├── task-flows/ # Per-event prompt templates (morning routine, hourly check, DM, …)
|
|
426
|
-
└── templates/ # Scaffold files copied to context/ on first run
|
|
1057
|
+
### `aitne` not found after `npm install -g`
|
|
427
1058
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
1059
|
+
```bash
|
|
1060
|
+
npm config get prefix
|
|
1061
|
+
# add the printed prefix's `bin/` (or its root on Windows) to your PATH
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
### SQLite errors on startup
|
|
1065
|
+
|
|
1066
|
+
The DB can be reset safely — your Markdown memory in `context/` is untouched:
|
|
1067
|
+
|
|
1068
|
+
```bash
|
|
1069
|
+
aitne stop
|
|
1070
|
+
rm ~/.personal-agent/data/personal_agent.db* # macOS / Linux
|
|
1071
|
+
# Remove-Item "$env:USERPROFILE\.personal-agent\data\personal_agent.db*" # Windows
|
|
1072
|
+
aitne start
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
### Backend auth expired
|
|
1076
|
+
|
|
1077
|
+
```bash
|
|
1078
|
+
aitne doctor # confirms which backend failed
|
|
1079
|
+
claude auth login --claudeai # re-auth Claude
|
|
1080
|
+
codex login --device-auth # re-auth Codex
|
|
1081
|
+
# Gemini re-auth happens automatically via the dashboard banner
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
### Diagnostic dump
|
|
1085
|
+
|
|
1086
|
+
```bash
|
|
1087
|
+
aitne audit --since 24h --result failed --detail
|
|
431
1088
|
```
|
|
432
1089
|
|
|
433
1090
|
---
|
|
434
1091
|
|
|
435
1092
|
## Development
|
|
436
1093
|
|
|
1094
|
+
For contributors:
|
|
1095
|
+
|
|
437
1096
|
```bash
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
pnpm
|
|
442
|
-
pnpm
|
|
443
|
-
pnpm
|
|
1097
|
+
git clone https://github.com/Aitne-sh/Aitne.git aitne
|
|
1098
|
+
cd aitne
|
|
1099
|
+
corepack enable
|
|
1100
|
+
pnpm install
|
|
1101
|
+
pnpm start # build (if stale) + launch in background
|
|
1102
|
+
pnpm dev # foreground mode with full stdio
|
|
1103
|
+
pnpm test # vitest — unit tests across packages/*
|
|
1104
|
+
pnpm test:watch
|
|
1105
|
+
pnpm lint # turbo run lint
|
|
1106
|
+
pnpm clean # remove all build artifacts and node_modules
|
|
444
1107
|
```
|
|
445
1108
|
|
|
446
|
-
|
|
1109
|
+
### Tech stack
|
|
1110
|
+
|
|
1111
|
+
| Layer | Stack |
|
|
1112
|
+
|---|---|
|
|
1113
|
+
| **Daemon** | Node.js 22 · Hono · `@anthropic-ai/claude-agent-sdk` · `@slack/bolt` · `telegraf` · `discord.js` · `baileys` · `googleapis` · `@notionhq/client` · `@octokit/rest` · `chokidar` · `node-cron` · `heap-js` · `pino` · `zod` |
|
|
1114
|
+
| **Storage** | `better-sqlite3` (WAL + FTS5 trigram) · OS Keychain · plain Markdown |
|
|
1115
|
+
| **Dashboard** | Next.js 16 (App Router) · React 19 · Tailwind CSS 4 · shadcn/ui · TanStack Query · Recharts · Monaco Editor |
|
|
1116
|
+
| **Monorepo** | pnpm 10.x workspaces · Turborepo · TypeScript 5.8 · Vitest 3 |
|
|
1117
|
+
|
|
1118
|
+
### Conventions
|
|
1119
|
+
|
|
1120
|
+
- All code, comments, tests, and user-facing text are in **English**
|
|
1121
|
+
- TypeScript throughout, camelCase, ESM with `.js` import extensions
|
|
1122
|
+
- Tests colocated with source as `foo.ts` + `foo.test.ts`
|
|
1123
|
+
- Vitest enforces **100% coverage** on a curated subset of pure-logic modules
|
|
1124
|
+
- The `docs/design/` tree (v4.16) is the authoritative spec; `packages/daemon/src/` is the source of truth when they diverge
|
|
1125
|
+
|
|
1126
|
+
### Source-of-truth pointers
|
|
1127
|
+
|
|
1128
|
+
| If you need to… | Start in |
|
|
1129
|
+
|---|---|
|
|
1130
|
+
| Understand startup order | `packages/daemon/src/index.ts` |
|
|
1131
|
+
| Change event routing | `src/core/dispatcher.ts` + `src/core/event-bus.ts` |
|
|
1132
|
+
| Add a backend or change tier mapping | `packages/shared/src/process-key.ts` + `src/core/backends/backend-router.ts` |
|
|
1133
|
+
| Add an API route | `src/api/routes/` + register in `src/api/server.ts` |
|
|
1134
|
+
| Add an integration | `src/services/<name>/` + `src/observers/` (if polling) + `src/api/routes/` |
|
|
1135
|
+
| Edit a built-in skill | `agent-assets/skills/<slug>/SKILL.md` |
|
|
1136
|
+
| Edit an event task flow | `agent-assets/task-flows/<eventType>.md` |
|
|
1137
|
+
| Change risk classification | `src/safety/risk-classifier.ts` |
|
|
1138
|
+
| Change auth health / recovery | `src/core/backends/auth-health-monitor.ts` + `auth-recovery.ts` |
|
|
447
1139
|
|
|
448
1140
|
---
|
|
449
1141
|
|
|
450
|
-
##
|
|
1142
|
+
## FAQ
|
|
1143
|
+
|
|
1144
|
+
**Is Aitne a chatbot?**
|
|
1145
|
+
No. It's a daemon. It also responds to chat, but the more interesting half is what it does *while you're not looking at it*.
|
|
1146
|
+
|
|
1147
|
+
**Does it phone home?**
|
|
1148
|
+
No. The daemon binds to `127.0.0.1` only. There is no telemetry. Verify with `lsof` and `nettop`.
|
|
451
1149
|
|
|
452
|
-
|
|
1150
|
+
**Where do my secrets live?**
|
|
1151
|
+
In your OS-native credential store (macOS Keychain / libsecret / DPAPI). Never in `.env`. On systems without a credential store, in an AES-encrypted file under `~/.personal-agent/secrets/`.
|
|
453
1152
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
1153
|
+
**Can I bring my own AI?**
|
|
1154
|
+
Yes — Claude Code, OpenAI Codex, and Google Gemini CLI are all supported. Pick one or all three. Per-process tier routing lets you mix-and-match.
|
|
1155
|
+
|
|
1156
|
+
**Do I need an API key?**
|
|
1157
|
+
You don't need a metered API key — Aitne uses your subscription quota via the official CLIs (`claude auth login`, `codex login`, `gemini`). If you'd rather pay-as-you-go, supply `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY` in the wizard.
|
|
1158
|
+
|
|
1159
|
+
**Can I edit the agent's memory directly?**
|
|
1160
|
+
Yes — that's the entire point. Open `~/.personal-agent/context/today.md` in your editor, change anything, save. The agent picks up your edits on the next routine. Any edit is *just text in a file* — no proprietary format, no migration headaches if you uninstall.
|
|
1161
|
+
|
|
1162
|
+
**What about Obsidian?**
|
|
1163
|
+
Aitne can use your existing Obsidian vault as the primary memory store. The agent reads vault files directly and writes via the official Obsidian CLI. Your wiki links keep working. Your daily notes get appended to.
|
|
1164
|
+
|
|
1165
|
+
**Can I run my own MCP servers?**
|
|
1166
|
+
Yes. Register them in the dashboard `/connections` page; the daemon writes the per-session MCP config into each backend's session workdir before launching, so all your MCP tools are available transparently.
|
|
1167
|
+
|
|
1168
|
+
**Do my existing Claude Code / Codex / Gemini settings work?**
|
|
1169
|
+
Yes. Aitne reads your `~/.claude/`, `~/.codex/`, `~/.gemini/` configs on session init and layers its persona on top. Custom skills, slash commands, MCP servers, and plugins all carry over. See [Bring your own harness](#bring-your-own-harness-byoh).
|
|
1170
|
+
|
|
1171
|
+
**Does it work without internet?**
|
|
1172
|
+
The AI backends and reactive messaging need internet (to hit those services). The daemon, dashboard, observers (Git, Obsidian local), and Markdown memory are entirely offline.
|
|
1173
|
+
|
|
1174
|
+
**Does it support languages other than English?**
|
|
1175
|
+
Yes. Talk to it in your native language — Japanese, German, Spanish, anything. The LLM handles it. The agent's internal Markdown memory is multilingual; what's stored is what you say.
|
|
1176
|
+
|
|
1177
|
+
**Is this for my whole team?**
|
|
1178
|
+
No — Aitne is **single-owner by design**. Group chats and multi-user channels are filtered at the adapter layer. If you want a team agent, run one Aitne per teammate.
|
|
1179
|
+
|
|
1180
|
+
**How do I uninstall?**
|
|
1181
|
+
`aitne uninstall`. It will offer to wipe `~/.personal-agent` or keep it for re-installation.
|
|
459
1182
|
|
|
460
1183
|
---
|
|
461
1184
|
|
|
462
1185
|
## License
|
|
463
1186
|
|
|
464
1187
|
MIT — use, modify, and distribute freely. See [LICENSE](./LICENSE) for the full text.
|
|
1188
|
+
|
|
1189
|
+
---
|
|
1190
|
+
|
|
1191
|
+
<div align="center">
|
|
1192
|
+
|
|
1193
|
+
**Aitne — Always on. Always yours.**
|
|
1194
|
+
|
|
1195
|
+
[Issues](https://github.com/Aitne-sh/Aitne/issues) · [Discussions](https://github.com/Aitne-sh/Aitne/discussions) · [npm](https://www.npmjs.com/package/@aitne-sh/aitne)
|
|
1196
|
+
|
|
1197
|
+
</div>
|