@kingcrab/pi-imessage 0.0.41 → 0.0.43
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 +23 -1
- package/dist/agent.d.ts +57 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +372 -51
- package/dist/agent.js.map +1 -1
- package/dist/main.js +34 -5
- package/dist/main.js.map +1 -1
- package/dist/memory.d.ts +53 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +196 -0
- package/dist/memory.js.map +1 -0
- package/dist/model-health.d.ts +11 -0
- package/dist/model-health.d.ts.map +1 -0
- package/dist/model-health.js +69 -0
- package/dist/model-health.js.map +1 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +5 -1
- package/dist/pipeline.js.map +1 -1
- package/dist/reminders.d.ts +42 -0
- package/dist/reminders.d.ts.map +1 -0
- package/dist/reminders.js +207 -0
- package/dist/reminders.js.map +1 -0
- package/dist/send.d.ts +6 -0
- package/dist/send.d.ts.map +1 -1
- package/dist/send.js +166 -13
- package/dist/send.js.map +1 -1
- package/dist/store.js +1 -1
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/web/index.d.ts +4 -0
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +75 -7
- package/dist/web/index.js.map +1 -1
- package/package.json +6 -17
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import Database from "better-sqlite3";
|
|
5
|
+
export const REMINDER_STATUSES = ["pending", "delivered", "cancelled", "failed"];
|
|
6
|
+
const MAX_TIMER_DELAY_MS = 2_147_000_000;
|
|
7
|
+
const DEFAULT_RETRY_BASE_MS = 30_000;
|
|
8
|
+
const DEFAULT_MAX_ATTEMPTS = 10;
|
|
9
|
+
const EXPLICIT_TIMEZONE_PATTERN = /(Z|[+-]\d{2}:?\d{2})$/i;
|
|
10
|
+
export function parseReminderTime(value) {
|
|
11
|
+
if (!EXPLICIT_TIMEZONE_PATTERN.test(value)) {
|
|
12
|
+
throw new Error("scheduledAt must be ISO 8601 with an explicit timezone, for example 2026-08-08T21:30:00+08:00");
|
|
13
|
+
}
|
|
14
|
+
const timestamp = Date.parse(value);
|
|
15
|
+
if (!Number.isFinite(timestamp))
|
|
16
|
+
throw new Error("scheduledAt is not a valid ISO 8601 timestamp");
|
|
17
|
+
return timestamp;
|
|
18
|
+
}
|
|
19
|
+
function iso(timestamp) {
|
|
20
|
+
return timestamp === null ? null : new Date(timestamp).toISOString();
|
|
21
|
+
}
|
|
22
|
+
function mapRow(row) {
|
|
23
|
+
return {
|
|
24
|
+
id: row.id,
|
|
25
|
+
chatGuid: row.chat_guid,
|
|
26
|
+
text: row.text,
|
|
27
|
+
scheduledAt: new Date(row.scheduled_at).toISOString(),
|
|
28
|
+
status: row.status,
|
|
29
|
+
attempts: row.attempts,
|
|
30
|
+
createdAt: new Date(row.created_at).toISOString(),
|
|
31
|
+
deliveredAt: iso(row.delivered_at),
|
|
32
|
+
cancelledAt: iso(row.cancelled_at),
|
|
33
|
+
lastError: row.last_error,
|
|
34
|
+
idempotencyKey: row.idempotency_key,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function createReminderService(config) {
|
|
38
|
+
const now = config.now ?? Date.now;
|
|
39
|
+
const retryBaseMs = config.retryBaseMs ?? DEFAULT_RETRY_BASE_MS;
|
|
40
|
+
const maxAttempts = config.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
41
|
+
mkdirSync(config.workingDir, { recursive: true });
|
|
42
|
+
const db = new Database(join(config.workingDir, "reminders.db"));
|
|
43
|
+
db.pragma("journal_mode = WAL");
|
|
44
|
+
db.exec(`
|
|
45
|
+
CREATE TABLE IF NOT EXISTS reminders (
|
|
46
|
+
id TEXT PRIMARY KEY,
|
|
47
|
+
chat_guid TEXT NOT NULL,
|
|
48
|
+
text TEXT NOT NULL,
|
|
49
|
+
scheduled_at INTEGER NOT NULL,
|
|
50
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'delivered', 'cancelled', 'failed')),
|
|
51
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
52
|
+
created_at INTEGER NOT NULL,
|
|
53
|
+
delivered_at INTEGER,
|
|
54
|
+
cancelled_at INTEGER,
|
|
55
|
+
last_error TEXT,
|
|
56
|
+
idempotency_key TEXT UNIQUE,
|
|
57
|
+
next_attempt_at INTEGER NOT NULL
|
|
58
|
+
);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS reminders_due_idx ON reminders(status, next_attempt_at);
|
|
60
|
+
`);
|
|
61
|
+
const findById = db.prepare("SELECT * FROM reminders WHERE id = ?");
|
|
62
|
+
const findByIdempotencyKey = db.prepare("SELECT * FROM reminders WHERE idempotency_key = ?");
|
|
63
|
+
const insert = db.prepare(`
|
|
64
|
+
INSERT INTO reminders (
|
|
65
|
+
id, chat_guid, text, scheduled_at, status, attempts, created_at,
|
|
66
|
+
delivered_at, cancelled_at, last_error, idempotency_key, next_attempt_at
|
|
67
|
+
) VALUES (?, ?, ?, ?, 'pending', 0, ?, NULL, NULL, NULL, ?, ?)
|
|
68
|
+
`);
|
|
69
|
+
const listAll = db.prepare("SELECT * FROM reminders ORDER BY scheduled_at ASC, created_at ASC");
|
|
70
|
+
const listByStatus = db.prepare("SELECT * FROM reminders WHERE status = ? ORDER BY scheduled_at ASC, created_at ASC");
|
|
71
|
+
const nextPending = db.prepare("SELECT * FROM reminders WHERE status = 'pending' ORDER BY next_attempt_at ASC, created_at ASC LIMIT 1");
|
|
72
|
+
const duePending = db.prepare("SELECT * FROM reminders WHERE status = 'pending' AND next_attempt_at <= ? ORDER BY next_attempt_at ASC, created_at ASC");
|
|
73
|
+
const incrementAttempt = db.prepare("UPDATE reminders SET attempts = attempts + 1, last_error = NULL WHERE id = ? AND status = 'pending'");
|
|
74
|
+
const markDelivered = db.prepare("UPDATE reminders SET status = 'delivered', delivered_at = ?, last_error = NULL WHERE id = ? AND status = 'pending'");
|
|
75
|
+
const markRetry = db.prepare("UPDATE reminders SET next_attempt_at = ?, last_error = ? WHERE id = ? AND status = 'pending'");
|
|
76
|
+
const markFailed = db.prepare("UPDATE reminders SET status = 'failed', last_error = ? WHERE id = ? AND status = 'pending'");
|
|
77
|
+
const markCancelled = db.prepare("UPDATE reminders SET status = 'cancelled', cancelled_at = ? WHERE id = ? AND status = 'pending'");
|
|
78
|
+
let timer = null;
|
|
79
|
+
let started = false;
|
|
80
|
+
let processing = false;
|
|
81
|
+
let activeRun = null;
|
|
82
|
+
let closed = false;
|
|
83
|
+
function rowById(id) {
|
|
84
|
+
return findById.get(id);
|
|
85
|
+
}
|
|
86
|
+
function clearTimer() {
|
|
87
|
+
if (timer)
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
timer = null;
|
|
90
|
+
}
|
|
91
|
+
function schedule() {
|
|
92
|
+
if (!started || processing)
|
|
93
|
+
return;
|
|
94
|
+
clearTimer();
|
|
95
|
+
const next = nextPending.get();
|
|
96
|
+
if (!next)
|
|
97
|
+
return;
|
|
98
|
+
const delay = Math.min(Math.max(0, next.next_attempt_at - now()), MAX_TIMER_DELAY_MS);
|
|
99
|
+
timer = setTimeout(() => {
|
|
100
|
+
timer = null;
|
|
101
|
+
activeRun = processDue()
|
|
102
|
+
.catch((error) => console.error("[reminder] scheduler error:", error))
|
|
103
|
+
.finally(() => {
|
|
104
|
+
activeRun = null;
|
|
105
|
+
});
|
|
106
|
+
}, delay);
|
|
107
|
+
timer.unref();
|
|
108
|
+
}
|
|
109
|
+
async function processDue() {
|
|
110
|
+
if (!started || processing)
|
|
111
|
+
return;
|
|
112
|
+
processing = true;
|
|
113
|
+
try {
|
|
114
|
+
const rows = duePending.all(now());
|
|
115
|
+
for (const row of rows) {
|
|
116
|
+
if (!started)
|
|
117
|
+
break;
|
|
118
|
+
incrementAttempt.run(row.id);
|
|
119
|
+
const current = rowById(row.id);
|
|
120
|
+
if (!current || current.status !== "pending")
|
|
121
|
+
continue;
|
|
122
|
+
const reminder = mapRow(current);
|
|
123
|
+
try {
|
|
124
|
+
await config.deliver(reminder);
|
|
125
|
+
markDelivered.run(now(), row.id);
|
|
126
|
+
console.log(`[reminder] delivered ${row.id} to ${row.chat_guid}`);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
130
|
+
if (current.attempts >= maxAttempts) {
|
|
131
|
+
markFailed.run(message, row.id);
|
|
132
|
+
console.error(`[reminder] permanently failed ${row.id} after ${current.attempts} attempts: ${message}`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const retryDelay = Math.min(retryBaseMs * 2 ** Math.max(0, current.attempts - 1), 60 * 60 * 1000);
|
|
136
|
+
markRetry.run(now() + retryDelay, message, row.id);
|
|
137
|
+
console.warn(`[reminder] delivery failed ${row.id}; retrying in ${retryDelay}ms: ${message}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
processing = false;
|
|
144
|
+
schedule();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
start() {
|
|
149
|
+
if (started)
|
|
150
|
+
return;
|
|
151
|
+
if (closed)
|
|
152
|
+
throw new Error("reminder service is closed");
|
|
153
|
+
started = true;
|
|
154
|
+
console.log(`[reminder] scheduler started (${join(config.workingDir, "reminders.db")})`);
|
|
155
|
+
schedule();
|
|
156
|
+
},
|
|
157
|
+
async stop() {
|
|
158
|
+
if (closed)
|
|
159
|
+
return;
|
|
160
|
+
started = false;
|
|
161
|
+
clearTimer();
|
|
162
|
+
await activeRun;
|
|
163
|
+
db.close();
|
|
164
|
+
closed = true;
|
|
165
|
+
},
|
|
166
|
+
create(input) {
|
|
167
|
+
const chatGuid = input.chatGuid.trim();
|
|
168
|
+
const text = input.text.trim();
|
|
169
|
+
const idempotencyKey = input.idempotencyKey?.trim() || null;
|
|
170
|
+
if (!chatGuid)
|
|
171
|
+
throw new Error("chatGuid is required");
|
|
172
|
+
if (!text)
|
|
173
|
+
throw new Error("text is required");
|
|
174
|
+
const scheduledAt = parseReminderTime(input.scheduledAt);
|
|
175
|
+
if (idempotencyKey) {
|
|
176
|
+
const existing = findByIdempotencyKey.get(idempotencyKey);
|
|
177
|
+
if (existing) {
|
|
178
|
+
if (existing.chat_guid !== chatGuid || existing.text !== text || existing.scheduled_at !== scheduledAt) {
|
|
179
|
+
throw new Error("idempotencyKey already exists with different reminder data");
|
|
180
|
+
}
|
|
181
|
+
return { reminder: mapRow(existing), created: false };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const id = randomUUID();
|
|
185
|
+
const createdAt = now();
|
|
186
|
+
insert.run(id, chatGuid, text, scheduledAt, createdAt, idempotencyKey, scheduledAt);
|
|
187
|
+
const reminder = mapRow(rowById(id));
|
|
188
|
+
console.log(`[reminder] scheduled ${id} for ${reminder.scheduledAt} to ${chatGuid}`);
|
|
189
|
+
schedule();
|
|
190
|
+
return { reminder, created: true };
|
|
191
|
+
},
|
|
192
|
+
list(status) {
|
|
193
|
+
const rows = status ? listByStatus.all(status) : listAll.all();
|
|
194
|
+
return rows.map(mapRow);
|
|
195
|
+
},
|
|
196
|
+
cancel(id) {
|
|
197
|
+
const result = markCancelled.run(now(), id);
|
|
198
|
+
if (result.changes === 0)
|
|
199
|
+
return null;
|
|
200
|
+
const reminder = mapRow(rowById(id));
|
|
201
|
+
console.log(`[reminder] cancelled ${id}`);
|
|
202
|
+
schedule();
|
|
203
|
+
return reminder;
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=reminders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reminders.js","sourceRoot":"","sources":["../src/reminders.ts"],"names":[],"mappings":"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"}
|
package/dist/send.d.ts
CHANGED
|
@@ -7,12 +7,18 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Supports DM (buddy), group chat (chat id), and SMS targets.
|
|
9
9
|
* Check Messages.app environment before first send with checkEnvironment().
|
|
10
|
+
*
|
|
11
|
+
* Attachment sends stage the file into ~/Library/Messages/Attachments/pi-imessage/
|
|
12
|
+
* because Messages.app's imagent helper is sandboxed and cannot read arbitrary
|
|
13
|
+
* paths (e.g. ~/.pi/..., ~/dotfile/...); staged copies are then verified against
|
|
14
|
+
* chat.db so we surface real failures instead of trusting AppleScript's ack.
|
|
10
15
|
*/
|
|
11
16
|
import type { RichTextSettings } from "./settings.js";
|
|
12
17
|
/** Check Messages.app is running and iMessage is signed in. */
|
|
13
18
|
export declare function checkEnvironment(): Promise<void>;
|
|
14
19
|
export interface MessageSender {
|
|
15
20
|
sendMessage(chatGuid: string, text: string, richText?: RichTextSettings): Promise<void>;
|
|
21
|
+
sendAttachment(chatGuid: string, filePath: string): Promise<void>;
|
|
16
22
|
}
|
|
17
23
|
export declare function createMessageSender(): MessageSender;
|
|
18
24
|
//# sourceMappingURL=send.d.ts.map
|
package/dist/send.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA2LtD,+DAA+D;AAC/D,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA4CtD;AAID,MAAM,WAAW,aAAa;IAC7B,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAqDnD"}
|
package/dist/send.js
CHANGED
|
@@ -7,19 +7,33 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Supports DM (buddy), group chat (chat id), and SMS targets.
|
|
9
9
|
* Check Messages.app environment before first send with checkEnvironment().
|
|
10
|
+
*
|
|
11
|
+
* Attachment sends stage the file into ~/Library/Messages/Attachments/pi-imessage/
|
|
12
|
+
* because Messages.app's imagent helper is sandboxed and cannot read arbitrary
|
|
13
|
+
* paths (e.g. ~/.pi/..., ~/dotfile/...); staged copies are then verified against
|
|
14
|
+
* chat.db so we surface real failures instead of trusting AppleScript's ack.
|
|
10
15
|
*/
|
|
11
16
|
import { execFile } from "node:child_process";
|
|
17
|
+
import { randomUUID } from "node:crypto";
|
|
12
18
|
import { constants, accessSync } from "node:fs";
|
|
19
|
+
import { copyFile, mkdir, unlink } from "node:fs/promises";
|
|
13
20
|
import { homedir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
21
|
+
import { basename, extname, join } from "node:path";
|
|
15
22
|
import { promisify } from "node:util";
|
|
16
23
|
import { sendRichTextMessage } from "./rich-text.js";
|
|
17
24
|
const execFileAsync = promisify(execFile);
|
|
18
25
|
const SCRIPT_TIMEOUT_MS = 30_000;
|
|
26
|
+
const ATTACHMENT_VERIFY_TIMEOUT_MS = 30_000;
|
|
27
|
+
const ATTACHMENT_VERIFY_POLL_MS = 500;
|
|
28
|
+
const MESSAGES_APP_PATH = "/System/Applications/Messages.app";
|
|
29
|
+
const ATTACHMENTS_ROOT = join(homedir(), "Library", "Messages", "Attachments");
|
|
30
|
+
const STAGING_DIR = join(ATTACHMENTS_ROOT, "pi-imessage");
|
|
31
|
+
const CHAT_DB_PATH = join(homedir(), "Library", "Messages", "chat.db");
|
|
19
32
|
// ── AppleScript helpers ───────────────────────────────────────────────────────
|
|
20
33
|
/** Escape special characters for AppleScript string literals. */
|
|
21
34
|
function escapeAppleScript(str) {
|
|
22
35
|
return str
|
|
36
|
+
.replace(/\0/g, "�")
|
|
23
37
|
.replace(/\\/g, "\\\\")
|
|
24
38
|
.replace(/"/g, '\\"')
|
|
25
39
|
.replace(/\n/g, "\\n")
|
|
@@ -40,18 +54,132 @@ function buildSendScript(chatGuid, text) {
|
|
|
40
54
|
const isGroup = parts[1] === "+";
|
|
41
55
|
if (isGroup) {
|
|
42
56
|
const escapedChatId = escapeAppleScript(chatGuid);
|
|
43
|
-
return `tell application "
|
|
57
|
+
return `tell application "${MESSAGES_APP_PATH}"
|
|
44
58
|
set targetChat to chat id "${escapedChatId}"
|
|
45
59
|
send "${escapedText}" to targetChat
|
|
46
60
|
end tell`;
|
|
47
61
|
}
|
|
48
62
|
const recipient = escapeAppleScript(parts[2] ?? "");
|
|
49
|
-
return `tell application "
|
|
63
|
+
return `tell application "${MESSAGES_APP_PATH}"
|
|
50
64
|
set targetService to 1st service whose service type = iMessage
|
|
51
65
|
set targetBuddy to buddy "${recipient}" of targetService
|
|
52
66
|
send "${escapedText}" to targetBuddy
|
|
53
67
|
end tell`;
|
|
54
68
|
}
|
|
69
|
+
/** Build AppleScript for sending a local file attachment. */
|
|
70
|
+
function buildSendAttachmentScript(chatGuid, filePath) {
|
|
71
|
+
const escapedPath = escapeAppleScript(filePath);
|
|
72
|
+
const parts = chatGuid.split(";");
|
|
73
|
+
const isGroup = parts[1] === "+";
|
|
74
|
+
if (isGroup) {
|
|
75
|
+
const escapedChatId = escapeAppleScript(chatGuid);
|
|
76
|
+
return `tell application "${MESSAGES_APP_PATH}"
|
|
77
|
+
set targetChat to chat id "${escapedChatId}"
|
|
78
|
+
send POSIX file "${escapedPath}" to targetChat
|
|
79
|
+
end tell`;
|
|
80
|
+
}
|
|
81
|
+
const recipient = escapeAppleScript(parts[2] ?? "");
|
|
82
|
+
return `tell application "${MESSAGES_APP_PATH}"
|
|
83
|
+
set targetService to 1st service whose service type = iMessage
|
|
84
|
+
set targetBuddy to buddy "${recipient}" of targetService
|
|
85
|
+
send POSIX file "${escapedPath}" to targetBuddy
|
|
86
|
+
end tell`;
|
|
87
|
+
}
|
|
88
|
+
// ── Attachment staging & verification ─────────────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* Copy an attachment into a location the sandboxed imagent process is allowed
|
|
91
|
+
* to read. Paths under ~/Library/Messages/Attachments/ are proven-good; paths
|
|
92
|
+
* under ~/.pi/... or ~/dotfile/... get rejected by TCC (Operation not permitted),
|
|
93
|
+
* which shows up as transfer_state=6 / is_sent=0 in chat.db.
|
|
94
|
+
*
|
|
95
|
+
* Returns the staged path; caller is responsible for cleanup after send.
|
|
96
|
+
*/
|
|
97
|
+
async function stageAttachment(sourcePath) {
|
|
98
|
+
// If the source is already inside the Attachments root, imagent can read it.
|
|
99
|
+
if (sourcePath.startsWith(`${ATTACHMENTS_ROOT}/`)) {
|
|
100
|
+
return { stagedPath: sourcePath, cleanup: async () => { } };
|
|
101
|
+
}
|
|
102
|
+
await mkdir(STAGING_DIR, { recursive: true, mode: 0o755 });
|
|
103
|
+
const ext = extname(sourcePath);
|
|
104
|
+
const base = basename(sourcePath, ext)
|
|
105
|
+
.replace(/[^A-Za-z0-9._-]/g, "_")
|
|
106
|
+
.slice(0, 40);
|
|
107
|
+
const stagedPath = join(STAGING_DIR, `${Date.now()}-${randomUUID().slice(0, 8)}-${base}${ext}`);
|
|
108
|
+
await copyFile(sourcePath, stagedPath);
|
|
109
|
+
return {
|
|
110
|
+
stagedPath,
|
|
111
|
+
cleanup: async () => {
|
|
112
|
+
try {
|
|
113
|
+
await unlink(stagedPath);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// best-effort; Messages may still hold a handle
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Poll chat.db until the staged attachment finishes transferring (or times out). */
|
|
122
|
+
async function verifyAttachmentSent(stagedPath, timeoutMs) {
|
|
123
|
+
const stagedBase = basename(stagedPath);
|
|
124
|
+
// filename in chat.db can be stored as absolute path or "~/Library/Messages/Attachments/...",
|
|
125
|
+
// so match on the unique basename we generated (Date.now() + UUID prefix).
|
|
126
|
+
const sql = `SELECT a.ROWID AS attachment_id, a.transfer_state, m.is_sent, m.error
|
|
127
|
+
FROM attachment a
|
|
128
|
+
LEFT JOIN message_attachment_join j ON j.attachment_id = a.ROWID
|
|
129
|
+
LEFT JOIN message m ON m.ROWID = j.message_id
|
|
130
|
+
WHERE a.filename LIKE '%${stagedBase.replace(/'/g, "''")}'
|
|
131
|
+
ORDER BY a.ROWID DESC
|
|
132
|
+
LIMIT 1;`;
|
|
133
|
+
const deadline = Date.now() + timeoutMs;
|
|
134
|
+
let last = { attachmentId: null, transferState: null, isSent: null, error: null };
|
|
135
|
+
while (Date.now() < deadline) {
|
|
136
|
+
try {
|
|
137
|
+
const { stdout } = await execFileAsync("sqlite3", ["-json", CHAT_DB_PATH, sql], { timeout: 5_000 });
|
|
138
|
+
const rows = stdout.trim() ? JSON.parse(stdout) : [];
|
|
139
|
+
const row = rows[0];
|
|
140
|
+
if (row) {
|
|
141
|
+
last = {
|
|
142
|
+
attachmentId: row.attachment_id ?? null,
|
|
143
|
+
transferState: row.transfer_state ?? null,
|
|
144
|
+
isSent: row.is_sent ?? null,
|
|
145
|
+
error: row.error ?? null,
|
|
146
|
+
};
|
|
147
|
+
// transfer_state: 5 = transferred, 6 = failed, other = in-progress/pending
|
|
148
|
+
if (last.transferState === 5 && last.isSent === 1) {
|
|
149
|
+
return {
|
|
150
|
+
ok: true,
|
|
151
|
+
detail: `attachment_id=${last.attachmentId} transfer_state=5 is_sent=1`,
|
|
152
|
+
...last,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (last.transferState === 6) {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
detail: `imagent rejected file (transfer_state=6, is_sent=${last.isSent}, error=${last.error}) — likely TCC/sandbox denial`,
|
|
159
|
+
...last,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (last.error && last.error !== 0) {
|
|
163
|
+
return {
|
|
164
|
+
ok: false,
|
|
165
|
+
detail: `message error=${last.error} transfer_state=${last.transferState} is_sent=${last.isSent}`,
|
|
166
|
+
...last,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
// ignore transient sqlite lock errors; try again
|
|
173
|
+
void err;
|
|
174
|
+
}
|
|
175
|
+
await new Promise((r) => setTimeout(r, ATTACHMENT_VERIFY_POLL_MS));
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
ok: false,
|
|
179
|
+
detail: `timeout after ${timeoutMs}ms (attachment_id=${last.attachmentId} transfer_state=${last.transferState} is_sent=${last.isSent} error=${last.error})`,
|
|
180
|
+
...last,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
55
183
|
// ── Environment check ─────────────────────────────────────────────────────────
|
|
56
184
|
/** Check Messages.app is running and iMessage is signed in. */
|
|
57
185
|
export async function checkEnvironment() {
|
|
@@ -63,15 +191,14 @@ export async function checkEnvironment() {
|
|
|
63
191
|
throw new Error("Messages.app is not running");
|
|
64
192
|
}
|
|
65
193
|
// 2. Check Full Disk Access (required to read chat.db)
|
|
66
|
-
const chatDbPath = join(homedir(), "Library", "Messages", "chat.db");
|
|
67
194
|
try {
|
|
68
|
-
accessSync(
|
|
195
|
+
accessSync(CHAT_DB_PATH, constants.R_OK);
|
|
69
196
|
}
|
|
70
197
|
catch {
|
|
71
|
-
throw new Error(`Cannot read ${
|
|
198
|
+
throw new Error(`Cannot read ${CHAT_DB_PATH} — grant Full Disk Access to your terminal in System Settings > Privacy & Security > Full Disk Access`);
|
|
72
199
|
}
|
|
73
200
|
// 3. Check iMessage has active accounts
|
|
74
|
-
const script = `tell application "
|
|
201
|
+
const script = `tell application "${MESSAGES_APP_PATH}"
|
|
75
202
|
try
|
|
76
203
|
set accountList to every account
|
|
77
204
|
if (count of accountList) is 0 then return "no_accounts"
|
|
@@ -79,21 +206,19 @@ export async function checkEnvironment() {
|
|
|
79
206
|
if enabled of acct is true then return "active"
|
|
80
207
|
end repeat
|
|
81
208
|
return "inactive"
|
|
82
|
-
on error
|
|
83
|
-
return "error"
|
|
209
|
+
on error errorMessage number errorNumber
|
|
210
|
+
return "error " & errorNumber & ": " & errorMessage
|
|
84
211
|
end try
|
|
85
212
|
end tell`;
|
|
86
213
|
try {
|
|
87
214
|
const { stdout } = await execFileAsync("osascript", ["-e", script], { timeout: 5_000 });
|
|
88
215
|
const status = stdout.trim();
|
|
89
216
|
if (status !== "active") {
|
|
90
|
-
|
|
217
|
+
console.warn(`[send] iMessage account status check returned ${status}; continuing so the watchdog can diagnose send failures`);
|
|
91
218
|
}
|
|
92
219
|
}
|
|
93
220
|
catch (error) {
|
|
94
|
-
|
|
95
|
-
throw error;
|
|
96
|
-
throw new Error(`Failed to check iMessage status: ${error instanceof Error ? error.message : String(error)}`);
|
|
221
|
+
console.warn(`[send] failed to check iMessage status; continuing so the watchdog can diagnose send failures: ${error instanceof Error ? error.message : String(error)}`);
|
|
97
222
|
}
|
|
98
223
|
}
|
|
99
224
|
export function createMessageSender() {
|
|
@@ -111,6 +236,34 @@ export function createMessageSender() {
|
|
|
111
236
|
await execFileAsync("osascript", ["-e", script], { timeout: SCRIPT_TIMEOUT_MS });
|
|
112
237
|
console.log(`[send] sent to ${chatGuid} mode=${mode} duration_ms=${Date.now() - startTime}: "${text.substring(0, 60)}"`);
|
|
113
238
|
},
|
|
239
|
+
async sendAttachment(chatGuid, filePath) {
|
|
240
|
+
const startTime = Date.now();
|
|
241
|
+
accessSync(filePath, constants.R_OK);
|
|
242
|
+
const origName = basename(filePath);
|
|
243
|
+
console.log(`[send] start: ${chatGuid} mode=attachment file=${origName}`);
|
|
244
|
+
const { stagedPath, cleanup } = await stageAttachment(filePath);
|
|
245
|
+
const staged = stagedPath !== filePath;
|
|
246
|
+
if (staged) {
|
|
247
|
+
console.log(`[send] staged attachment for imagent: ${basename(stagedPath)}`);
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const script = buildSendAttachmentScript(chatGuid, stagedPath);
|
|
251
|
+
await execFileAsync("osascript", ["-e", script], { timeout: SCRIPT_TIMEOUT_MS });
|
|
252
|
+
const status = await verifyAttachmentSent(stagedPath, ATTACHMENT_VERIFY_TIMEOUT_MS);
|
|
253
|
+
if (!status.ok) {
|
|
254
|
+
throw new Error(`attachment send failed for ${origName}: ${status.detail}`);
|
|
255
|
+
}
|
|
256
|
+
console.log(`[send] sent attachment to ${chatGuid} duration_ms=${Date.now() - startTime}: "${origName}" (${status.detail})`);
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
if (staged) {
|
|
260
|
+
// Give Messages a moment to fully ingest before removing the staged copy.
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
cleanup().catch(() => { });
|
|
263
|
+
}, 60_000).unref();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
114
267
|
};
|
|
115
268
|
}
|
|
116
269
|
//# sourceMappingURL=send.js.map
|
package/dist/send.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"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"}
|
package/dist/store.js
CHANGED
|
@@ -110,7 +110,7 @@ export function createChatStore(config) {
|
|
|
110
110
|
}
|
|
111
111
|
if (records.length > 0) {
|
|
112
112
|
const indexPath = join(chatDir(chatGuid), "images", "index.jsonl");
|
|
113
|
-
await appendFile(indexPath, records.map((record) => JSON.stringify(record)).join("\n")
|
|
113
|
+
await appendFile(indexPath, `${records.map((record) => JSON.stringify(record)).join("\n")}\n`, "utf-8");
|
|
114
114
|
}
|
|
115
115
|
return records;
|
|
116
116
|
}
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAyBpD,iFAAiF;AAEjF,2FAA2F;AAC3F,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC3C,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IACnD,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAU;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,YAAY,CAAC,QAAuB,EAAE,IAAY;IAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,QAAQ,QAAQ,EAAE,CAAC;QAClB,KAAK,YAAY;YAChB,OAAO,MAAM,CAAC;QACf,KAAK,WAAW;YACf,OAAO,MAAM,CAAC;QACf,KAAK,WAAW;YACf,OAAO,MAAM,CAAC;QACf,KAAK,YAAY;YAChB,OAAO,OAAO,CAAC;QAChB,KAAK,YAAY;YAChB,OAAO,OAAO,CAAC;QAChB,KAAK,YAAY;YAChB,OAAO,OAAO,CAAC;QAChB;YACC,OAAO,MAAM,CAAC;IAChB,CAAC;AACF,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;AAC3E,CAAC;AA0BD,MAAM,UAAU,eAAe,CAAC,MAAuB;IACtD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAE9B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,SAAS,OAAO,CAAC,QAAgB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,SAAS,OAAO,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,UAAU,MAAM,CAAC,QAAgB,EAAE,OAAgB;QACvD,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,QAAyB;QACvE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QACxD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzC,MAAM,OAAO,GAA0B,EAAE,CAAC;QAC1C,KAAK,MAAM,UAAU,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC/C,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEzD,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC;YACrC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC;YACpH,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAClC,MAAM,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;YAClD,CAAC;YAED,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;YACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YAC3D,UAAU,CAAC,IAAI,GAAG,eAAe,CAAC;YAElC,OAAO,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,GAAG;gBACH,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,QAAQ;gBACR,YAAY;gBACZ,YAAY;gBACZ,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,MAAM;gBACN,SAAS;gBACT,IAAI,EAAE,QAAQ,CAAC,IAAI;aACnB,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YACnE,MAAM,UAAU,CAAC,SAAS,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzG,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,OAAO;QACN,KAAK,CAAC,GAAG,CAAC,QAAgB,EAAE,OAA8B;YACzD,MAAM,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,aAAa;KACb,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,CAAC;AAIvD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,WAAW,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAGvD;AAED,gDAAgD;AAChD,MAAM,WAAW,UAAU;IAC1B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qEAAqE;IACrE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,sFAAsF;IACtF,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAID,gFAAgF;AAChF,MAAM,MAAM,UAAU,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAI5F,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAY1D;AAID,mDAAmD;AACnD,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;CACxB;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD"}
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Web server: serves the chat log UI, logs page, and API endpoints. */
|
|
2
2
|
import type { AgentManager } from "../agent.js";
|
|
3
|
+
import type { ModelHealthChecker } from "../model-health.js";
|
|
4
|
+
import { type ReminderService } from "../reminders.js";
|
|
3
5
|
import type { SelfEchoFilter } from "../self-echo.js";
|
|
4
6
|
import type { MessageSender } from "../send.js";
|
|
5
7
|
import type { Settings } from "../settings.js";
|
|
@@ -12,6 +14,8 @@ export interface WebServerConfig {
|
|
|
12
14
|
sender: MessageSender;
|
|
13
15
|
echoFilter: SelfEchoFilter;
|
|
14
16
|
agent: AgentManager;
|
|
17
|
+
checkModelHealth: ModelHealthChecker;
|
|
18
|
+
reminders: ReminderService;
|
|
15
19
|
}
|
|
16
20
|
export interface WebServer {
|
|
17
21
|
start(): void;
|
package/dist/web/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAKxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAKxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAqB,KAAK,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,YAAY,CAAC;IACpB,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,SAAS,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAgDD,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAySlE"}
|