@decibelsystems/tools 2.1.2 → 2.1.3
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/agentCommands.d.ts +11 -0
- package/dist/agentCommands.d.ts.map +1 -0
- package/dist/agentCommands.js +267 -0
- package/dist/agentCommands.js.map +1 -0
- package/dist/agentInbox.d.ts +37 -0
- package/dist/agentInbox.d.ts.map +1 -0
- package/dist/agentInbox.js +128 -0
- package/dist/agentInbox.js.map +1 -0
- package/dist/agentPresence.d.ts +36 -0
- package/dist/agentPresence.d.ts.map +1 -0
- package/dist/agentPresence.js +227 -0
- package/dist/agentPresence.js.map +1 -0
- package/dist/agenticJobs.d.ts +49 -0
- package/dist/agenticJobs.d.ts.map +1 -0
- package/dist/agenticJobs.js +190 -0
- package/dist/agenticJobs.js.map +1 -0
- package/dist/architectAdrs.d.ts +7 -0
- package/dist/architectAdrs.d.ts.map +1 -1
- package/dist/architectAdrs.js +91 -28
- package/dist/architectAdrs.js.map +1 -1
- package/dist/daemon.d.ts +6 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +14 -0
- package/dist/daemon.js.map +1 -1
- package/dist/facades/definitions.d.ts.map +1 -1
- package/dist/facades/definitions.js +40 -6
- package/dist/facades/definitions.js.map +1 -1
- package/dist/hq/defineAgent.d.ts +11 -0
- package/dist/hq/defineAgent.d.ts.map +1 -0
- package/dist/hq/defineAgent.js +185 -0
- package/dist/hq/defineAgent.js.map +1 -0
- package/dist/hq/index.d.ts +3 -0
- package/dist/hq/index.d.ts.map +1 -0
- package/dist/hq/index.js +28 -0
- package/dist/hq/index.js.map +1 -0
- package/dist/hq/types.d.ts +59 -0
- package/dist/hq/types.d.ts.map +1 -0
- package/dist/hq/types.js +12 -0
- package/dist/hq/types.js.map +1 -0
- package/dist/httpServer.d.ts +1 -1
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +327 -19
- package/dist/httpServer.js.map +1 -1
- package/dist/kernel.d.ts +3 -1
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +40 -9
- package/dist/kernel.js.map +1 -1
- package/dist/projectRegistry.d.ts +27 -0
- package/dist/projectRegistry.d.ts.map +1 -1
- package/dist/projectRegistry.js +191 -5
- package/dist/projectRegistry.js.map +1 -1
- package/dist/sentinelIssues.d.ts +5 -0
- package/dist/sentinelIssues.d.ts.map +1 -1
- package/dist/sentinelIssues.js +1 -1
- package/dist/sentinelIssues.js.map +1 -1
- package/dist/server.js +12 -0
- package/dist/server.js.map +1 -1
- package/dist/store/fsStore.d.ts +6 -0
- package/dist/store/fsStore.d.ts.map +1 -0
- package/dist/store/fsStore.js +77 -0
- package/dist/store/fsStore.js.map +1 -0
- package/dist/store/index.d.ts +8 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +23 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/markdown.d.ts +21 -0
- package/dist/store/markdown.d.ts.map +1 -0
- package/dist/store/markdown.js +175 -0
- package/dist/store/markdown.js.map +1 -0
- package/dist/store/supabaseStore.d.ts +6 -0
- package/dist/store/supabaseStore.d.ts.map +1 -0
- package/dist/store/supabaseStore.js +152 -0
- package/dist/store/supabaseStore.js.map +1 -0
- package/dist/store/types.d.ts +49 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +11 -0
- package/dist/store/types.js.map +1 -0
- package/dist/supabaseRetry.d.ts +21 -0
- package/dist/supabaseRetry.d.ts.map +1 -0
- package/dist/supabaseRetry.js +72 -0
- package/dist/supabaseRetry.js.map +1 -0
- package/dist/toolConfig.d.ts +49 -0
- package/dist/toolConfig.d.ts.map +1 -0
- package/dist/toolConfig.js +309 -0
- package/dist/toolConfig.js.map +1 -0
- package/dist/tools/agentic/agentQueue.d.ts.map +1 -1
- package/dist/tools/agentic/agentQueue.js +7 -5
- package/dist/tools/agentic/agentQueue.js.map +1 -1
- package/dist/tools/agentic/index.d.ts +3 -0
- package/dist/tools/agentic/index.d.ts.map +1 -1
- package/dist/tools/agentic/index.js +158 -1
- package/dist/tools/agentic/index.js.map +1 -1
- package/dist/tools/codereview/index.d.ts +4 -0
- package/dist/tools/codereview/index.d.ts.map +1 -0
- package/dist/tools/codereview/index.js +93 -0
- package/dist/tools/codereview/index.js.map +1 -0
- package/dist/tools/codereview.d.ts +56 -0
- package/dist/tools/codereview.d.ts.map +1 -0
- package/dist/tools/codereview.js +304 -0
- package/dist/tools/codereview.js.map +1 -0
- package/dist/tools/concepts.d.ts +38 -0
- package/dist/tools/concepts.d.ts.map +1 -0
- package/dist/tools/concepts.js +283 -0
- package/dist/tools/concepts.js.map +1 -0
- package/dist/tools/corpus/index.d.ts +3 -0
- package/dist/tools/corpus/index.d.ts.map +1 -1
- package/dist/tools/corpus/index.js +183 -1
- package/dist/tools/corpus/index.js.map +1 -1
- package/dist/tools/corpus.d.ts +52 -0
- package/dist/tools/corpus.d.ts.map +1 -1
- package/dist/tools/corpus.js +207 -2
- package/dist/tools/corpus.js.map +1 -1
- package/dist/tools/dojo.d.ts.map +1 -1
- package/dist/tools/dojo.js +11 -1
- package/dist/tools/dojo.js.map +1 -1
- package/dist/tools/git-sentinel.d.ts.map +1 -1
- package/dist/tools/git-sentinel.js +24 -8
- package/dist/tools/git-sentinel.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/oracle.d.ts +2 -0
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +146 -17
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/peers.d.ts +15 -0
- package/dist/tools/peers.d.ts.map +1 -0
- package/dist/tools/peers.js +70 -0
- package/dist/tools/peers.js.map +1 -0
- package/dist/tools/registry/index.d.ts +4 -0
- package/dist/tools/registry/index.d.ts.map +1 -1
- package/dist/tools/registry/index.js +274 -1
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/roadmap.d.ts +4 -0
- package/dist/tools/roadmap.d.ts.map +1 -1
- package/dist/tools/roadmap.js.map +1 -1
- package/dist/tools/sentinel.d.ts +15 -1
- package/dist/tools/sentinel.d.ts.map +1 -1
- package/dist/tools/sentinel.js +198 -34
- package/dist/tools/sentinel.js.map +1 -1
- package/dist/tools/voice/index.d.ts.map +1 -1
- package/dist/tools/voice/index.js +2 -3
- package/dist/tools/voice/index.js.map +1 -1
- package/dist/tools/voice.d.ts +1 -1
- package/dist/tools/voice.js +2 -2
- package/dist/tools/voice.js.map +1 -1
- package/dist/tools/workflow.js +5 -5
- package/dist/tools/workflow.js.map +1 -1
- package/dist/transports/http.js +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const ORG_ID: string;
|
|
2
|
+
/**
|
|
3
|
+
* Settle a command from an SDK ack (POST /agents/commands/ack). The SDK ran
|
|
4
|
+
* onCommand and reports done|failed (+ optional result/error). We write it back to
|
|
5
|
+
* Core via service_role, org-scoped. Returns false if Supabase is unconfigured.
|
|
6
|
+
* Only 'done'|'failed' are accepted from an ack (the SDK can't set other states).
|
|
7
|
+
*/
|
|
8
|
+
export declare function settleCommandFromAck(id: string, status: 'done' | 'failed', result?: Record<string, unknown> | null, error?: string | null): Promise<boolean>;
|
|
9
|
+
/** Start the command dispatcher loop. Returns a stop function. No-ops if Supabase unconfigured. */
|
|
10
|
+
export declare function startCommandDispatcher(): () => void;
|
|
11
|
+
//# sourceMappingURL=agentCommands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentCommands.d.ts","sourceRoot":"","sources":["../src/agentCommands.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,MAAM,QAAuE,CAAC;AAoO3F;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GAAG,QAAQ,EACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACvC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,mGAAmG;AACnG,wBAAgB,sBAAsB,IAAI,MAAM,IAAI,CAcnD"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Agent-command dispatcher — HQ → agent control surface (Plan D, v1)
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// The inverse of agentPresence: HQ (org admin) WRITES commands into
|
|
5
|
+
// hq.agent_commands under RLS; this daemon picks up pending commands targeted at
|
|
6
|
+
// sessions IT hosts and dispatches them, writing status/result back via
|
|
7
|
+
// SERVICE_ROLE. v1 kinds (Ben-scoped, allowlisted): 'message' + 'request_status'.
|
|
8
|
+
// No shell, no lifecycle. Contract co-designed with decibel-hq (hq.agent_commands
|
|
9
|
+
// migration + cancel RPC + expire sweep). EPIC-0033.
|
|
10
|
+
//
|
|
11
|
+
// SAFETY: a 'message' is delivered to the target peer as untrusted-channel DATA
|
|
12
|
+
// (via the claude-peers broker) — it is NOT an auto-executed instruction. The
|
|
13
|
+
// daemon only transports it.
|
|
14
|
+
//
|
|
15
|
+
// ⚠️ LOAD-BEARING CROSS-ORG INVARIANT (per HQ /security-review):
|
|
16
|
+
// target_session_key / target_host are FREE TEXT on hq.agent_commands — HQ does
|
|
17
|
+
// NOT bind them to a same-org live session (keys churn). The ENTIRE cross-org
|
|
18
|
+
// targeting defense therefore rests on THIS query: it MUST filter on org_id
|
|
19
|
+
// FIRST (the org this daemon is authorized to serve), with target_host ==
|
|
20
|
+
// own hostname + target_session_key ∈ live registry as defense-in-depth.
|
|
21
|
+
// An org-A admin can write a row naming an org-B peer's guessable session_key,
|
|
22
|
+
// but that row carries org_id=A; as long as org-B's daemon only ever dispatches
|
|
23
|
+
// rows scoped to org B's org_id, the A-row never reaches B. DO NOT refactor this
|
|
24
|
+
// to key purely on (host, session_key) ignoring org_id — that opens cross-org
|
|
25
|
+
// targeting on a shared host.
|
|
26
|
+
//
|
|
27
|
+
// Other boundaries:
|
|
28
|
+
// - host-match: only dispatch commands whose target_host == this host.
|
|
29
|
+
// - expiry: skip expires_at < now; also call the DB sweep each cycle.
|
|
30
|
+
// - poll every 5s (robust; realtime is HQ's status view, not our pickup path).
|
|
31
|
+
// ============================================================================
|
|
32
|
+
import { createClient } from '@supabase/supabase-js';
|
|
33
|
+
import { log } from './config.js';
|
|
34
|
+
import { withRetryResult } from './supabaseRetry.js';
|
|
35
|
+
import { enqueueCommand } from './agentInbox.js';
|
|
36
|
+
import { resolveHost } from './agentPresence.js';
|
|
37
|
+
const BROKER_URL = `http://127.0.0.1:${process.env.CLAUDE_PEERS_PORT ?? '7899'}`;
|
|
38
|
+
// Exported so the HTTP inbox endpoints (httpServer.ts) org-scope drainCommands to
|
|
39
|
+
// the same org this daemon serves — keeps the org-id-first invariant on the read path.
|
|
40
|
+
export const ORG_ID = process.env.DECIBEL_ORG_ID || '1cb79e24-e06f-46c9-8a22-5ee025ffb0f4';
|
|
41
|
+
const POLL_MS = 5_000;
|
|
42
|
+
const ALLOWED_KINDS = new Set(['message', 'request_status']);
|
|
43
|
+
// Ben-scoped staged rollout: the FIRST run dispatches request_status ONLY so he can
|
|
44
|
+
// watch a read-only round-trip before any message reaches a live agent. 'message'
|
|
45
|
+
// dispatch stays held (rows left pending → they expire) until DECIBEL_ENABLE_AGENT_MESSAGES=1.
|
|
46
|
+
const MESSAGES_ENABLED = process.env.DECIBEL_ENABLE_AGENT_MESSAGES === '1';
|
|
47
|
+
function serviceClient() {
|
|
48
|
+
const url = process.env.SUPABASE_URL;
|
|
49
|
+
const key = process.env.SUPABASE_SERVICE_KEY;
|
|
50
|
+
if (!url || !key)
|
|
51
|
+
return null;
|
|
52
|
+
return createClient(url, key, {
|
|
53
|
+
auth: { persistSession: false, autoRefreshToken: false },
|
|
54
|
+
db: { schema: 'hq' },
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function brokerListPeers() {
|
|
58
|
+
try {
|
|
59
|
+
const res = await fetch(`${BROKER_URL}/list-peers`, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
body: JSON.stringify({ requester_id: 'decibel-daemon', scope: 'machine' }),
|
|
63
|
+
signal: AbortSignal.timeout(2000),
|
|
64
|
+
});
|
|
65
|
+
if (!res.ok)
|
|
66
|
+
return [];
|
|
67
|
+
return (await res.json());
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Send a peer message via the claude-peers broker. Returns ok + optional error. */
|
|
74
|
+
async function brokerSend(to, message) {
|
|
75
|
+
try {
|
|
76
|
+
const res = await fetch(`${BROKER_URL}/send-message`, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
headers: { 'Content-Type': 'application/json' },
|
|
79
|
+
// Broker contract: {from_id, to_id, text} (claude-peers broker.ts:280,
|
|
80
|
+
// shared/types.ts:59 — confirmed line-by-line by the claude-peers owner).
|
|
81
|
+
// from_id="decibel-daemon": a plainly NON-privileged relay label. Deliberately
|
|
82
|
+
// NOT "system" — a "system" sender reads to the receiving agent as a trusted/
|
|
83
|
+
// privileged directive, the OPPOSITE of the required posture (an HQ command is
|
|
84
|
+
// untrusted-channel DATA, not an auto-executed instruction). Human provenance
|
|
85
|
+
// rides in `text` ("HQ · <issuer>: ..."). FK is off in the broker so any
|
|
86
|
+
// from_id delivers; if FK is ever enabled, register decibel-daemon then.
|
|
87
|
+
body: JSON.stringify({ from_id: 'decibel-daemon', to_id: to, text: message }),
|
|
88
|
+
signal: AbortSignal.timeout(3000),
|
|
89
|
+
});
|
|
90
|
+
const body = (await res.json().catch(() => ({})));
|
|
91
|
+
return { ok: body.ok === true, error: body.error ?? (res.ok ? undefined : `HTTP ${res.status}`) };
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const TERMINAL = new Set(['done', 'failed', 'cancelled', 'expired']);
|
|
98
|
+
async function settle(client, id, patch) {
|
|
99
|
+
// Stamp completed_at on terminal transitions so HQ can show completion timing.
|
|
100
|
+
if (typeof patch.status === 'string' && TERMINAL.has(patch.status) && !('completed_at' in patch)) {
|
|
101
|
+
patch = { ...patch, completed_at: new Date().toISOString() };
|
|
102
|
+
}
|
|
103
|
+
// org_id-scoped settle too — never update a row outside our authorized org.
|
|
104
|
+
const { error } = await client.from('agent_commands').update(patch).eq('id', id).eq('org_id', ORG_ID);
|
|
105
|
+
if (error)
|
|
106
|
+
log(`Commands: settle ${id} failed: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
async function dispatchOne(client, cmd, peers, sdkSessions) {
|
|
109
|
+
// Defensive expiry + kind allowlist (DB also enforces, belt-and-suspenders).
|
|
110
|
+
if (cmd.expires_at && Date.parse(cmd.expires_at) < Date.now())
|
|
111
|
+
return;
|
|
112
|
+
if (!ALLOWED_KINDS.has(cmd.kind)) {
|
|
113
|
+
await settle(client, cmd.id, { status: 'failed', error: `unsupported kind '${cmd.kind}'` });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Staged rollout: hold 'message' until explicitly enabled. Leave the row pending
|
|
117
|
+
// (untouched) so it simply expires — do NOT settle, so it can dispatch later if
|
|
118
|
+
// messages are enabled before it expires.
|
|
119
|
+
if (cmd.kind === 'message' && !MESSAGES_ENABLED)
|
|
120
|
+
return;
|
|
121
|
+
const peer = peers.find((p) => p.id === cmd.target_session_key);
|
|
122
|
+
const isSdkSession = !peer && sdkSessions.has(cmd.target_session_key);
|
|
123
|
+
// Target not (yet) resolvable as either a broker peer OR a known SDK session.
|
|
124
|
+
// DON'T permanently fail it — a session that registers in the split-second after
|
|
125
|
+
// the command was issued would otherwise be lost on the first tick. Leave it
|
|
126
|
+
// 'pending' so the next tick re-checks; the DB expiry sweep terminates it (→
|
|
127
|
+
// 'expired') if the target never appears. (Race fix found via SDK e2e 2026-06-15.)
|
|
128
|
+
if (!peer && !isSdkSession) {
|
|
129
|
+
return; // leave pending; retried next tick, expires if truly absent
|
|
130
|
+
}
|
|
131
|
+
// SDK-runtime target (registered via /agents/register, NOT a claude-peers peer):
|
|
132
|
+
// it has no broker transport, so we don't resolve/deliver here. Enqueue it for the
|
|
133
|
+
// SDK to poll + ack (which settles the Core row). Mark 'delivered' so HQ sees
|
|
134
|
+
// pickup; the SDK ack flips it to done/failed. (request_status is treated the same
|
|
135
|
+
// way for SDK sessions — the SDK answers it via onCommand and acks with a result.)
|
|
136
|
+
if (isSdkSession) {
|
|
137
|
+
await settle(client, cmd.id, { status: 'delivered', delivered_at: new Date().toISOString() });
|
|
138
|
+
enqueueCommand(cmd.target_session_key, {
|
|
139
|
+
id: cmd.id,
|
|
140
|
+
org_id: cmd.org_id,
|
|
141
|
+
kind: cmd.kind,
|
|
142
|
+
payload: cmd.payload ?? {},
|
|
143
|
+
enqueued_at: Date.now(),
|
|
144
|
+
});
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// From here, peer is a live broker session. Mark delivered (picked up).
|
|
148
|
+
await settle(client, cmd.id, { status: 'delivered', delivered_at: new Date().toISOString() });
|
|
149
|
+
if (cmd.kind === 'request_status') {
|
|
150
|
+
await settle(client, cmd.id, {
|
|
151
|
+
status: 'done',
|
|
152
|
+
result: { summary: peer.summary || null, cwd: peer.cwd || null, last_seen: peer.last_seen, status: 'active' },
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// kind === 'message'
|
|
157
|
+
const text = cmd.payload?.text;
|
|
158
|
+
if (!text) {
|
|
159
|
+
await settle(client, cmd.id, { status: 'failed', error: 'message payload missing text' });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const label = cmd.payload?.from_label ? `${cmd.payload.from_label}: ` : '';
|
|
163
|
+
const r = await brokerSend(cmd.target_session_key, `${label}${text}`);
|
|
164
|
+
if (r.ok) {
|
|
165
|
+
await settle(client, cmd.id, { status: 'done', result: { delivered: true } });
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
await settle(client, cmd.id, { status: 'failed', error: r.error || 'broker send failed' });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function tick(client) {
|
|
172
|
+
const host = resolveHost();
|
|
173
|
+
// DB-side sweep: flip pending->expired where past expiry (idempotent, service_role).
|
|
174
|
+
try {
|
|
175
|
+
await client.rpc('expire_stale_agent_commands');
|
|
176
|
+
}
|
|
177
|
+
catch { /* RPC optional/non-fatal */ }
|
|
178
|
+
// Pending commands for OUR org (primary cross-org filter — see invariant above),
|
|
179
|
+
// targeted at sessions THIS daemon hosts. withRetryResult smooths transient
|
|
180
|
+
// "fetch failed" blips (issue 2026-06-13) before giving up for this tick.
|
|
181
|
+
const { data, error } = await withRetryResult(() => client
|
|
182
|
+
.from('agent_commands')
|
|
183
|
+
.select('id,org_id,target_session_key,target_host,kind,payload,expires_at,status')
|
|
184
|
+
.eq('org_id', ORG_ID)
|
|
185
|
+
.eq('status', 'pending')
|
|
186
|
+
.eq('target_host', host), 'commands.poll');
|
|
187
|
+
if (error) {
|
|
188
|
+
log(`Commands: poll failed: ${error.message}`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const pending = (data ?? []);
|
|
192
|
+
if (pending.length === 0)
|
|
193
|
+
return;
|
|
194
|
+
// SDK runtimes hosting on this box (live, non-claude-code sessions): commands
|
|
195
|
+
// targeting these route to the in-daemon inbox for the SDK to poll+ack, instead
|
|
196
|
+
// of failing as "not found in live registry". org-id-first + host-match preserved.
|
|
197
|
+
const sdkSessions = await loadSdkSessions(client, host);
|
|
198
|
+
const peers = await brokerListPeers();
|
|
199
|
+
for (const cmd of pending) {
|
|
200
|
+
try {
|
|
201
|
+
await dispatchOne(client, cmd, peers, sdkSessions);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
log(`Commands: dispatch ${cmd.id} error: ${e instanceof Error ? e.message : String(e)}`);
|
|
205
|
+
await settle(client, cmd.id, { status: 'failed', error: 'dispatch exception' }).catch(() => { });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Live SDK-runtime session_keys this daemon hosts (org + host scoped, runtime not
|
|
211
|
+
* claude-code, status active). These receive commands via the inbox, not the broker.
|
|
212
|
+
*/
|
|
213
|
+
async function loadSdkSessions(client, host) {
|
|
214
|
+
const { data, error } = await withRetryResult(() => client
|
|
215
|
+
.from('agent_sessions')
|
|
216
|
+
.select('session_key,runtime,status')
|
|
217
|
+
.eq('org_id', ORG_ID)
|
|
218
|
+
.eq('host', host)
|
|
219
|
+
.eq('status', 'active')
|
|
220
|
+
.neq('runtime', 'claude-code'), 'commands.sdkSessions');
|
|
221
|
+
const set = new Set();
|
|
222
|
+
if (error)
|
|
223
|
+
log(`Commands: loadSdkSessions query error: ${error.message}`);
|
|
224
|
+
if (!error && data) {
|
|
225
|
+
for (const r of data)
|
|
226
|
+
set.add(r.session_key);
|
|
227
|
+
}
|
|
228
|
+
return set;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Settle a command from an SDK ack (POST /agents/commands/ack). The SDK ran
|
|
232
|
+
* onCommand and reports done|failed (+ optional result/error). We write it back to
|
|
233
|
+
* Core via service_role, org-scoped. Returns false if Supabase is unconfigured.
|
|
234
|
+
* Only 'done'|'failed' are accepted from an ack (the SDK can't set other states).
|
|
235
|
+
*/
|
|
236
|
+
export async function settleCommandFromAck(id, status, result, error) {
|
|
237
|
+
const client = serviceClient();
|
|
238
|
+
if (!client)
|
|
239
|
+
return false;
|
|
240
|
+
if (status !== 'done' && status !== 'failed')
|
|
241
|
+
return false;
|
|
242
|
+
const patch = { status };
|
|
243
|
+
if (result !== undefined && result !== null)
|
|
244
|
+
patch.result = result;
|
|
245
|
+
if (error !== undefined && error !== null)
|
|
246
|
+
patch.error = error;
|
|
247
|
+
await settle(client, id, patch);
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
/** Start the command dispatcher loop. Returns a stop function. No-ops if Supabase unconfigured. */
|
|
251
|
+
export function startCommandDispatcher() {
|
|
252
|
+
const client = serviceClient();
|
|
253
|
+
if (!client) {
|
|
254
|
+
log('Commands: SUPABASE_URL/SERVICE_KEY not set — agent-command dispatcher disabled.');
|
|
255
|
+
return () => { };
|
|
256
|
+
}
|
|
257
|
+
log(`Commands: dispatcher started (5s poll of hq.agent_commands, host ${resolveHost()}, org ${ORG_ID}).`);
|
|
258
|
+
const run = () => {
|
|
259
|
+
tick(client).catch((e) => log(`Commands: tick error: ${e instanceof Error ? e.message : String(e)}`));
|
|
260
|
+
};
|
|
261
|
+
run();
|
|
262
|
+
const iv = setInterval(run, POLL_MS);
|
|
263
|
+
if (typeof iv.unref === 'function')
|
|
264
|
+
iv.unref();
|
|
265
|
+
return () => clearInterval(iv);
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=agentCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentCommands.js","sourceRoot":"","sources":["../src/agentCommands.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qEAAqE;AACrE,+EAA+E;AAC/E,oEAAoE;AACpE,iFAAiF;AACjF,wEAAwE;AACxE,kFAAkF;AAClF,kFAAkF;AAClF,qDAAqD;AACrD,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,6BAA6B;AAC7B,EAAE;AACF,iEAAiE;AACjE,kFAAkF;AAClF,gFAAgF;AAChF,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,iFAAiF;AACjF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAChF,gCAAgC;AAChC,EAAE;AACF,oBAAoB;AACpB,yEAAyE;AACzE,wEAAwE;AACxE,iFAAiF;AACjF,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,UAAU,GAAG,oBAAoB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,MAAM,EAAE,CAAC;AACjF,kFAAkF;AAClF,uFAAuF;AACvF,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,sCAAsC,CAAC;AAC3F,MAAM,OAAO,GAAG,KAAK,CAAC;AACtB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAC7D,oFAAoF;AACpF,kFAAkF;AAClF,+FAA+F;AAC/F,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,GAAG,CAAC;AAqB3E,SAAS,aAAa;IACpB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAC7C,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;QAC5B,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE;QACxD,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;KACrB,CAAC,CAAC;AACL,CAAC;AAGD,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,aAAa,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YAC1E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,UAAU,CAAC,EAAU,EAAE,OAAe;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,eAAe,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,uEAAuE;YACvE,0EAA0E;YAC1E,+EAA+E;YAC/E,8EAA8E;YAC9E,+EAA+E;YAC/E,8EAA8E;YAC9E,yEAAyE;YACzE,yEAAyE;YACzE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAC7E,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAqC,CAAC;QACtF,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IACpG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;AAErE,KAAK,UAAU,MAAM,CAAC,MAAgB,EAAE,EAAU,EAAE,KAA8B;IAChF,+EAA+E;IAC/E,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,cAAc,IAAI,KAAK,CAAC,EAAE,CAAC;QACjG,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAC/D,CAAC;IACD,4EAA4E;IAC5E,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtG,IAAI,KAAK;QAAE,GAAG,CAAC,oBAAoB,EAAE,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAgB,EAChB,GAAe,EACf,KAAmB,EACnB,WAAwB;IAExB,6EAA6E;IAC7E,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO;IACtE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC5F,OAAO;IACT,CAAC;IAED,iFAAiF;IACjF,gFAAgF;IAChF,0CAA0C;IAC1C,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,gBAAgB;QAAE,OAAO;IAExD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAEtE,8EAA8E;IAC9E,iFAAiF;IACjF,6EAA6E;IAC7E,6EAA6E;IAC7E,mFAAmF;IACnF,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QAC3B,OAAO,CAAC,4DAA4D;IACtE,CAAC;IAED,iFAAiF;IACjF,mFAAmF;IACnF,8EAA8E;IAC9E,mFAAmF;IACnF,mFAAmF;IACnF,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC9F,cAAc,CAAC,GAAG,CAAC,kBAAkB,EAAE;YACrC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAG,GAAG,CAAC,OAAmC,IAAI,EAAE;YACvD,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,wEAAwE;IACxE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAE9F,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAClC,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAE,OAAO,EAAE,IAAK,CAAC,OAAO,IAAI,IAAI,EAAE,GAAG,EAAE,IAAK,CAAC,GAAG,IAAI,IAAI,EAAE,SAAS,EAAE,IAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;SACjH,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,qBAAqB;IACrB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,kBAAkB,EAAE,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;QACT,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,MAAgB;IAClC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAE3B,qFAAqF;IACrF,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;IAExC,iFAAiF;IACjF,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,eAAe,CAC3C,GAAG,EAAE,CAAC,MAAM;SACT,IAAI,CAAC,gBAAgB,CAAC;SACtB,MAAM,CAAC,yEAAyE,CAAC;SACjF,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACpB,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;SACvB,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,EAC1B,eAAe,CAChB,CAAC;IACF,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;IAC7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,8EAA8E;IAC9E,gFAAgF;IAChF,mFAAmF;IACnF,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAExD,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,sBAAsB,GAAG,CAAC,EAAE,WAAW,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzF,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClG,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,eAAe,CAAC,MAAgB,EAAE,IAAY;IAC3D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,eAAe,CAC3C,GAAG,EAAE,CAAC,MAAM;SACT,IAAI,CAAC,gBAAgB,CAAC;SACtB,MAAM,CAAC,4BAA4B,CAAC;SACpC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACpB,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC;SAChB,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;SACtB,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,EAChC,sBAAsB,CACvB,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,KAAK;QAAE,GAAG,CAAC,0CAA0C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,IAAsC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAU,EACV,MAAyB,EACzB,MAAuC,EACvC,KAAqB;IAErB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,KAAK,GAA4B,EAAE,MAAM,EAAE,CAAC;IAClD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;QAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IACnE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IAC/D,MAAM,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,sBAAsB;IACpC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,iFAAiF,CAAC,CAAC;QACvF,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC;IACD,GAAG,CAAC,oEAAoE,WAAW,EAAE,SAAS,MAAM,IAAI,CAAC,CAAC;IAC1G,MAAM,GAAG,GAAG,GAAG,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxG,CAAC,CAAC;IACF,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,OAAQ,EAA6B,CAAC,KAAK,KAAK,UAAU;QAAG,EAA4B,CAAC,KAAK,EAAE,CAAC;IACtG,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface InboxCommand {
|
|
2
|
+
id: string;
|
|
3
|
+
org_id: string;
|
|
4
|
+
kind: string;
|
|
5
|
+
payload: Record<string, unknown>;
|
|
6
|
+
enqueued_at: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Enqueue a command for an SDK session to poll. Idempotent on command id. Also
|
|
10
|
+
* records the id→session ownership (for ack authorization). cmd.org_id is the
|
|
11
|
+
* owning org; drainCommands only returns commands whose org matches the caller's.
|
|
12
|
+
*/
|
|
13
|
+
export declare function enqueueCommand(sessionKey: string, cmd: InboxCommand): void;
|
|
14
|
+
/**
|
|
15
|
+
* Drain pending commands for a session (returns + removes them). Evicts stale
|
|
16
|
+
* first. Only returns commands belonging to `orgId` — a cross-org command (which
|
|
17
|
+
* should never be enqueued here given the dispatcher's org-first filter) is
|
|
18
|
+
* dropped, never delivered.
|
|
19
|
+
*/
|
|
20
|
+
export declare function drainCommands(sessionKey: string, orgId: string): InboxCommand[];
|
|
21
|
+
/** Is this session_key one the inbox is tracking? (has pending commands) */
|
|
22
|
+
export declare function hasInbox(sessionKey: string): boolean;
|
|
23
|
+
/** Store (or replace) the capability token for a session. */
|
|
24
|
+
export declare function setSessionToken(sessionKey: string, token: string): void;
|
|
25
|
+
/** The capability token for a session, or undefined if none is registered. */
|
|
26
|
+
export declare function getSessionToken(sessionKey: string): string | undefined;
|
|
27
|
+
/** Forget a session's token (on 'ended' lifecycle). */
|
|
28
|
+
export declare function dropSessionToken(sessionKey: string): void;
|
|
29
|
+
/** The session_key a command id was enqueued for (for ack authorization). */
|
|
30
|
+
export declare function ackOwnerOf(id: string): string | undefined;
|
|
31
|
+
/** Forget an id→session ownership once the command has been acked/settled. */
|
|
32
|
+
export declare function clearAckOwner(id: string): void;
|
|
33
|
+
/** Total queued commands across all sessions (for /health + tests). */
|
|
34
|
+
export declare function inboxDepth(): number;
|
|
35
|
+
/** Test/shutdown helper — resets inboxes, tokens, and ack-owners. */
|
|
36
|
+
export declare function clearInbox(): void;
|
|
37
|
+
//# sourceMappingURL=agentInbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentInbox.d.ts","sourceRoot":"","sources":["../src/agentInbox.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB;AAyBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,CAQ1E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAK/E;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAGpD;AAMD,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvE;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEtE;AAED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzD;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE9C;AAeD,uEAAuE;AACvE,wBAAgB,UAAU,IAAI,MAAM,CAInC;AAED,qEAAqE;AACrE,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Agent command inbox — daemon-side delivery for SDK (non-broker) runtimes
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// The HQ→agent command dispatcher (agentCommands.ts) delivers `message` to
|
|
5
|
+
// claude-peers sessions via the broker, and answers `request_status` from the
|
|
6
|
+
// broker's live registry. But SDK-registered runtimes (hermes/openclaw/codex/…
|
|
7
|
+
// from @decibelsystems/tools/hq) aren't in the broker — they have no transport.
|
|
8
|
+
//
|
|
9
|
+
// This module bridges that gap WITHOUT giving the SDK any Supabase creds (the
|
|
10
|
+
// "no service_role in untrusted hands" rule holds): the dispatcher ENQUEUES a
|
|
11
|
+
// command targeting a known SDK session here; the SDK polls GET /agents/commands
|
|
12
|
+
// + acks POST /agents/commands/ack (both localhost-only); the daemon settles the
|
|
13
|
+
// hq.agent_commands row in Core via service_role on ack.
|
|
14
|
+
//
|
|
15
|
+
// IDENTITY — capability token, NOT a bare label (security review 2026-06-15):
|
|
16
|
+
// session_key is a GUESSABLE label, so localhost-bind alone would let any
|
|
17
|
+
// co-resident local runtime drain/ack ANOTHER runtime's commands (the SDK's whole
|
|
18
|
+
// premise is several runtimes side-by-side). So the daemon mints a per-session
|
|
19
|
+
// SECRET token at /agents/register, returns it to that one SDK process, and
|
|
20
|
+
// requires it on poll + ack. session_key says "which inbox"; the token proves
|
|
21
|
+
// "I'm the process that registered it." The org-id-first cross-org invariant is
|
|
22
|
+
// preserved here too: InboxCommand carries org_id and drainCommands filters on it,
|
|
23
|
+
// so even a token-authenticated poll only ever receives its own org's commands.
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// session_key → its pending commands. In-memory: the daemon is the single
|
|
26
|
+
// authority for sessions it hosts; a restart re-derives state from Core (pending
|
|
27
|
+
// rows get re-dispatched on the next tick).
|
|
28
|
+
const inboxes = new Map();
|
|
29
|
+
// session_key → its per-session capability token (the secret an SDK must present
|
|
30
|
+
// on poll/ack to prove it's the registrant). Minted by the HTTP register/heartbeat
|
|
31
|
+
// handler; verified there too (timing-safe). Wiped on a daemon restart — the SDK's
|
|
32
|
+
// next heartbeat re-mints, and it stores the fresh token from the response.
|
|
33
|
+
const sessionTokens = new Map();
|
|
34
|
+
// command id → the session_key it was enqueued for, with a timestamp for TTL
|
|
35
|
+
// eviction. The ack arrives AFTER drainCommands has already removed the command
|
|
36
|
+
// from the inbox, so the inbox itself can't tell us who owns an acked id — this
|
|
37
|
+
// map can. The ack handler maps id→session→token to authorize the settle.
|
|
38
|
+
const ackOwners = new Map();
|
|
39
|
+
// Drop inbox entries an SDK never polled, so a vanished runtime doesn't leak
|
|
40
|
+
// memory. Slightly longer than the command expiry (5min) so a slow poller still
|
|
41
|
+
// gets it; the dispatcher's expiry sweep settles the Core row regardless.
|
|
42
|
+
const INBOX_TTL_MS = 6 * 60_000;
|
|
43
|
+
const MAX_PER_SESSION = 100; // backstop against unbounded growth per session
|
|
44
|
+
/**
|
|
45
|
+
* Enqueue a command for an SDK session to poll. Idempotent on command id. Also
|
|
46
|
+
* records the id→session ownership (for ack authorization). cmd.org_id is the
|
|
47
|
+
* owning org; drainCommands only returns commands whose org matches the caller's.
|
|
48
|
+
*/
|
|
49
|
+
export function enqueueCommand(sessionKey, cmd) {
|
|
50
|
+
const list = inboxes.get(sessionKey) ?? [];
|
|
51
|
+
if (list.some((c) => c.id === cmd.id))
|
|
52
|
+
return; // already queued (keep first owner)
|
|
53
|
+
list.push(cmd);
|
|
54
|
+
// Trim oldest if a session somehow accumulates a flood (shouldn't happen).
|
|
55
|
+
while (list.length > MAX_PER_SESSION)
|
|
56
|
+
list.shift();
|
|
57
|
+
inboxes.set(sessionKey, list);
|
|
58
|
+
ackOwners.set(cmd.id, { sessionKey, at: cmd.enqueued_at });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Drain pending commands for a session (returns + removes them). Evicts stale
|
|
62
|
+
* first. Only returns commands belonging to `orgId` — a cross-org command (which
|
|
63
|
+
* should never be enqueued here given the dispatcher's org-first filter) is
|
|
64
|
+
* dropped, never delivered.
|
|
65
|
+
*/
|
|
66
|
+
export function drainCommands(sessionKey, orgId) {
|
|
67
|
+
evictStale();
|
|
68
|
+
const list = inboxes.get(sessionKey) ?? [];
|
|
69
|
+
inboxes.delete(sessionKey);
|
|
70
|
+
return list.filter((c) => c.org_id === orgId);
|
|
71
|
+
}
|
|
72
|
+
/** Is this session_key one the inbox is tracking? (has pending commands) */
|
|
73
|
+
export function hasInbox(sessionKey) {
|
|
74
|
+
const list = inboxes.get(sessionKey);
|
|
75
|
+
return !!list && list.length > 0;
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Per-session capability tokens (proof-of-possession for poll/ack)
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/** Store (or replace) the capability token for a session. */
|
|
81
|
+
export function setSessionToken(sessionKey, token) {
|
|
82
|
+
sessionTokens.set(sessionKey, token);
|
|
83
|
+
}
|
|
84
|
+
/** The capability token for a session, or undefined if none is registered. */
|
|
85
|
+
export function getSessionToken(sessionKey) {
|
|
86
|
+
return sessionTokens.get(sessionKey);
|
|
87
|
+
}
|
|
88
|
+
/** Forget a session's token (on 'ended' lifecycle). */
|
|
89
|
+
export function dropSessionToken(sessionKey) {
|
|
90
|
+
sessionTokens.delete(sessionKey);
|
|
91
|
+
}
|
|
92
|
+
/** The session_key a command id was enqueued for (for ack authorization). */
|
|
93
|
+
export function ackOwnerOf(id) {
|
|
94
|
+
return ackOwners.get(id)?.sessionKey;
|
|
95
|
+
}
|
|
96
|
+
/** Forget an id→session ownership once the command has been acked/settled. */
|
|
97
|
+
export function clearAckOwner(id) {
|
|
98
|
+
ackOwners.delete(id);
|
|
99
|
+
}
|
|
100
|
+
/** Evict commands + ack-owners older than the TTL (the dispatcher/DB sweep handles Core-side). */
|
|
101
|
+
function evictStale() {
|
|
102
|
+
const cutoff = Date.now() - INBOX_TTL_MS;
|
|
103
|
+
for (const [key, list] of inboxes) {
|
|
104
|
+
const kept = list.filter((c) => c.enqueued_at >= cutoff);
|
|
105
|
+
if (kept.length === 0)
|
|
106
|
+
inboxes.delete(key);
|
|
107
|
+
else if (kept.length !== list.length)
|
|
108
|
+
inboxes.set(key, kept);
|
|
109
|
+
}
|
|
110
|
+
for (const [id, owner] of ackOwners) {
|
|
111
|
+
if (owner.at < cutoff)
|
|
112
|
+
ackOwners.delete(id);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Total queued commands across all sessions (for /health + tests). */
|
|
116
|
+
export function inboxDepth() {
|
|
117
|
+
let n = 0;
|
|
118
|
+
for (const list of inboxes.values())
|
|
119
|
+
n += list.length;
|
|
120
|
+
return n;
|
|
121
|
+
}
|
|
122
|
+
/** Test/shutdown helper — resets inboxes, tokens, and ack-owners. */
|
|
123
|
+
export function clearInbox() {
|
|
124
|
+
inboxes.clear();
|
|
125
|
+
sessionTokens.clear();
|
|
126
|
+
ackOwners.clear();
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=agentInbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentInbox.js","sourceRoot":"","sources":["../src/agentInbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The daemon's host identity for presence + command targeting. Defaults to
|
|
3
|
+
* os.hostname() but is overridable via DECIBEL_PRESENCE_HOST — needed where the
|
|
4
|
+
* OS hostname isn't a stable/unique daemon identity (containers with shared
|
|
5
|
+
* hostnames, or two daemons on one machine, e.g. a rolling restart or a test
|
|
6
|
+
* harness). target_host on hq.agent_commands matches this, so it must be the same
|
|
7
|
+
* value the presence writer stamps. Shared by the dispatcher (agentCommands.ts).
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveHost(): string;
|
|
10
|
+
export interface LocalAgentRegistration {
|
|
11
|
+
session_key: string;
|
|
12
|
+
runtime: string;
|
|
13
|
+
agent?: string | null;
|
|
14
|
+
cwd?: string | null;
|
|
15
|
+
summary?: string | null;
|
|
16
|
+
meta?: Record<string, unknown>;
|
|
17
|
+
status?: 'active' | 'ended';
|
|
18
|
+
}
|
|
19
|
+
/** Strip control chars/null bytes and cap length. Empty-after-clean → null. */
|
|
20
|
+
export declare function sanitizeText(s: string | null | undefined, maxLen: number): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Flatten meta to display-safe primitives: strings cleaned + capped, numbers/
|
|
23
|
+
* booleans/null kept, nested objects/arrays dropped (HQ typeof-guards numeric
|
|
24
|
+
* meta and renders strings as text). If the result still exceeds META_MAX_BYTES,
|
|
25
|
+
* drop it entirely — the caller re-adds the trusted last_action_at.
|
|
26
|
+
*/
|
|
27
|
+
export declare function sanitizeMeta(meta: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Upsert a local-runtime session into hq.agent_sessions (register or heartbeat).
|
|
30
|
+
* Returns true on success, false if Supabase is unconfigured or the write failed.
|
|
31
|
+
* Reuses the presence writer's org config + cwd→project resolution.
|
|
32
|
+
*/
|
|
33
|
+
export declare function writeLocalAgentSession(reg: LocalAgentRegistration): Promise<boolean>;
|
|
34
|
+
/** Start the presence writer loop. Returns a stop function. No-ops if Supabase unconfigured. */
|
|
35
|
+
export declare function startPresenceWriter(): () => void;
|
|
36
|
+
//# sourceMappingURL=agentPresence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentPresence.d.ts","sourceRoot":"","sources":["../src/agentPresence.ts"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAwHD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAG/B,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC7B;AAmBD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIxF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU/F;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuC1F;AAED,gGAAgG;AAChG,wBAAgB,mBAAmB,IAAI,MAAM,IAAI,CAchD"}
|