@kingcrab/pi-imessage 0.0.41 → 0.0.42

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/dist/main.js CHANGED
@@ -7,6 +7,7 @@ import { join } from "node:path";
7
7
  import { createAgentManager } from "./agent.js";
8
8
  import { createIMessageBot } from "./imessage.js";
9
9
  import { createAppLogger, createDigestLogger } from "./logger.js";
10
+ import { createModelHealthChecker } from "./model-health.js";
10
11
  import { createAsyncQueue } from "./queue.js";
11
12
  import { createSelfEchoFilter } from "./self-echo.js";
12
13
  import { checkEnvironment, createMessageSender } from "./send.js";
@@ -29,12 +30,23 @@ async function main() {
29
30
  const getSettings = () => readSettings(workingDir);
30
31
  const setSettings = (updated) => writeSettings(workingDir, updated);
31
32
  const agent = await createAgentManager({ workingDir });
33
+ const checkModelHealth = createModelHealthChecker(workingDir);
32
34
  const store = createChatStore({ workingDir });
33
35
  const queue = createAsyncQueue(join(workingDir, "queue.json"));
34
36
  const watcher = createWatcher({ queue });
35
37
  const bot = createIMessageBot({ queue, agent, sender, echoFilter, store, getSettings, digestLogger });
36
38
  const web = webEnabled
37
- ? createWebServer({ workingDir, host: webHost, port: webPort, getSettings, setSettings, sender, echoFilter, agent })
39
+ ? createWebServer({
40
+ workingDir,
41
+ host: webHost,
42
+ port: webPort,
43
+ getSettings,
44
+ setSettings,
45
+ sender,
46
+ echoFilter,
47
+ agent,
48
+ checkModelHealth,
49
+ })
38
50
  : null;
39
51
  console.log(`[sid] workspace: ${workingDir}`);
40
52
  watcher.start();
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export declare const MEMORY_KINDS: readonly ["fact", "event", "preference", "procedure"];
2
+ export type MemoryKind = (typeof MEMORY_KINDS)[number];
3
+ export interface MemorySource {
4
+ type: string;
5
+ label: string;
6
+ path?: string;
7
+ line_start?: number;
8
+ line_end?: number;
9
+ block_hash?: string;
10
+ }
11
+ export interface StructuredMemoryItem {
12
+ id: string;
13
+ text: string;
14
+ namespace: string;
15
+ kind: MemoryKind;
16
+ subjects: string[];
17
+ event_time: string | null;
18
+ sources: MemorySource[];
19
+ importance: number;
20
+ confidence: number;
21
+ status: "active" | "superseded";
22
+ created_at: string;
23
+ supersedes_id?: string;
24
+ }
25
+ export interface SaveMemoryInput {
26
+ text: string;
27
+ namespace: string;
28
+ kind: MemoryKind;
29
+ subjects: string[];
30
+ event_time: string | null;
31
+ source: string;
32
+ importance: number;
33
+ confidence: number;
34
+ supersedes_id?: string;
35
+ }
36
+ export declare function readCoreMemory(workingDir: string): string;
37
+ export declare function listMemoryNamespaces(workingDir: string): Array<{
38
+ namespace: string;
39
+ total: number;
40
+ active: number;
41
+ }>;
42
+ export declare function loadAllMemoryItems(workingDir: string): StructuredMemoryItem[];
43
+ export declare function activeMemoryItems(items: StructuredMemoryItem[]): StructuredMemoryItem[];
44
+ export declare function loadMemoryNamespaces(workingDir: string, namespaces: string[]): StructuredMemoryItem[];
45
+ export declare function searchMemory(workingDir: string, query: string, options?: {
46
+ namespaces?: string[];
47
+ limit?: number;
48
+ }): StructuredMemoryItem[];
49
+ export declare function saveMemory(workingDir: string, input: SaveMemoryInput): Promise<{
50
+ added: boolean;
51
+ item: StructuredMemoryItem;
52
+ }>;
53
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,uDAAwD,CAAC;AAClF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,YAAY,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAgDD,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CASzD;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CASpH;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAE7E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CAKvF;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAIrG;AAED,wBAAgB,YAAY,CAC3B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,oBAAoB,EAAE,CAqBxB;AA8CD,wBAAsB,UAAU,CAC/B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,eAAe,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,CAAC,CA2CzD"}
package/dist/memory.js ADDED
@@ -0,0 +1,196 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
3
+ import { appendFile, mkdir, rmdir } from "node:fs/promises";
4
+ import { dirname, join, relative, sep } from "node:path";
5
+ export const MEMORY_KINDS = ["fact", "event", "preference", "procedure"];
6
+ const NAMESPACE_PATTERN = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-]*)+$/;
7
+ function memoryRoot(workingDir) {
8
+ return join(workingDir, "skills", "file-memory");
9
+ }
10
+ function namespaceRoot(workingDir) {
11
+ return join(memoryRoot(workingDir), "namespaces");
12
+ }
13
+ function namespacePath(workingDir, namespace) {
14
+ if (!NAMESPACE_PATTERN.test(namespace))
15
+ throw new Error(`Invalid memory namespace: ${namespace}`);
16
+ return `${join(namespaceRoot(workingDir), ...namespace.split("/"))}.jsonl`;
17
+ }
18
+ function findJsonlFiles(root) {
19
+ if (!existsSync(root))
20
+ return [];
21
+ const result = [];
22
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
23
+ const path = join(root, entry.name);
24
+ if (entry.isDirectory())
25
+ result.push(...findJsonlFiles(path));
26
+ else if (entry.isFile() && entry.name.endsWith(".jsonl"))
27
+ result.push(path);
28
+ }
29
+ return result.sort();
30
+ }
31
+ function namespaceFromPath(workingDir, path) {
32
+ return relative(namespaceRoot(workingDir), path)
33
+ .replaceAll(sep, "/")
34
+ .replace(/\.jsonl$/, "");
35
+ }
36
+ function parseJsonl(path) {
37
+ if (!existsSync(path))
38
+ return [];
39
+ const items = [];
40
+ for (const [index, raw] of readFileSync(path, "utf8").split("\n").entries()) {
41
+ if (!raw.trim())
42
+ continue;
43
+ try {
44
+ items.push(JSON.parse(raw));
45
+ }
46
+ catch (error) {
47
+ throw new Error(`Invalid memory JSONL ${path}:${index + 1}: ${error}`);
48
+ }
49
+ }
50
+ return items;
51
+ }
52
+ export function readCoreMemory(workingDir) {
53
+ const path = join(memoryRoot(workingDir), "core.md");
54
+ if (!existsSync(path))
55
+ return "(no core memory yet)";
56
+ try {
57
+ return readFileSync(path, "utf8").trim() || "(no core memory yet)";
58
+ }
59
+ catch (error) {
60
+ console.warn(`[memory] failed to read core memory: ${error}`);
61
+ return "(core memory unavailable)";
62
+ }
63
+ }
64
+ export function listMemoryNamespaces(workingDir) {
65
+ return findJsonlFiles(namespaceRoot(workingDir)).map((path) => {
66
+ const items = parseJsonl(path);
67
+ return {
68
+ namespace: namespaceFromPath(workingDir, path),
69
+ total: items.length,
70
+ active: activeMemoryItems(items).length,
71
+ };
72
+ });
73
+ }
74
+ export function loadAllMemoryItems(workingDir) {
75
+ return findJsonlFiles(namespaceRoot(workingDir)).flatMap(parseJsonl);
76
+ }
77
+ export function activeMemoryItems(items) {
78
+ const supersededIds = new Set(items.filter((item) => item.status === "active" && item.supersedes_id).map((item) => item.supersedes_id));
79
+ return items.filter((item) => item.status === "active" && !supersededIds.has(item.id));
80
+ }
81
+ export function loadMemoryNamespaces(workingDir, namespaces) {
82
+ const selected = new Set(namespaces);
83
+ for (const namespace of selected)
84
+ namespacePath(workingDir, namespace);
85
+ return activeMemoryItems(loadAllMemoryItems(workingDir)).filter((item) => selected.has(item.namespace));
86
+ }
87
+ export function searchMemory(workingDir, query, options = {}) {
88
+ const terms = query
89
+ .toLowerCase()
90
+ .split(/[\s,,、]+/)
91
+ .filter(Boolean);
92
+ const selected = options.namespaces ? new Set(options.namespaces) : undefined;
93
+ const matches = activeMemoryItems(loadAllMemoryItems(workingDir))
94
+ .filter((item) => !selected || selected.has(item.namespace))
95
+ .map((item) => {
96
+ const haystack = [item.text, item.namespace, item.kind, ...item.subjects].join(" ").toLowerCase();
97
+ const lexical = terms.filter((term) => haystack.includes(term)).length;
98
+ return { item, lexical };
99
+ })
100
+ .filter(({ lexical }) => terms.length === 0 || lexical > 0)
101
+ .sort((a, b) => b.lexical - a.lexical ||
102
+ b.item.importance - a.item.importance ||
103
+ (b.item.event_time ?? "").localeCompare(a.item.event_time ?? ""));
104
+ return matches.slice(0, options.limit ?? 10).map(({ item }) => item);
105
+ }
106
+ function validateSaveInput(input) {
107
+ if (!input.text.trim())
108
+ throw new Error("Memory text must not be empty");
109
+ if (!NAMESPACE_PATTERN.test(input.namespace))
110
+ throw new Error(`Invalid memory namespace: ${input.namespace}`);
111
+ if (!MEMORY_KINDS.includes(input.kind))
112
+ throw new Error(`Invalid memory kind: ${input.kind}`);
113
+ if (input.event_time !== null && !/^\d{4}-\d{2}-\d{2}$/.test(input.event_time)) {
114
+ throw new Error("event_time must be YYYY-MM-DD or null");
115
+ }
116
+ if (!input.source.trim())
117
+ throw new Error("Memory source must not be empty");
118
+ if (input.importance < 0 || input.importance > 1 || input.confidence < 0 || input.confidence > 1) {
119
+ throw new Error("importance and confidence must be between 0 and 1");
120
+ }
121
+ }
122
+ function stableKey(input) {
123
+ return JSON.stringify({
124
+ text: input.text.trim().replace(/\s+/g, " "),
125
+ namespace: input.namespace,
126
+ kind: input.kind,
127
+ subjects: [...new Set(input.subjects.map((subject) => subject.trim()).filter(Boolean))].sort(),
128
+ event_time: input.event_time,
129
+ supersedes_id: input.supersedes_id,
130
+ });
131
+ }
132
+ async function withWriteLock(workingDir, operation) {
133
+ const lockPath = join(memoryRoot(workingDir), ".write-lock");
134
+ const deadline = Date.now() + 5_000;
135
+ while (true) {
136
+ try {
137
+ await mkdir(lockPath);
138
+ break;
139
+ }
140
+ catch (error) {
141
+ if (error.code !== "EEXIST")
142
+ throw error;
143
+ if (Date.now() >= deadline)
144
+ throw new Error("Timed out waiting for memory write lock");
145
+ await new Promise((resolve) => setTimeout(resolve, 50));
146
+ }
147
+ }
148
+ try {
149
+ return await operation();
150
+ }
151
+ finally {
152
+ await rmdir(lockPath).catch(() => { });
153
+ }
154
+ }
155
+ export async function saveMemory(workingDir, input) {
156
+ validateSaveInput(input);
157
+ return withWriteLock(workingDir, async () => {
158
+ const existing = loadAllMemoryItems(workingDir);
159
+ const ids = new Set(existing.map((item) => item.id));
160
+ if (input.supersedes_id && !ids.has(input.supersedes_id)) {
161
+ throw new Error(`Unknown supersedes_id: ${input.supersedes_id}`);
162
+ }
163
+ const normalized = stableKey(input);
164
+ const id = `mem_${createHash("sha256").update(normalized).digest("hex").slice(0, 16)}`;
165
+ const duplicate = existing.find((item) => item.id === id ||
166
+ stableKey({
167
+ text: item.text,
168
+ namespace: item.namespace,
169
+ kind: item.kind,
170
+ subjects: item.subjects,
171
+ event_time: item.event_time,
172
+ supersedes_id: item.supersedes_id,
173
+ }) === normalized);
174
+ if (duplicate)
175
+ return { added: false, item: duplicate };
176
+ const item = {
177
+ id,
178
+ text: input.text.trim(),
179
+ namespace: input.namespace,
180
+ kind: input.kind,
181
+ subjects: [...new Set(input.subjects.map((subject) => subject.trim()).filter(Boolean))].sort(),
182
+ event_time: input.event_time,
183
+ sources: [{ type: "chat", label: input.source.trim() }],
184
+ importance: input.importance,
185
+ confidence: input.confidence,
186
+ status: "active",
187
+ created_at: new Date().toISOString(),
188
+ ...(input.supersedes_id ? { supersedes_id: input.supersedes_id } : {}),
189
+ };
190
+ const path = namespacePath(workingDir, input.namespace);
191
+ await mkdir(dirname(path), { recursive: true });
192
+ await appendFile(path, `${JSON.stringify(item)}\n`, "utf8");
193
+ return { added: true, item };
194
+ });
195
+ }
196
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** Lightweight live check for the currently configured default AI model. */
2
+ export interface ModelHealthResult {
3
+ ok: boolean;
4
+ model: string | null;
5
+ latencyMs: number;
6
+ checkedAt: string;
7
+ error?: string;
8
+ }
9
+ export type ModelHealthChecker = () => Promise<ModelHealthResult>;
10
+ export declare function createModelHealthChecker(workingDir: string): ModelHealthChecker;
11
+ //# sourceMappingURL=model-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-health.d.ts","sourceRoot":"","sources":["../src/model-health.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAQ5E,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAElE,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAoE/E"}
@@ -0,0 +1,67 @@
1
+ /** Lightweight live check for the currently configured default AI model. */
2
+ import { complete } from "@earendil-works/pi-ai/compat";
3
+ import { AuthStorage, ModelRegistry, SettingsManager, getAgentDir } from "@earendil-works/pi-coding-agent";
4
+ const CHECK_TIMEOUT_MS = 30_000;
5
+ export function createModelHealthChecker(workingDir) {
6
+ const agentDir = getAgentDir();
7
+ const modelRegistry = ModelRegistry.create(AuthStorage.create());
8
+ return async () => {
9
+ const startedAt = Date.now();
10
+ let modelLabel = null;
11
+ try {
12
+ modelRegistry.refresh();
13
+ const settings = SettingsManager.create(workingDir, agentDir);
14
+ const provider = settings.getDefaultProvider();
15
+ const modelId = settings.getDefaultModel();
16
+ if (!provider || !modelId)
17
+ throw new Error("No default model configured");
18
+ const model = modelRegistry.find(provider, modelId);
19
+ modelLabel = `${provider}/${modelId}`;
20
+ if (!model)
21
+ throw new Error(`Default model not found: ${modelLabel}`);
22
+ const auth = await modelRegistry.getApiKeyAndHeaders(model);
23
+ if (!auth.ok)
24
+ throw new Error(auth.error);
25
+ console.log(`[health] model check start: ${modelLabel}`);
26
+ const message = {
27
+ role: "user",
28
+ content: "Reply with exactly OK.",
29
+ timestamp: Date.now(),
30
+ };
31
+ const response = await complete(model, { messages: [message] }, {
32
+ apiKey: auth.apiKey,
33
+ headers: auth.headers,
34
+ maxTokens: 64,
35
+ maxRetries: 0,
36
+ timeoutMs: CHECK_TIMEOUT_MS,
37
+ signal: AbortSignal.timeout(CHECK_TIMEOUT_MS),
38
+ });
39
+ if (response.stopReason === "error" || response.stopReason === "aborted") {
40
+ throw new Error(response.errorMessage || `Model stopped with reason: ${response.stopReason}`);
41
+ }
42
+ const hasText = response.content.some((part) => part.type === "text" && part.text.trim().length > 0);
43
+ if (!hasText)
44
+ throw new Error("Model returned no text");
45
+ const result = {
46
+ ok: true,
47
+ model: modelLabel,
48
+ latencyMs: Date.now() - startedAt,
49
+ checkedAt: new Date().toISOString(),
50
+ };
51
+ console.log(`[health] model check ok: ${modelLabel} latency_ms=${result.latencyMs}`);
52
+ return result;
53
+ }
54
+ catch (error) {
55
+ const result = {
56
+ ok: false,
57
+ model: modelLabel,
58
+ latencyMs: Date.now() - startedAt,
59
+ checkedAt: new Date().toISOString(),
60
+ error: error instanceof Error ? error.message : String(error),
61
+ };
62
+ console.error(`[health] model check failed: ${modelLabel ?? "unknown"} latency_ms=${result.latencyMs} error="${result.error}"`);
63
+ return result;
64
+ }
65
+ };
66
+ }
67
+ //# sourceMappingURL=model-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-health.js","sourceRoot":"","sources":["../src/model-health.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGhF,MAAM,MAAM,UAAU,GAAG,CACxB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,KACrB,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;AAEhD,iGAAiG;AACjG,MAAM,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;AACzD,MAAM,MAAM,SAAS,GAAG,CACvB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;AAEnH,MAAM,WAAW,eAAe;IAC/B,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7D;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CA0CvD"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGhF,MAAM,MAAM,UAAU,GAAG,CACxB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,KACrB,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;AAEhD,iGAAiG;AACjG,MAAM,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;AACzD,MAAM,MAAM,SAAS,GAAG,CACvB,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,MAAM,KACR,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;AAEnH,MAAM,WAAW,eAAe;IAC/B,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7D;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CA8CvD"}
package/dist/pipeline.js CHANGED
@@ -35,7 +35,11 @@ export function createMessagePipeline() {
35
35
  // emit() is sync — queues end tasks onto endChain for serialized execution
36
36
  let endChain = Promise.resolve();
37
37
  const emit = (out) => {
38
- endChain = endChain.then(() => runEndTasks(chat, out));
38
+ endChain = endChain
39
+ .then(() => runEndTasks(chat, out))
40
+ .catch((error) => {
41
+ console.error(`[pipeline] end task error for ${chat.chatGuid}:`, error);
42
+ });
39
43
  };
40
44
  for (const task of startTasks) {
41
45
  await task(chat, incoming, outgoing, emit);
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA0BlE,MAAM,UAAU,qBAAqB;IACpC,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,UAAU,WAAW,CAAC,IAAiB,EAAE,QAAyB;QACtE,IAAI,MAAM,GAAG,QAAQ,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,OAAO;QACpC,CAAC;IACF,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,QAAyB;QAC/C,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,QAAQ,GAAG,qBAAqB,EAAE,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,cAAc;gBAAE,OAAO,QAAQ,CAAC;QAC/C,CAAC;QAED,2EAA2E;QAC3E,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,GAAW,CAAC,GAAG,EAAE,EAAE;YAC5B,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,cAAc;gBAAE,MAAM;QACrC,CAAC;QACD,MAAM,QAAQ,CAAC;QAEf,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,OAAO;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QACxC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,OAAO;KACP,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA0BlE,MAAM,UAAU,qBAAqB;IACpC,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,UAAU,WAAW,CAAC,IAAiB,EAAE,QAAyB;QACtE,IAAI,MAAM,GAAG,QAAQ,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,cAAc;gBAAE,OAAO;QACpC,CAAC;IACF,CAAC;IAED,KAAK,UAAU,OAAO,CAAC,QAAyB;QAC/C,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,QAAQ,GAAG,qBAAqB,EAAE,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,cAAc;gBAAE,OAAO,QAAQ,CAAC;QAC/C,CAAC;QAED,2EAA2E;QAC3E,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,GAAW,CAAC,GAAG,EAAE,EAAE;YAC5B,QAAQ,GAAG,QAAQ;iBACjB,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;iBAClC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChB,OAAO,CAAC,KAAK,CAAC,iCAAiC,IAAI,CAAC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,cAAc;gBAAE,MAAM;QACrC,CAAC;QACD,MAAM,QAAQ,CAAC;QAEf,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,OAAO;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QACxC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAClC,OAAO;KACP,CAAC;AACH,CAAC"}
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
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAgDtD,+DAA+D;AAC/D,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA0CtD;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;CACxF;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAoBnD"}
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"}