aibroker 0.58.1 → 0.59.0
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/adapters/iterm/core.d.ts +12 -1
- package/dist/adapters/iterm/core.d.ts.map +1 -1
- package/dist/adapters/iterm/core.js +32 -5
- package/dist/adapters/iterm/core.js.map +1 -1
- package/dist/adapters/iterm/sessions.d.ts.map +1 -1
- package/dist/adapters/iterm/sessions.js +36 -4
- package/dist/adapters/iterm/sessions.js.map +1 -1
- package/dist/core/state.d.ts +7 -1
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +13 -3
- package/dist/core/state.js.map +1 -1
- package/dist/daemon/core-handlers.d.ts +28 -0
- package/dist/daemon/core-handlers.d.ts.map +1 -1
- package/dist/daemon/core-handlers.js +150 -50
- package/dist/daemon/core-handlers.js.map +1 -1
- package/dist/daemon/dispatch.d.ts +39 -0
- package/dist/daemon/dispatch.d.ts.map +1 -1
- package/dist/daemon/dispatch.js +331 -2
- package/dist/daemon/dispatch.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +10 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/manage.d.ts +37 -0
- package/dist/daemon/manage.d.ts.map +1 -1
- package/dist/daemon/manage.js +157 -12
- package/dist/daemon/manage.js.map +1 -1
- package/dist/daemon/todoist-pending.d.ts +45 -0
- package/dist/daemon/todoist-pending.d.ts.map +1 -0
- package/dist/daemon/todoist-pending.js +58 -0
- package/dist/daemon/todoist-pending.js.map +1 -0
- package/dist/daemon/todoist-reply.d.ts +10 -0
- package/dist/daemon/todoist-reply.d.ts.map +1 -1
- package/dist/daemon/todoist-reply.js +1 -0
- package/dist/daemon/todoist-reply.js.map +1 -1
- package/dist/daemon/todoist-webhook.d.ts +29 -0
- package/dist/daemon/todoist-webhook.d.ts.map +1 -1
- package/dist/daemon/todoist-webhook.js +331 -208
- package/dist/daemon/todoist-webhook.js.map +1 -1
- package/dist/ipc/client.d.ts.map +1 -1
- package/dist/ipc/client.js +24 -3
- package/dist/ipc/client.js.map +1 -1
- package/dist/mcp/index.js +19 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/transport/sync-facade.d.ts +15 -2
- package/dist/transport/sync-facade.d.ts.map +1 -1
- package/dist/transport/sync-facade.js +16 -3
- package/dist/transport/sync-facade.js.map +1 -1
- package/hooks/drain-mailbox.mjs +34 -8
- package/package.json +1 -1
|
@@ -56,12 +56,16 @@ function tmuxToSnapshot(s) {
|
|
|
56
56
|
aibrokerId: s.aibrokerId,
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
/**
|
|
60
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Enumerate sessions across all permitted transports, availability checked live.
|
|
61
|
+
* `fresh` bypasses iTerm's short-lived cache — forwarded verbatim, see
|
|
62
|
+
* adapters/iterm/core.ts. tmux's `listSessions()` has no such cache to bypass.
|
|
63
|
+
*/
|
|
64
|
+
export function snapshotAllSessions(opts = {}) {
|
|
61
65
|
// Query tmux first (returns [] if no server is running). This is the LIVE
|
|
62
66
|
// availability check — a server that appears post-boot is seen immediately.
|
|
63
67
|
const tmuxSessions = allowTmux ? tmuxTransport.listSessions() : [];
|
|
64
|
-
let itermSessions = allowIterm ? iterm.snapshotAllSessions() : [];
|
|
68
|
+
let itermSessions = allowIterm ? iterm.snapshotAllSessions(opts) : [];
|
|
65
69
|
if (allowIterm && tmuxSessions.length) {
|
|
66
70
|
// De-dup nesting: an iTerm/Terminal tab running `tmux attach` is just a
|
|
67
71
|
// VIEWER of tmux panes we already enumerate directly. Suppress those rows
|
|
@@ -73,6 +77,15 @@ export function snapshotAllSessions() {
|
|
|
73
77
|
}
|
|
74
78
|
return [...itermSessions, ...tmuxSessions.map(tmuxToSnapshot)];
|
|
75
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether the LAST snapshotAllSessions() call actually enumerated iTerm,
|
|
82
|
+
* rather than getting an osascript failure back as an indistinguishable `[]`.
|
|
83
|
+
* tmux has no such failure mode here — `listSessions()` returning `[]` means
|
|
84
|
+
* "no server", which is a real answer, not a dropped one.
|
|
85
|
+
*/
|
|
86
|
+
export function wasLastEnumerationReliable() {
|
|
87
|
+
return allowIterm ? iterm.wasLastSnapshotReliable() : true;
|
|
88
|
+
}
|
|
76
89
|
/**
|
|
77
90
|
* Decide whether an id belongs to tmux. tmux session ids are now durable
|
|
78
91
|
* @aibroker_ids (a raw "%N" pane id may also appear during inbound translation).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-facade.js","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,KAAK,MAAM,2BAA2B,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAE7E,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AAC1C,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;AAE5C,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,8EAA8E;AAC9E,8BAA8B;AAC9B,MAAM,UAAU,GAAG,QAAQ,KAAK,MAAM,CAAC;AACvC,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAC;AAEvC,SAAS,cAAc,CAAC,CAAiB;IACvC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;QAChB,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;QACjB,6EAA6E;QAC7E,OAAO,EAAE,IAAI;QACb,+EAA+E;QAC/E,UAAU,EAAE,CAAC,CAAC,UAAU;KACzB,CAAC;AACJ,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"sync-facade.js","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"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"}
|
package/hooks/drain-mailbox.mjs
CHANGED
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
* anything queued is injected as context on the very next turn rather than
|
|
14
14
|
* whenever someone thinks to check.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Delivery is two-phase for the same reason: a destructive read here lost a
|
|
17
|
+
* message live on 2026-09-25 (daemon drained, hook's 1.5 s reply timeout
|
|
18
|
+
* fired, nothing emitted). So this hook PEEKS (non-destructive), emits, and
|
|
19
|
+
* only then ACKs the daemon to clear. Any timeout along the way leaves the
|
|
20
|
+
* messages queued for the next prompt — a duplicate redelivery, never a loss.
|
|
21
|
+
* If the output cannot be emitted at all, the messages are additionally
|
|
22
|
+
* written to ~/.aibroker/undelivered.jsonl rather than lost, which is the
|
|
23
|
+
* whole failure this hook exists to end.
|
|
20
24
|
*
|
|
21
25
|
* Silent when there is nothing waiting, and silent on every error: a hook that
|
|
22
26
|
* fails loudly on every prompt is a hook someone disables.
|
|
@@ -27,7 +31,9 @@ import { appendFileSync, mkdirSync } from "node:fs";
|
|
|
27
31
|
import { homedir } from "node:os";
|
|
28
32
|
import { join } from "node:path";
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
// AIBROKER_HOOK_SOCKET is a test seam: it lets tests point the hook at a fake
|
|
35
|
+
// daemon socket instead of the live one. Production never sets it.
|
|
36
|
+
const SOCKET = process.env.AIBROKER_HOOK_SOCKET ?? "/tmp/aibroker.sock";
|
|
31
37
|
const TIMEOUT_MS = 1500;
|
|
32
38
|
const UNDELIVERED = join(homedir(), ".aibroker", "undelivered.jsonl");
|
|
33
39
|
|
|
@@ -59,10 +65,22 @@ function call(method, params) {
|
|
|
59
65
|
});
|
|
60
66
|
}
|
|
61
67
|
|
|
68
|
+
// A worker child process (PAI_WORKER=1) inherits TERM_SESSION_ID/
|
|
69
|
+
// ITERM_SESSION_ID/TMUX_PANE from the pane it runs inside, so sessionId()
|
|
70
|
+
// below would resolve to the pane OWNER's id, not its own — draining is
|
|
71
|
+
// destructive, so this would empty the owner's real mailbox on the worker's
|
|
72
|
+
// own prompts before the owner ever saw the messages in it. Observed live
|
|
73
|
+
// 2026-09-23: a worker's reply to "AIBroker" was recorded as delivered but
|
|
74
|
+
// never surfaced in the real AIBroker session, and aibroker_receive there
|
|
75
|
+
// found nothing.
|
|
76
|
+
if (process.env.PAI_WORKER === "1") process.exit(0);
|
|
77
|
+
|
|
62
78
|
const id = sessionId();
|
|
63
79
|
if (!id) process.exit(0);
|
|
64
80
|
|
|
65
|
-
|
|
81
|
+
// Phase 1: peek, non-destructive. A timeout here emits nothing and the
|
|
82
|
+
// messages stay queued — delivered on the next prompt instead of lost.
|
|
83
|
+
const res = await call("session_mailbox_peek", { sessionId: id });
|
|
66
84
|
const messages = res?.ok ? (res.result?.messages ?? []) : [];
|
|
67
85
|
if (messages.length === 0) process.exit(0);
|
|
68
86
|
|
|
@@ -85,13 +103,21 @@ const out =
|
|
|
85
103
|
lines.join("\n\n") +
|
|
86
104
|
`\n</system-reminder>`;
|
|
87
105
|
|
|
106
|
+
let emitted = true;
|
|
88
107
|
try {
|
|
89
108
|
process.stdout.write(out + "\n");
|
|
90
109
|
} catch (e) {
|
|
91
|
-
|
|
92
|
-
//
|
|
110
|
+
emitted = false;
|
|
111
|
+
// The mailbox is NOT cleared on a peek, so the messages stay queued — but a
|
|
112
|
+
// queue nobody drains is undelivered, not pending, so they are recorded here
|
|
113
|
+
// too. Losing them would be the exact silent drop this hook was written to stop.
|
|
93
114
|
try {
|
|
94
115
|
mkdirSync(join(homedir(), ".aibroker"), { recursive: true });
|
|
95
116
|
appendFileSync(UNDELIVERED, messages.map((m) => JSON.stringify({ ...m, failedAt: new Date().toISOString(), error: String(e) })).join("\n") + "\n");
|
|
96
117
|
} catch { /* nothing left to try */ }
|
|
97
118
|
}
|
|
119
|
+
|
|
120
|
+
// Phase 2, only after a successful emit: ack the daemon to clear what was
|
|
121
|
+
// peeked. Best-effort — a timeout here leaves the messages queued and they are
|
|
122
|
+
// re-delivered on the next prompt. A duplicate is acceptable; a loss is not.
|
|
123
|
+
if (emitted) await call("session_mailbox_ack", { sessionId: id, count: messages.length });
|