@kingcrab/pi-imessage 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +120 -0
  2. package/dist/agent.d.ts +22 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +341 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/cli.d.ts +15 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +179 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/imessage.d.ts +32 -0
  11. package/dist/imessage.d.ts.map +1 -0
  12. package/dist/imessage.js +65 -0
  13. package/dist/imessage.js.map +1 -0
  14. package/dist/logger.d.ts +33 -0
  15. package/dist/logger.d.ts.map +1 -0
  16. package/dist/logger.js +103 -0
  17. package/dist/logger.js.map +1 -0
  18. package/dist/main.d.ts +5 -0
  19. package/dist/main.d.ts.map +1 -0
  20. package/dist/main.js +66 -0
  21. package/dist/main.js.map +1 -0
  22. package/dist/pipeline.d.ts +26 -0
  23. package/dist/pipeline.d.ts.map +1 -0
  24. package/dist/pipeline.js +48 -0
  25. package/dist/pipeline.js.map +1 -0
  26. package/dist/queue.d.ts +16 -0
  27. package/dist/queue.d.ts.map +1 -0
  28. package/dist/queue.js +47 -0
  29. package/dist/queue.js.map +1 -0
  30. package/dist/self-echo.d.ts +19 -0
  31. package/dist/self-echo.d.ts.map +1 -0
  32. package/dist/self-echo.js +54 -0
  33. package/dist/self-echo.js.map +1 -0
  34. package/dist/send.d.ts +17 -0
  35. package/dist/send.d.ts.map +1 -0
  36. package/dist/send.js +107 -0
  37. package/dist/send.js.map +1 -0
  38. package/dist/settings.d.ts +39 -0
  39. package/dist/settings.d.ts.map +1 -0
  40. package/dist/settings.js +74 -0
  41. package/dist/settings.js.map +1 -0
  42. package/dist/store.d.ts +41 -0
  43. package/dist/store.d.ts.map +1 -0
  44. package/dist/store.js +72 -0
  45. package/dist/store.js.map +1 -0
  46. package/dist/tasks.d.ts +88 -0
  47. package/dist/tasks.d.ts.map +1 -0
  48. package/dist/tasks.js +260 -0
  49. package/dist/tasks.js.map +1 -0
  50. package/dist/types.d.ts +77 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +24 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/watch.d.ts +21 -0
  55. package/dist/watch.d.ts.map +1 -0
  56. package/dist/watch.js +137 -0
  57. package/dist/watch.js.map +1 -0
  58. package/dist/web/data.d.ts +11 -0
  59. package/dist/web/data.d.ts.map +1 -0
  60. package/dist/web/data.js +56 -0
  61. package/dist/web/data.js.map +1 -0
  62. package/dist/web/html.d.ts +5 -0
  63. package/dist/web/html.d.ts.map +1 -0
  64. package/dist/web/html.js +16 -0
  65. package/dist/web/html.js.map +1 -0
  66. package/dist/web/index.d.ts +15 -0
  67. package/dist/web/index.d.ts.map +1 -0
  68. package/dist/web/index.js +116 -0
  69. package/dist/web/index.js.map +1 -0
  70. package/dist/web/render.d.ts +5 -0
  71. package/dist/web/render.d.ts.map +1 -0
  72. package/dist/web/render.js +50 -0
  73. package/dist/web/render.js.map +1 -0
  74. package/dist/web/templates/page.eta +85 -0
  75. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # pi-imessage
2
+
3
+ An self-managing iMessage bot — powered by [pi](https://github.com/badlogic/pi-mono).
4
+
5
+ ![](https://github.com/user-attachments/assets/0dbfd0ae-1e22-4c0f-8421-7b2c93cfe174)
6
+
7
+ ## Features
8
+
9
+ - **Transparent**: tool calls and reasoning are sent to your iMessage chat, so you can see exactly what it's doing and why
10
+ - **Web UI**: browse chat history, toggle replies on/off, live updates
11
+ - **Working memory & custom tools**: remembers context across sessions and creates workflow-specific CLI tools (aka "skills") for your tasks
12
+ - **Group chat aware**: distinguishes DMs, SMS, and group chats; identifies who sent each message
13
+
14
+ ## Quick Start
15
+
16
+ Prerequisites: macOS with Messages.app, Full Disk Access for the terminal, [Pi Coding Agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent#quick-start) authenticated
17
+
18
+ ```bash
19
+ npm install -g @kingcrab/pi-imessage
20
+
21
+ pi-imessage # run in foreground
22
+ pi-imessage install # install as launchd service (auto-start on boot, restart on crash)
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Web UI
28
+
29
+ Available at `http://localhost:7750` (configurable via `WEB_PORT`).
30
+
31
+ - Displays chat logs from the last 7 days, sorted by most recent activity
32
+ - Toggle reply on/off per chat
33
+ - Live updates via SSE when new messages arrive
34
+
35
+ ### Commands
36
+
37
+ Send these as iMessage to interact with the bot:
38
+
39
+ | Command | Description | Example Reply |
40
+ |---|---|---|
41
+ | `/new` | Reset the session, starting a fresh conversation | `✓ New session started` |
42
+ | `/status` | Show session stats: tokens, context, model | `💬 3 msgs - ↑7.2k ↓505 1.1%/128k`<br>`🤖 anthropic/claude-sonnet-4 • 💭 minimal` |
43
+
44
+ ### Settings (`WORKING_DIR/settings.json`)
45
+
46
+ All fields are optional.
47
+
48
+ ```json
49
+ {
50
+ "chatAllowlist": {
51
+ "whitelist": ["*"],
52
+ "blacklist": ["iMessage;-;+11234567890"]
53
+ }
54
+ }
55
+ ```
56
+
57
+ **Chat allowlist** controls which chats receive replies (messages are always logged). Resolution priority: `blacklist[guid]` > `whitelist[guid]` > `blacklist["*"]` > `whitelist["*"]`.
58
+
59
+ ### Environment Variables
60
+
61
+ | Variable | Required | Default | Description |
62
+ |---|---|---|---|
63
+ | `WEB_HOST` | no | `localhost` | Web UI host |
64
+ | `WEB_PORT` | no | `7750` | Web UI port |
65
+ | `WORKING_DIR` | no | `~/.pi/imessage` | Workspace directory |
66
+
67
+ ## Development
68
+
69
+ ```bash
70
+ npm run check # typecheck + lint (run after code changes)
71
+ npm test # run tests
72
+ ```
73
+
74
+ ## How It Works
75
+
76
+ ```
77
+ ~/Library/Messages/chat.db
78
+
79
+ (poll every 2s for new rows)
80
+
81
+
82
+ ┌──────────────────────────────────────────────────┐
83
+ │ pi-imessage │
84
+ │ │
85
+ │ Watcher (chat.db polling) │
86
+ │ │ │
87
+ │ ├─ Filter: is_from_me=0, no reactions │
88
+ │ ├─ Deduplicate via seenRowIds │
89
+ │ ├─ Read attachments from local disk │
90
+ │ │ │
91
+ │ ▼ │
92
+ │ AsyncQueue<IncomingMessage> │
93
+ │ │ │
94
+ │ ▼ │
95
+ │ SessionManager (pi-coding-agent) │
96
+ │ │ per chatGuid, persistent on disk │
97
+ │ │ └─ data/<chatGuid>/ │
98
+ │ │ ├─ log.jsonl (full history) │
99
+ │ │ └─ context.jsonl (LLM context) │
100
+ │ │ │
101
+ │ ▼ │
102
+ │ Agent loop (pi-agent-core) │
103
+ │ │ │
104
+ │ │ ┌─ outer: follow-up messages ────┐ │
105
+ │ │ │ ┌─ inner: tool calls + ┐ │ │
106
+ │ │ │ │ steering messages │ │ │
107
+ │ │ │ └───────────────────────────┘ │ │
108
+ │ │ └────────────────────────────────┘ │
109
+ │ │ │
110
+ │ ▼ │
111
+ │ Collect assistant reply text │
112
+ │ │ │
113
+ │ ├─ sendMessage (AppleScript → Messages.app) │
114
+ │ └─ save logs (messages, digests) │
115
+ │ │
116
+ └──────────────────────────────────────────────────┘
117
+
118
+
119
+ iMessage (user receives reply via Messages.app)
120
+ ```
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Agent module — text-in / text-out AI processor per iMessage chat.
3
+ *
4
+ * Each chat gets a lazily-created AgentSession with persistent context
5
+ * (context.jsonl per chat directory).
6
+ *
7
+ * Reply delivery: each tool or assistant event enqueues an onReply call
8
+ * through replyChain, so iMessages arrive in order.
9
+ *
10
+ * Model: uses ~/.pi/agent/ defaults (via createAgentSession).
11
+ */
12
+ import type { AgentReply, IncomingMessage } from "./types.js";
13
+ export interface AgentManagerConfig {
14
+ workingDir: string;
15
+ }
16
+ export declare function createAgentManager(config: AgentManagerConfig): Promise<{
17
+ processMessage: (msg: IncomingMessage, onReply: (reply: AgentReply) => Promise<void>) => Promise<void>;
18
+ newSession: (chatGuid: string) => Promise<void>;
19
+ getSessionStatus: (chatGuid: string) => Promise<string>;
20
+ }>;
21
+ export type AgentManager = Pick<Awaited<ReturnType<typeof createAgentManager>>, "processMessage" | "newSession" | "getSessionStatus">;
22
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAI9D,MAAM,WAAW,kBAAkB;IAClC,UAAU,EAAE,MAAM,CAAC;CACnB;AAuMD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB;0BAqC/B,eAAe,WAAW,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;2BAsF7E,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iCAkBhB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;GA4BlE;AAWD,MAAM,MAAM,YAAY,GAAG,IAAI,CAC9B,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,EAC9C,gBAAgB,GAAG,YAAY,GAAG,kBAAkB,CACpD,CAAC"}
package/dist/agent.js ADDED
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Agent module — text-in / text-out AI processor per iMessage chat.
3
+ *
4
+ * Each chat gets a lazily-created AgentSession with persistent context
5
+ * (context.jsonl per chat directory).
6
+ *
7
+ * Reply delivery: each tool or assistant event enqueues an onReply call
8
+ * through replyChain, so iMessages arrive in order.
9
+ *
10
+ * Model: uses ~/.pi/agent/ defaults (via createAgentSession).
11
+ */
12
+ import { existsSync, mkdirSync, readFileSync, unlinkSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { AuthStorage, DefaultResourceLoader, ModelRegistry, SessionManager, createAgentSession, } from "@mariozechner/pi-coding-agent";
15
+ /** Create and initialize shared resources (auth, model registry, resource loader). */
16
+ async function initSharedResources(workingDir) {
17
+ const authStorage = AuthStorage.create();
18
+ const modelRegistry = new ModelRegistry(authStorage);
19
+ // Resource loader with iMessage-specific system prompt; no extensions/skills needed.
20
+ const resourceLoader = new DefaultResourceLoader({
21
+ systemPrompt: buildSystemPrompt(workingDir),
22
+ noExtensions: true,
23
+ noSkills: true,
24
+ noPromptTemplates: true,
25
+ noThemes: true,
26
+ });
27
+ await resourceLoader.reload();
28
+ return { authStorage, modelRegistry, resourceLoader };
29
+ }
30
+ // ── Helpers ───────────────────────────────────────────────────────────────────
31
+ /**
32
+ * Format a prompt with sender/chat context prefix.
33
+ *
34
+ * Examples:
35
+ * [DM from +1234567890] hey
36
+ * [SMS from +1234567890] hey
37
+ * [Group 'Family' from alice@example.com] hey
38
+ */
39
+ function formatPromptText(msg) {
40
+ const text = msg.text ?? "";
41
+ let prefix;
42
+ if (msg.messageType === "group") {
43
+ const name = msg.groupName || "unnamed";
44
+ prefix = `[Group '${name}' from ${msg.sender}]`;
45
+ }
46
+ else if (msg.messageType === "sms") {
47
+ prefix = `[SMS from ${msg.sender}]`;
48
+ }
49
+ else {
50
+ prefix = `[DM from ${msg.sender}]`;
51
+ }
52
+ return `${prefix} ${text}`;
53
+ }
54
+ /** Replace characters that are invalid in directory names. */
55
+ function sanitizeChatGuid(chatGuid) {
56
+ return chatGuid.replace(/[^a-zA-Z0-9_\-;+.@]/g, "_");
57
+ }
58
+ /** Read global and chat-specific MEMORY.md files, returning combined content. */
59
+ function getMemory(workingDir, chatDir) {
60
+ const parts = [];
61
+ const globalMemoryPath = join(workingDir, "MEMORY.md");
62
+ if (existsSync(globalMemoryPath)) {
63
+ try {
64
+ const content = readFileSync(globalMemoryPath, "utf-8").trim();
65
+ if (content) {
66
+ parts.push(`### Global Memory\n${content}`);
67
+ }
68
+ }
69
+ catch (error) {
70
+ console.warn(`[agent] failed to read global memory: ${error}`);
71
+ }
72
+ }
73
+ if (chatDir) {
74
+ const chatMemoryPath = join(chatDir, "MEMORY.md");
75
+ if (existsSync(chatMemoryPath)) {
76
+ try {
77
+ const content = readFileSync(chatMemoryPath, "utf-8").trim();
78
+ if (content) {
79
+ parts.push(`### Chat Memory\n${content}`);
80
+ }
81
+ }
82
+ catch (error) {
83
+ console.warn(`[agent] failed to read chat memory: ${error}`);
84
+ }
85
+ }
86
+ }
87
+ return parts.length > 0 ? parts.join("\n\n") : "(no memory yet)";
88
+ }
89
+ function buildSystemPrompt(workingDir, chatDir) {
90
+ const memory = getMemory(workingDir, chatDir);
91
+ return `You are the user's best friend communicating via iMessage. Be concise. No emojis.
92
+
93
+ ## Context
94
+ - Plain text only. Do not use Markdown formatting, double asterisks (**like this**), or [markdown](links).
95
+ - Reply in the same language the user is writing in.
96
+
97
+ ## Environment
98
+ You are running directly on the host machine.
99
+ - Bash working directory: ${workingDir}
100
+ - Be careful with system modifications;
101
+
102
+ ## Workspace Layout
103
+ ${workingDir}/
104
+ ├── settings.json # Bot configuration (see below)
105
+ ├── MEMORY.md # Global memory (all chats)
106
+ ├── SYSTEM.md # System configuration log
107
+ ├── skills/ # Global CLI tools you create
108
+ └── <chatId>/ # Each iMessage chat gets a directory
109
+ ├── MEMORY.md # Chat-specific memory
110
+ ├── context.jsonl # LLM context (session persistence)
111
+ ├── log.jsonl # Message history
112
+ ├── attachments/ # User-shared files
113
+ ├── scratch/ # Your working directory
114
+ └── skills/ # Chat-specific tools
115
+
116
+ ## Memory
117
+ Write to MEMORY.md files to persist context across conversations.
118
+ - Global (${workingDir}/MEMORY.md): preferences, project info, shared knowledge
119
+ - Chat-specific (<chatDir>/MEMORY.md): user details, ongoing topics, decisions
120
+ Update when you learn something important or when asked to remember something.
121
+
122
+ ### Current Memory
123
+ ${memory}
124
+
125
+ ## System Configuration Log
126
+ Maintain ${workingDir}/SYSTEM.md to log all environment modifications:
127
+ - Installed packages (npm install, pip install, brew install, etc.)
128
+ - Environment variables set
129
+ - Config files modified (~/.gitconfig, cron jobs, etc.)
130
+ - Skill dependencies installed
131
+
132
+ Update this file whenever you modify the environment.
133
+
134
+ ## Skills (Custom CLI Tools)
135
+ You can create reusable CLI tools for recurring tasks (email, APIs, data processing, etc.).
136
+
137
+ ### Creating Skills
138
+ Store in \`${workingDir}/skills/<name>/\` (global) or \`<chatDir>/skills/<name>/\` (chat-specific).
139
+ Each skill directory needs a \`SKILL.md\` with YAML frontmatter:
140
+
141
+ \`\`\`markdown
142
+ ---
143
+ name: skill-name
144
+ description: What this skill does
145
+ ---
146
+ Usage instructions and details here.
147
+ \`\`\``;
148
+ }
149
+ /** Extract concatenated text from a Message, ignoring non-text content parts. */
150
+ function extractMessageText(message) {
151
+ if (typeof message.content === "string")
152
+ return message.content;
153
+ const texts = message.content
154
+ .filter((part) => part.type === "text" && "text" in part)
155
+ .map((part) => part.text);
156
+ const joined = texts.join("\n").trim();
157
+ return joined || null;
158
+ }
159
+ /** Extract human-readable text from a tool result (string or content-array). */
160
+ function extractToolResultText(result) {
161
+ if (typeof result === "string")
162
+ return result;
163
+ if (result && typeof result === "object" && "content" in result) {
164
+ const content = result.content;
165
+ if (Array.isArray(content)) {
166
+ const parts = [];
167
+ for (const part of content) {
168
+ if (part && typeof part === "object" && part.type === "text" && "text" in part) {
169
+ parts.push(part.text);
170
+ }
171
+ }
172
+ const joined = parts.join("\n").trim();
173
+ if (joined)
174
+ return joined;
175
+ }
176
+ }
177
+ return JSON.stringify(result);
178
+ }
179
+ /** Pick a human-readable label for a tool invocation. */
180
+ function extractToolLabel(toolName, args) {
181
+ if (toolName === "bash" && typeof args.command === "string")
182
+ return args.command;
183
+ if (typeof args.path === "string")
184
+ return `${toolName}: ${args.path}`;
185
+ if (typeof args.label === "string")
186
+ return args.label;
187
+ return toolName;
188
+ }
189
+ // ── Agent Manager ─────────────────────────────────────────────────────────────
190
+ export async function createAgentManager(config) {
191
+ const { workingDir } = config;
192
+ const sessionMap = new Map();
193
+ const { modelRegistry, resourceLoader } = await initSharedResources(workingDir);
194
+ /** Lazily create one AgentSession per chat, persisted to context.jsonl. */
195
+ async function getOrCreateSession(chatGuid) {
196
+ const existing = sessionMap.get(chatGuid);
197
+ if (existing)
198
+ return existing;
199
+ // Per-chat session manager — each chat gets its own context.jsonl.
200
+ const chatDir = join(workingDir, sanitizeChatGuid(chatGuid));
201
+ mkdirSync(chatDir, { recursive: true });
202
+ const sessionManager = SessionManager.open(join(chatDir, "context.jsonl"), chatDir);
203
+ const { session } = await createAgentSession({
204
+ modelRegistry,
205
+ sessionManager,
206
+ resourceLoader,
207
+ });
208
+ const model = session.model;
209
+ const modelLabel = model ? `${model.provider}/${model.id}` : "default";
210
+ console.log(`[agent] session created: ${chatGuid} model=${modelLabel}`);
211
+ const entry = { session, chatGuid };
212
+ sessionMap.set(chatGuid, entry);
213
+ return entry;
214
+ }
215
+ /**
216
+ * Send a user message through the agent and deliver replies via onReply.
217
+ *
218
+ * Events are serialized: each tool_execution_start/end and assistant
219
+ * message_end enqueues an onReply call through replyChain so iMessages
220
+ * arrive in order.
221
+ */
222
+ async function processMessage(msg, onReply) {
223
+ const entry = await getOrCreateSession(msg.chatGuid);
224
+ // Track pending tool calls for duration logging
225
+ const pendingTools = new Map();
226
+ // Serialize onReply calls — subscribe is sync so we chain promises
227
+ let replyChain = Promise.resolve();
228
+ const unsub = entry.session.subscribe((event) => {
229
+ if (event.type === "message_end" && event.message.role === "assistant") {
230
+ const assistantMsg = event.message;
231
+ const text = extractMessageText(event.message);
232
+ const stopReason = assistantMsg.stopReason;
233
+ const errorMessage = assistantMsg.errorMessage;
234
+ console.log(`[agent] message end: ${entry.chatGuid} role=assistant stopReason=${stopReason}` +
235
+ `${errorMessage ? ` error="${errorMessage}"` : ""}` +
236
+ ` text="${(text ?? "(empty)").substring(0, 60)}"`);
237
+ if (text) {
238
+ replyChain = replyChain.then(() => onReply({ kind: "assistant", text }));
239
+ }
240
+ }
241
+ else if (event.type === "tool_execution_start") {
242
+ const toolArgs = event.args;
243
+ const label = extractToolLabel(event.toolName, toolArgs);
244
+ pendingTools.set(event.toolCallId, {
245
+ toolName: event.toolName,
246
+ args: toolArgs,
247
+ startTime: Date.now(),
248
+ });
249
+ console.log(`[agent] tool start: ${entry.chatGuid} → ${label}`);
250
+ replyChain = replyChain.then(() => onReply({ kind: "tool_start", label }));
251
+ }
252
+ else if (event.type === "tool_execution_end") {
253
+ const resultText = extractToolResultText(event.result);
254
+ const pending = pendingTools.get(event.toolCallId);
255
+ pendingTools.delete(event.toolCallId);
256
+ const durationMs = pending ? Date.now() - pending.startTime : 0;
257
+ const duration = (durationMs / 1000).toFixed(1);
258
+ const symbol = event.isError ? "✗" : "✓";
259
+ console.log(`[agent] tool end: ${entry.chatGuid} ${symbol} ${event.toolName} (${duration}s)` +
260
+ ` result="${resultText.substring(0, 60)}"`);
261
+ replyChain = replyChain.then(() => onReply({ kind: "tool_end", toolName: event.toolName, symbol, duration, result: resultText }));
262
+ }
263
+ });
264
+ // Build prompt with sender/chat context prefix
265
+ // Format: "[DM from +1234567890] hey" or "[Group 'Family' from alice@example.com] hey"
266
+ const promptText = formatPromptText(msg);
267
+ // Refresh system prompt with current memory before each prompt
268
+ const chatDir = join(workingDir, sanitizeChatGuid(msg.chatGuid));
269
+ entry.session.agent.setSystemPrompt(buildSystemPrompt(workingDir, chatDir));
270
+ const currentModel = entry.session.model;
271
+ const currentModelLabel = currentModel ? `${currentModel.provider}/${currentModel.id}` : "default";
272
+ console.log(`[agent] prompt start (steer): ${entry.chatGuid} model=${currentModelLabel} "${promptText.substring(0, 60)}"`);
273
+ const promptPromise = msg.images.length > 0
274
+ ? entry.session.prompt(promptText, { images: msg.images, streamingBehavior: "steer" })
275
+ : entry.session.prompt(promptText, { streamingBehavior: "steer" });
276
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("agent prompt timed out after 120s")), 120_000));
277
+ try {
278
+ await Promise.race([promptPromise, timeoutPromise]);
279
+ await replyChain; // wait for all dispatched replies to finish
280
+ console.log(`[agent] prompt end: ${entry.chatGuid}`);
281
+ }
282
+ finally {
283
+ unsub();
284
+ }
285
+ }
286
+ /** Start a new session for a chat by deleting context and evicting the in-memory session. */
287
+ async function newSession(chatGuid) {
288
+ sessionMap.delete(chatGuid);
289
+ const chatDir = join(workingDir, sanitizeChatGuid(chatGuid));
290
+ const contextFile = join(chatDir, "context.jsonl");
291
+ if (existsSync(contextFile)) {
292
+ unlinkSync(contextFile);
293
+ }
294
+ console.log(`[agent] new session: ${chatGuid}`);
295
+ }
296
+ /**
297
+ * Get a formatted status string for a chat session.
298
+ * Lazily creates/resumes the session from disk if not already in memory.
299
+ *
300
+ * Format (two lines):
301
+ * 💬 3 msgs - ↑7.2k ↓505 1.1%/128k
302
+ * 🤖 github-copilot/gpt-5-mini • 💭 minimal
303
+ */
304
+ async function getSessionStatus(chatGuid) {
305
+ const entry = await getOrCreateSession(chatGuid);
306
+ const { session } = entry;
307
+ const stats = session.getSessionStats();
308
+ const contextUsage = session.getContextUsage();
309
+ const model = session.model;
310
+ const thinkingLevel = session.thinkingLevel;
311
+ // Line 1: message count + token counts + context usage
312
+ const line1Parts = [];
313
+ line1Parts.push(`💬 ${stats.userMessages} msgs`);
314
+ line1Parts.push(`↑${formatTokenCount(stats.tokens.input)}`);
315
+ line1Parts.push(`↓${formatTokenCount(stats.tokens.output)}`);
316
+ if (contextUsage) {
317
+ const percent = contextUsage.percent !== null ? `${contextUsage.percent.toFixed(1)}%` : "?%";
318
+ const window = formatTokenCount(contextUsage.contextWindow);
319
+ line1Parts.push(`${percent}/${window}`);
320
+ }
321
+ const line1 = `${line1Parts[0]} - ${line1Parts.slice(1).join(" ")}`;
322
+ // Line 2: provider/model • thinking level
323
+ const modelLabel = model ? `${model.provider}/${model.id}` : "default";
324
+ const line2 = `🤖 ${modelLabel} • 💭 ${thinkingLevel ?? "off"}`;
325
+ return `${line1}\n${line2}`;
326
+ }
327
+ return { processMessage, newSession, getSessionStatus };
328
+ }
329
+ /** Format a token count as a compact string: 0, 1.2k, 5.9k, 12k, 1.8M, etc. */
330
+ function formatTokenCount(tokens) {
331
+ if (tokens === 0)
332
+ return "0";
333
+ if (tokens < 1_000)
334
+ return String(tokens);
335
+ if (tokens < 10_000)
336
+ return `${(tokens / 1_000).toFixed(1)}k`;
337
+ if (tokens < 1_000_000)
338
+ return `${Math.round(tokens / 1_000)}k`;
339
+ return `${(tokens / 1_000_000).toFixed(1)}M`;
340
+ }
341
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point — handles launchd service management and foreground run.
4
+ *
5
+ * Usage:
6
+ * pi-imessage Run in foreground
7
+ * pi-imessage install Install + start launchd service (auto-starts on boot)
8
+ * pi-imessage uninstall Stop + remove launchd service
9
+ * pi-imessage start Start the service
10
+ * pi-imessage stop Stop the service
11
+ * pi-imessage restart Restart the service
12
+ * pi-imessage logs Tail service logs
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}