reflectt-node 0.1.14 → 0.1.16
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 +54 -0
- package/defaults/TEAM-ROLES.starter.yaml +87 -0
- package/defaults/lane-templates/ops.json +32 -0
- package/defaults/lane-templates/workflow.json +32 -0
- package/defaults/reviewer-routing.yaml +34 -0
- package/dist/activationEvents.d.ts +7 -1
- package/dist/activationEvents.d.ts.map +1 -1
- package/dist/activationEvents.js +29 -3
- package/dist/activationEvents.js.map +1 -1
- package/dist/activity-stream-normalizer.d.ts +37 -0
- package/dist/activity-stream-normalizer.d.ts.map +1 -0
- package/dist/activity-stream-normalizer.js +101 -0
- package/dist/activity-stream-normalizer.js.map +1 -0
- package/dist/agent-exec-guardrail.d.ts +9 -0
- package/dist/agent-exec-guardrail.d.ts.map +1 -0
- package/dist/agent-exec-guardrail.js +24 -0
- package/dist/agent-exec-guardrail.js.map +1 -0
- package/dist/agent-exec-guardrail.test.d.ts +2 -0
- package/dist/agent-exec-guardrail.test.d.ts.map +1 -0
- package/dist/agent-exec-guardrail.test.js +55 -0
- package/dist/agent-exec-guardrail.test.js.map +1 -0
- package/dist/agent-interface.d.ts +137 -0
- package/dist/agent-interface.d.ts.map +1 -0
- package/dist/agent-interface.js +463 -0
- package/dist/agent-interface.js.map +1 -0
- package/dist/agent-notifications.d.ts +51 -0
- package/dist/agent-notifications.d.ts.map +1 -0
- package/dist/agent-notifications.js +104 -0
- package/dist/agent-notifications.js.map +1 -0
- package/dist/agent-runs.d.ts +31 -7
- package/dist/agent-runs.d.ts.map +1 -1
- package/dist/agent-runs.js +137 -28
- package/dist/agent-runs.js.map +1 -1
- package/dist/artifact-mirror.d.ts.map +1 -1
- package/dist/artifact-mirror.js +4 -1
- package/dist/artifact-mirror.js.map +1 -1
- package/dist/assignment.d.ts.map +1 -1
- package/dist/assignment.js +54 -2
- package/dist/assignment.js.map +1 -1
- package/dist/boardHealthWorker.d.ts.map +1 -1
- package/dist/boardHealthWorker.js +15 -1
- package/dist/boardHealthWorker.js.map +1 -1
- package/dist/canvas-auto-state.d.ts +58 -0
- package/dist/canvas-auto-state.d.ts.map +1 -0
- package/dist/canvas-auto-state.js +89 -0
- package/dist/canvas-auto-state.js.map +1 -0
- package/dist/canvas-routes.d.ts +36 -0
- package/dist/canvas-routes.d.ts.map +1 -0
- package/dist/canvas-routes.js +47 -0
- package/dist/canvas-routes.js.map +1 -0
- package/dist/capability-readiness.d.ts +28 -0
- package/dist/capability-readiness.d.ts.map +1 -0
- package/dist/capability-readiness.js +162 -0
- package/dist/capability-readiness.js.map +1 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +1 -0
- package/dist/channels.js.map +1 -1
- package/dist/cli.js +179 -4
- package/dist/cli.js.map +1 -1
- package/dist/cloud.d.ts +5 -0
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js +485 -18
- package/dist/cloud.js.map +1 -1
- package/dist/comms-routing-policy.d.ts +31 -0
- package/dist/comms-routing-policy.d.ts.map +1 -0
- package/dist/comms-routing-policy.js +128 -0
- package/dist/comms-routing-policy.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/continuity-loop.d.ts.map +1 -1
- package/dist/continuity-loop.js +26 -0
- package/dist/continuity-loop.js.map +1 -1
- package/dist/cost-enforcement.d.ts.map +1 -1
- package/dist/cost-enforcement.js +22 -0
- package/dist/cost-enforcement.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +56 -5
- package/dist/db.js.map +1 -1
- package/dist/doctor.js +2 -2
- package/dist/e2e-loop-proof.test.js +11 -1
- package/dist/e2e-loop-proof.test.js.map +1 -1
- package/dist/events.d.ts +4 -2
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +22 -1
- package/dist/events.js.map +1 -1
- package/dist/executionSweeper.d.ts.map +1 -1
- package/dist/executionSweeper.js +155 -0
- package/dist/executionSweeper.js.map +1 -1
- package/dist/health.d.ts +21 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +164 -19
- package/dist/health.js.map +1 -1
- package/dist/inbox.d.ts +4 -0
- package/dist/inbox.d.ts.map +1 -1
- package/dist/inbox.js +38 -1
- package/dist/inbox.js.map +1 -1
- package/dist/index.js +90 -14
- package/dist/index.js.map +1 -1
- package/dist/insight-auto-tagger.d.ts +58 -0
- package/dist/insight-auto-tagger.d.ts.map +1 -0
- package/dist/insight-auto-tagger.js +331 -0
- package/dist/insight-auto-tagger.js.map +1 -0
- package/dist/insight-task-bridge.d.ts +9 -0
- package/dist/insight-task-bridge.d.ts.map +1 -1
- package/dist/insight-task-bridge.js +43 -7
- package/dist/insight-task-bridge.js.map +1 -1
- package/dist/insights.d.ts +6 -0
- package/dist/insights.d.ts.map +1 -1
- package/dist/insights.js +13 -0
- package/dist/insights.js.map +1 -1
- package/dist/lane-config.d.ts.map +1 -1
- package/dist/lane-config.js +1 -0
- package/dist/lane-config.js.map +1 -1
- package/dist/lane-template-successor.d.ts +13 -0
- package/dist/lane-template-successor.d.ts.map +1 -0
- package/dist/lane-template-successor.js +132 -0
- package/dist/lane-template-successor.js.map +1 -0
- package/dist/local-whisper.d.ts +21 -0
- package/dist/local-whisper.d.ts.map +1 -0
- package/dist/local-whisper.js +137 -0
- package/dist/local-whisper.js.map +1 -0
- package/dist/macos-accessibility.d.ts +50 -0
- package/dist/macos-accessibility.d.ts.map +1 -0
- package/dist/macos-accessibility.js +185 -0
- package/dist/macos-accessibility.js.map +1 -0
- package/dist/manage.d.ts.map +1 -1
- package/dist/manage.js +47 -1
- package/dist/manage.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +123 -0
- package/dist/mcp.js.map +1 -1
- package/dist/notification-worker.d.ts +66 -0
- package/dist/notification-worker.d.ts.map +1 -0
- package/dist/notification-worker.js +232 -0
- package/dist/notification-worker.js.map +1 -0
- package/dist/openclaw-usage-sync.d.ts +28 -0
- package/dist/openclaw-usage-sync.d.ts.map +1 -0
- package/dist/openclaw-usage-sync.js +161 -0
- package/dist/openclaw-usage-sync.js.map +1 -0
- package/dist/policy.js +1 -1
- package/dist/policy.js.map +1 -1
- package/dist/pr-link-reconciler.d.ts +61 -0
- package/dist/pr-link-reconciler.d.ts.map +1 -0
- package/dist/pr-link-reconciler.js +127 -0
- package/dist/pr-link-reconciler.js.map +1 -0
- package/dist/preflight.js +2 -2
- package/dist/presence-narrator.d.ts +52 -0
- package/dist/presence-narrator.d.ts.map +1 -0
- package/dist/presence-narrator.js +193 -0
- package/dist/presence-narrator.js.map +1 -0
- package/dist/presence.d.ts +2 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +23 -3
- package/dist/presence.js.map +1 -1
- package/dist/product-observation-source.d.ts +52 -0
- package/dist/product-observation-source.d.ts.map +1 -0
- package/dist/product-observation-source.js +326 -0
- package/dist/product-observation-source.js.map +1 -0
- package/dist/reflection-automation.d.ts +25 -0
- package/dist/reflection-automation.d.ts.map +1 -1
- package/dist/reflection-automation.js +163 -42
- package/dist/reflection-automation.js.map +1 -1
- package/dist/review-autoclose.d.ts +62 -0
- package/dist/review-autoclose.d.ts.map +1 -0
- package/dist/review-autoclose.js +75 -0
- package/dist/review-autoclose.js.map +1 -0
- package/dist/routing-enforcement.test.js +32 -56
- package/dist/routing-enforcement.test.js.map +1 -1
- package/dist/sentry-webhook.d.ts +69 -0
- package/dist/sentry-webhook.d.ts.map +1 -0
- package/dist/sentry-webhook.js +88 -0
- package/dist/sentry-webhook.js.map +1 -0
- package/dist/sentry.d.ts +29 -0
- package/dist/sentry.d.ts.map +1 -0
- package/dist/sentry.js +86 -0
- package/dist/sentry.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5130 -233
- package/dist/server.js.map +1 -1
- package/dist/stale-candidate-reconciler.d.ts +69 -0
- package/dist/stale-candidate-reconciler.d.ts.map +1 -0
- package/dist/stale-candidate-reconciler.js +236 -0
- package/dist/stale-candidate-reconciler.js.map +1 -0
- package/dist/system-loop-state.d.ts +1 -1
- package/dist/system-loop-state.d.ts.map +1 -1
- package/dist/system-loop-state.js +1 -0
- package/dist/system-loop-state.js.map +1 -1
- package/dist/taskPrecheck.d.ts.map +1 -1
- package/dist/taskPrecheck.js +47 -2
- package/dist/taskPrecheck.js.map +1 -1
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +130 -0
- package/dist/tasks.js.map +1 -1
- package/dist/trust-events.d.ts +61 -0
- package/dist/trust-events.d.ts.map +1 -0
- package/dist/trust-events.js +148 -0
- package/dist/trust-events.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usage-tracking.d.ts +6 -0
- package/dist/usage-tracking.d.ts.map +1 -1
- package/dist/usage-tracking.js +14 -0
- package/dist/usage-tracking.js.map +1 -1
- package/dist/voice-sessions.d.ts +51 -0
- package/dist/voice-sessions.d.ts.map +1 -0
- package/dist/voice-sessions.js +143 -0
- package/dist/voice-sessions.js.map +1 -0
- package/dist/workflow-templates.d.ts.map +1 -1
- package/dist/workflow-templates.js +18 -3
- package/dist/workflow-templates.js.map +1 -1
- package/dist/working-contract.d.ts +22 -1
- package/dist/working-contract.d.ts.map +1 -1
- package/dist/working-contract.js +31 -2
- package/dist/working-contract.js.map +1 -1
- package/package.json +4 -4
- package/public/dashboard.js +12 -4
- package/public/docs.md +98 -10
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Delivery Worker
|
|
3
|
+
*
|
|
4
|
+
* Polls agent_notifications for pending rows and delivers them to active agents.
|
|
5
|
+
* Respects interruption budget: agents with budget=closed skip non-urgent notifications.
|
|
6
|
+
*
|
|
7
|
+
* Delivery surface: chat DM (channel: 'notifications') or task comment when task_id is set.
|
|
8
|
+
* Marks notifications as delivered (status='delivered') or failed after one retry.
|
|
9
|
+
*
|
|
10
|
+
* task-1773659376304
|
|
11
|
+
*/
|
|
12
|
+
import type Database from 'better-sqlite3';
|
|
13
|
+
import type { PresenceManager } from './presence.js';
|
|
14
|
+
export type InterruptionBudget = 'open' | 'focused' | 'closed';
|
|
15
|
+
export interface DeliveryTarget {
|
|
16
|
+
agent: string;
|
|
17
|
+
isActive: boolean;
|
|
18
|
+
budget: InterruptionBudget;
|
|
19
|
+
}
|
|
20
|
+
export interface DeliveryResult {
|
|
21
|
+
notificationId: string;
|
|
22
|
+
delivered: boolean;
|
|
23
|
+
reason?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface NotificationWorkerConfig {
|
|
26
|
+
/** Poll interval in ms (default: 30000 = 30s) */
|
|
27
|
+
pollIntervalMs?: number;
|
|
28
|
+
/** Max notifications to process per tick (default: 20) */
|
|
29
|
+
batchSize?: number;
|
|
30
|
+
/** Max age before expiring undelivered notifications (default: 24h) */
|
|
31
|
+
expireAfterMs?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class NotificationDeliveryWorker {
|
|
34
|
+
private readonly getDb;
|
|
35
|
+
private readonly presenceManager;
|
|
36
|
+
private readonly sendMessage;
|
|
37
|
+
private readonly postTaskComment?;
|
|
38
|
+
private timer;
|
|
39
|
+
private readonly pollIntervalMs;
|
|
40
|
+
private readonly batchSize;
|
|
41
|
+
private readonly expireAfterMs;
|
|
42
|
+
private stats;
|
|
43
|
+
constructor(getDb: () => Database.Database, presenceManager: PresenceManager, sendMessage: (opts: {
|
|
44
|
+
from: string;
|
|
45
|
+
content: string;
|
|
46
|
+
channel: string;
|
|
47
|
+
metadata?: Record<string, unknown>;
|
|
48
|
+
}) => Promise<unknown>, postTaskComment?: ((taskId: string, author: string, content: string) => Promise<unknown>) | undefined, config?: NotificationWorkerConfig);
|
|
49
|
+
/** Start the worker loop */
|
|
50
|
+
start(): void;
|
|
51
|
+
/** Stop the worker loop */
|
|
52
|
+
stop(): void;
|
|
53
|
+
/** Get worker stats */
|
|
54
|
+
getStats(): {
|
|
55
|
+
running: boolean;
|
|
56
|
+
delivered: number;
|
|
57
|
+
skipped: number;
|
|
58
|
+
failed: number;
|
|
59
|
+
expired: number;
|
|
60
|
+
ticks: number;
|
|
61
|
+
lastTickAt: number;
|
|
62
|
+
};
|
|
63
|
+
/** Process one batch of pending notifications */
|
|
64
|
+
tick(): Promise<DeliveryResult[]>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=notification-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-worker.d.ts","sourceRoot":"","sources":["../src/notification-worker.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAIpD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,kBAAkB,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAmDD,qBAAa,0BAA0B;IAenC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAjBnC,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,KAAK,CAOZ;gBAGkB,KAAK,EAAE,MAAM,QAAQ,CAAC,QAAQ,EAC9B,eAAe,EAAE,eAAe,EAChC,WAAW,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EAC/H,eAAe,CAAC,GAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,aAAA,EACxG,MAAM,CAAC,EAAE,wBAAwB;IAOnC,4BAA4B;IAC5B,KAAK,IAAI,IAAI;IAWb,2BAA2B;IAC3B,IAAI,IAAI,IAAI;IAQZ,uBAAuB;IACvB,QAAQ;;;;;;;;;IAIR,iDAAiD;IAC3C,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;CA+HxC"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) Reflectt AI
|
|
3
|
+
// ── Interruption budget ────────────────────────────────────────────────────
|
|
4
|
+
/** Map presence status to interruption budget */
|
|
5
|
+
function presenceToBudget(status) {
|
|
6
|
+
switch (status) {
|
|
7
|
+
case 'working': return 'focused';
|
|
8
|
+
case 'reviewing': return 'focused';
|
|
9
|
+
case 'blocked': return 'open';
|
|
10
|
+
case 'waiting': return 'open';
|
|
11
|
+
case 'idle': return 'open';
|
|
12
|
+
case 'offline': return 'closed';
|
|
13
|
+
default: return 'open';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Whether a notification can interrupt at this budget level */
|
|
17
|
+
function canInterrupt(priority, budget) {
|
|
18
|
+
if (budget === 'open')
|
|
19
|
+
return true;
|
|
20
|
+
if (budget === 'focused')
|
|
21
|
+
return priority === 'critical' || priority === 'high';
|
|
22
|
+
// closed: only critical
|
|
23
|
+
return priority === 'critical';
|
|
24
|
+
}
|
|
25
|
+
// ── Delivery helpers ───────────────────────────────────────────────────────
|
|
26
|
+
function formatNotificationMessage(notification) {
|
|
27
|
+
const emoji = notification.priority === 'critical' ? '🚨' :
|
|
28
|
+
notification.priority === 'high' ? '🔴' :
|
|
29
|
+
notification.priority === 'medium' ? '📋' : 'ℹ️';
|
|
30
|
+
const source = notification.source_agent ? ` from @${notification.source_agent}` : '';
|
|
31
|
+
const taskRef = notification.task_id ? ` (${notification.task_id})` : '';
|
|
32
|
+
const lines = [
|
|
33
|
+
`${emoji} **${notification.title}**${source}${taskRef}`,
|
|
34
|
+
];
|
|
35
|
+
if (notification.body) {
|
|
36
|
+
lines.push(notification.body);
|
|
37
|
+
}
|
|
38
|
+
lines.push(`_ID: ${notification.id} · Ack: POST /agent-notifications/${notification.id}/ack { decision: "seen"|"accept"|"defer"|"dismiss" }_`);
|
|
39
|
+
return lines.join('\n');
|
|
40
|
+
}
|
|
41
|
+
// ── Worker class ───────────────────────────────────────────────────────────
|
|
42
|
+
export class NotificationDeliveryWorker {
|
|
43
|
+
getDb;
|
|
44
|
+
presenceManager;
|
|
45
|
+
sendMessage;
|
|
46
|
+
postTaskComment;
|
|
47
|
+
timer = null;
|
|
48
|
+
pollIntervalMs;
|
|
49
|
+
batchSize;
|
|
50
|
+
expireAfterMs;
|
|
51
|
+
stats = {
|
|
52
|
+
delivered: 0,
|
|
53
|
+
skipped: 0,
|
|
54
|
+
failed: 0,
|
|
55
|
+
expired: 0,
|
|
56
|
+
ticks: 0,
|
|
57
|
+
lastTickAt: 0,
|
|
58
|
+
};
|
|
59
|
+
constructor(getDb, presenceManager, sendMessage, postTaskComment, config) {
|
|
60
|
+
this.getDb = getDb;
|
|
61
|
+
this.presenceManager = presenceManager;
|
|
62
|
+
this.sendMessage = sendMessage;
|
|
63
|
+
this.postTaskComment = postTaskComment;
|
|
64
|
+
this.pollIntervalMs = config?.pollIntervalMs ?? 30_000;
|
|
65
|
+
this.batchSize = config?.batchSize ?? 20;
|
|
66
|
+
this.expireAfterMs = config?.expireAfterMs ?? 24 * 60 * 60 * 1000;
|
|
67
|
+
}
|
|
68
|
+
/** Start the worker loop */
|
|
69
|
+
start() {
|
|
70
|
+
if (this.timer)
|
|
71
|
+
return;
|
|
72
|
+
console.log(`[NotifWorker] Started (poll every ${this.pollIntervalMs / 1000}s, batch ${this.batchSize})`);
|
|
73
|
+
// Run first tick after a short delay to let server warm up
|
|
74
|
+
setTimeout(() => this.tick().catch(err => console.error('[NotifWorker] tick error:', err)), 5000);
|
|
75
|
+
this.timer = setInterval(() => {
|
|
76
|
+
this.tick().catch(err => console.error('[NotifWorker] tick error:', err));
|
|
77
|
+
}, this.pollIntervalMs);
|
|
78
|
+
this.timer.unref();
|
|
79
|
+
}
|
|
80
|
+
/** Stop the worker loop */
|
|
81
|
+
stop() {
|
|
82
|
+
if (this.timer) {
|
|
83
|
+
clearInterval(this.timer);
|
|
84
|
+
this.timer = null;
|
|
85
|
+
console.log('[NotifWorker] Stopped');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Get worker stats */
|
|
89
|
+
getStats() {
|
|
90
|
+
return { ...this.stats, running: this.timer !== null };
|
|
91
|
+
}
|
|
92
|
+
/** Process one batch of pending notifications */
|
|
93
|
+
async tick() {
|
|
94
|
+
this.stats.ticks++;
|
|
95
|
+
this.stats.lastTickAt = Date.now();
|
|
96
|
+
const db = this.getDb();
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const results = [];
|
|
99
|
+
// 1. Expire old notifications first
|
|
100
|
+
const expired = db.prepare(`
|
|
101
|
+
UPDATE agent_notifications
|
|
102
|
+
SET status = 'expired'
|
|
103
|
+
WHERE status = 'pending' AND expires_at IS NOT NULL AND expires_at < ?
|
|
104
|
+
`).run(now);
|
|
105
|
+
if (expired.changes > 0) {
|
|
106
|
+
this.stats.expired += expired.changes;
|
|
107
|
+
console.log(`[NotifWorker] Expired ${expired.changes} notification(s)`);
|
|
108
|
+
}
|
|
109
|
+
// Also expire very old notifications without explicit expires_at
|
|
110
|
+
const staleExpired = db.prepare(`
|
|
111
|
+
UPDATE agent_notifications
|
|
112
|
+
SET status = 'expired'
|
|
113
|
+
WHERE status = 'pending' AND expires_at IS NULL AND created_at < ?
|
|
114
|
+
`).run(now - this.expireAfterMs);
|
|
115
|
+
if (staleExpired.changes > 0) {
|
|
116
|
+
this.stats.expired += staleExpired.changes;
|
|
117
|
+
}
|
|
118
|
+
// 2. Fetch pending notifications, ordered by priority then age
|
|
119
|
+
const pending = db.prepare(`
|
|
120
|
+
SELECT * FROM agent_notifications
|
|
121
|
+
WHERE status = 'pending'
|
|
122
|
+
ORDER BY
|
|
123
|
+
CASE priority
|
|
124
|
+
WHEN 'critical' THEN 0
|
|
125
|
+
WHEN 'high' THEN 1
|
|
126
|
+
WHEN 'medium' THEN 2
|
|
127
|
+
WHEN 'low' THEN 3
|
|
128
|
+
END,
|
|
129
|
+
created_at ASC
|
|
130
|
+
LIMIT ?
|
|
131
|
+
`).all(this.batchSize);
|
|
132
|
+
if (pending.length === 0)
|
|
133
|
+
return results;
|
|
134
|
+
// 3. Deliver each notification
|
|
135
|
+
for (const row of pending) {
|
|
136
|
+
const notification = deserializeRow(row);
|
|
137
|
+
const targetAgent = notification.target_agent;
|
|
138
|
+
// Check agent presence
|
|
139
|
+
const presence = this.presenceManager.getPresence(targetAgent);
|
|
140
|
+
const budget = presence ? presenceToBudget(presence.status) : 'closed';
|
|
141
|
+
// Budget check
|
|
142
|
+
if (!canInterrupt(notification.priority, budget)) {
|
|
143
|
+
this.stats.skipped++;
|
|
144
|
+
results.push({ notificationId: notification.id, delivered: false, reason: `budget=${budget}, priority=${notification.priority}` });
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
// Attempt delivery
|
|
148
|
+
let delivered = false;
|
|
149
|
+
let deliveryError;
|
|
150
|
+
try {
|
|
151
|
+
if (notification.task_id && this.postTaskComment) {
|
|
152
|
+
// Deliver as task comment when task_id is set
|
|
153
|
+
await this.postTaskComment(notification.task_id, 'system', formatNotificationMessage(notification));
|
|
154
|
+
delivered = true;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Deliver as DM via chat
|
|
158
|
+
await this.sendMessage({
|
|
159
|
+
from: 'system',
|
|
160
|
+
content: formatNotificationMessage(notification),
|
|
161
|
+
channel: 'notifications',
|
|
162
|
+
metadata: { notification_id: notification.id, target_agent: targetAgent },
|
|
163
|
+
});
|
|
164
|
+
delivered = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
deliveryError = err instanceof Error ? err.message : String(err);
|
|
169
|
+
console.error(`[NotifWorker] Delivery failed for ${notification.id}:`, deliveryError);
|
|
170
|
+
// Retry once
|
|
171
|
+
try {
|
|
172
|
+
await this.sendMessage({
|
|
173
|
+
from: 'system',
|
|
174
|
+
content: formatNotificationMessage(notification),
|
|
175
|
+
channel: 'notifications',
|
|
176
|
+
metadata: { notification_id: notification.id, target_agent: targetAgent, retry: true },
|
|
177
|
+
});
|
|
178
|
+
delivered = true;
|
|
179
|
+
deliveryError = undefined;
|
|
180
|
+
}
|
|
181
|
+
catch (retryErr) {
|
|
182
|
+
deliveryError = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Update status
|
|
186
|
+
if (delivered) {
|
|
187
|
+
db.prepare(`
|
|
188
|
+
UPDATE agent_notifications
|
|
189
|
+
SET status = 'delivered', ack_at = ?
|
|
190
|
+
WHERE id = ?
|
|
191
|
+
`).run(now, notification.id);
|
|
192
|
+
this.stats.delivered++;
|
|
193
|
+
results.push({ notificationId: notification.id, delivered: true });
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
db.prepare(`
|
|
197
|
+
UPDATE agent_notifications
|
|
198
|
+
SET status = 'failed', metadata = json_set(COALESCE(metadata, '{}'), '$.delivery_error', ?)
|
|
199
|
+
WHERE id = ?
|
|
200
|
+
`).run(deliveryError ?? 'unknown', notification.id);
|
|
201
|
+
this.stats.failed++;
|
|
202
|
+
results.push({ notificationId: notification.id, delivered: false, reason: deliveryError });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (results.length > 0) {
|
|
206
|
+
const delivered = results.filter(r => r.delivered).length;
|
|
207
|
+
const skipped = results.filter(r => !r.delivered).length;
|
|
208
|
+
console.log(`[NotifWorker] Processed ${results.length}: ${delivered} delivered, ${skipped} skipped/failed`);
|
|
209
|
+
}
|
|
210
|
+
return results;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ── Row deserialization ────────────────────────────────────────────────────
|
|
214
|
+
function deserializeRow(row) {
|
|
215
|
+
return {
|
|
216
|
+
id: String(row.id),
|
|
217
|
+
target_agent: String(row.target_agent),
|
|
218
|
+
source_agent: row.source_agent ? String(row.source_agent) : null,
|
|
219
|
+
type: String(row.type),
|
|
220
|
+
title: String(row.title),
|
|
221
|
+
body: row.body ? String(row.body) : null,
|
|
222
|
+
priority: String(row.priority),
|
|
223
|
+
status: String(row.status),
|
|
224
|
+
ack_decision: row.ack_decision ? String(row.ack_decision) : null,
|
|
225
|
+
ack_at: typeof row.ack_at === 'number' ? row.ack_at : null,
|
|
226
|
+
task_id: row.task_id ? String(row.task_id) : null,
|
|
227
|
+
metadata: row.metadata ? (typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata) : null,
|
|
228
|
+
created_at: typeof row.created_at === 'number' ? row.created_at : Date.now(),
|
|
229
|
+
expires_at: typeof row.expires_at === 'number' ? row.expires_at : null,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=notification-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-worker.js","sourceRoot":"","sources":["../src/notification-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openclaw-usage-sync.ts
|
|
3
|
+
*
|
|
4
|
+
* Periodic sync job that reads OpenClaw agent session files and ingests
|
|
5
|
+
* token/cost data into the reflectt-node model_usage table via recordUsage().
|
|
6
|
+
*
|
|
7
|
+
* Problem: 16+ agents running via OpenClaw report $0 in the cloud usage
|
|
8
|
+
* dashboard because they never call POST /usage/report. Their token/cost
|
|
9
|
+
* data IS stored in ~/.openclaw/agents/{agent}/sessions/sessions.json.
|
|
10
|
+
*
|
|
11
|
+
* Solution: Walk that directory tree, read sessions.json for every agent,
|
|
12
|
+
* extract per-session token counts + model, and ingest any sessions not
|
|
13
|
+
* yet recorded (dedup via api_source = "openclaw:{sessionId}").
|
|
14
|
+
*
|
|
15
|
+
* Wired up in server.ts: startOpenClawUsageSync() / stopOpenClawUsageSync().
|
|
16
|
+
*/
|
|
17
|
+
interface SyncResult {
|
|
18
|
+
agentsScanned: number;
|
|
19
|
+
sessionsFound: number;
|
|
20
|
+
sessionsIngested: number;
|
|
21
|
+
sessionsSkipped: number;
|
|
22
|
+
errors: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function syncOpenClawUsage(): Promise<SyncResult>;
|
|
25
|
+
export declare function startOpenClawUsageSync(): void;
|
|
26
|
+
export declare function stopOpenClawUsageSync(): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=openclaw-usage-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-usage-sync.d.ts","sourceRoot":"","sources":["../src/openclaw-usage-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA4BH,UAAU,UAAU;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAwBD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAsF7D;AAMD,wBAAgB,sBAAsB,IAAI,IAAI,CAiC7C;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openclaw-usage-sync.ts
|
|
3
|
+
*
|
|
4
|
+
* Periodic sync job that reads OpenClaw agent session files and ingests
|
|
5
|
+
* token/cost data into the reflectt-node model_usage table via recordUsage().
|
|
6
|
+
*
|
|
7
|
+
* Problem: 16+ agents running via OpenClaw report $0 in the cloud usage
|
|
8
|
+
* dashboard because they never call POST /usage/report. Their token/cost
|
|
9
|
+
* data IS stored in ~/.openclaw/agents/{agent}/sessions/sessions.json.
|
|
10
|
+
*
|
|
11
|
+
* Solution: Walk that directory tree, read sessions.json for every agent,
|
|
12
|
+
* extract per-session token counts + model, and ingest any sessions not
|
|
13
|
+
* yet recorded (dedup via api_source = "openclaw:{sessionId}").
|
|
14
|
+
*
|
|
15
|
+
* Wired up in server.ts: startOpenClawUsageSync() / stopOpenClawUsageSync().
|
|
16
|
+
*/
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { homedir } from 'os';
|
|
19
|
+
import { promises as fs, existsSync } from 'fs';
|
|
20
|
+
import { recordUsage } from './usage-tracking.js';
|
|
21
|
+
import { getDb } from './db.js';
|
|
22
|
+
// ── Config ────────────────────────────────────────────────────────────────
|
|
23
|
+
const OPENCLAW_HOME = process.env.OPENCLAW_HOME || join(homedir(), '.openclaw');
|
|
24
|
+
const AGENTS_DIR = join(OPENCLAW_HOME, 'agents');
|
|
25
|
+
const SYNC_INTERVAL_MS = 5 * 60 * 1000; // every 5 minutes
|
|
26
|
+
// ── Dedup check ───────────────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Returns the set of sessionIds already present in model_usage as
|
|
29
|
+
* api_source = "openclaw:{sessionId}".
|
|
30
|
+
*/
|
|
31
|
+
function getIngestedSessionIds() {
|
|
32
|
+
const db = getDb();
|
|
33
|
+
const rows = db.prepare(`SELECT api_source FROM model_usage WHERE api_source LIKE 'openclaw:%'`).all();
|
|
34
|
+
const ids = new Set();
|
|
35
|
+
for (const row of rows) {
|
|
36
|
+
const id = row.api_source.replace('openclaw:', '');
|
|
37
|
+
if (id)
|
|
38
|
+
ids.add(id);
|
|
39
|
+
}
|
|
40
|
+
return ids;
|
|
41
|
+
}
|
|
42
|
+
// ── Core sync ─────────────────────────────────────────────────────────────
|
|
43
|
+
export async function syncOpenClawUsage() {
|
|
44
|
+
const result = {
|
|
45
|
+
agentsScanned: 0,
|
|
46
|
+
sessionsFound: 0,
|
|
47
|
+
sessionsIngested: 0,
|
|
48
|
+
sessionsSkipped: 0,
|
|
49
|
+
errors: [],
|
|
50
|
+
};
|
|
51
|
+
if (!existsSync(AGENTS_DIR)) {
|
|
52
|
+
return result; // OpenClaw not installed or wrong path
|
|
53
|
+
}
|
|
54
|
+
let agentDirs;
|
|
55
|
+
try {
|
|
56
|
+
agentDirs = await fs.readdir(AGENTS_DIR);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
result.errors.push(`Failed to read agents dir: ${err.message}`);
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
// Snapshot ingested session IDs once upfront to avoid per-row queries
|
|
63
|
+
const ingestedIds = getIngestedSessionIds();
|
|
64
|
+
for (const agentName of agentDirs) {
|
|
65
|
+
const sessionsJsonPath = join(AGENTS_DIR, agentName, 'sessions', 'sessions.json');
|
|
66
|
+
if (!existsSync(sessionsJsonPath))
|
|
67
|
+
continue;
|
|
68
|
+
result.agentsScanned++;
|
|
69
|
+
let sessionsData;
|
|
70
|
+
try {
|
|
71
|
+
const raw = await fs.readFile(sessionsJsonPath, 'utf8');
|
|
72
|
+
sessionsData = JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
result.errors.push(`${agentName}: failed to parse sessions.json — ${err.message}`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
for (const [, session] of Object.entries(sessionsData)) {
|
|
79
|
+
const sessionId = session.sessionId;
|
|
80
|
+
if (!sessionId)
|
|
81
|
+
continue;
|
|
82
|
+
if (!session.model)
|
|
83
|
+
continue;
|
|
84
|
+
// Skip sessions with no tokens (e.g. freshly created, not yet used)
|
|
85
|
+
const inputTokens = session.inputTokens ?? 0;
|
|
86
|
+
const outputTokens = session.outputTokens ?? 0;
|
|
87
|
+
if (inputTokens === 0 && outputTokens === 0)
|
|
88
|
+
continue;
|
|
89
|
+
result.sessionsFound++;
|
|
90
|
+
// Dedup: skip if already ingested
|
|
91
|
+
if (ingestedIds.has(sessionId)) {
|
|
92
|
+
result.sessionsSkipped++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
recordUsage({
|
|
97
|
+
agent: agentName,
|
|
98
|
+
model: session.model,
|
|
99
|
+
provider: session.modelProvider ?? 'openclaw',
|
|
100
|
+
input_tokens: inputTokens,
|
|
101
|
+
output_tokens: outputTokens,
|
|
102
|
+
// cost_usd not stored in sessions.json aggregate — estimateCost() fills this
|
|
103
|
+
category: 'other',
|
|
104
|
+
timestamp: session.updatedAt ?? Date.now(),
|
|
105
|
+
api_source: `openclaw:${sessionId}`,
|
|
106
|
+
metadata: {
|
|
107
|
+
session_id: sessionId,
|
|
108
|
+
cache_read_tokens: session.cacheRead ?? 0,
|
|
109
|
+
cache_write_tokens: session.cacheWrite ?? 0,
|
|
110
|
+
total_tokens: session.totalTokens ?? (inputTokens + outputTokens),
|
|
111
|
+
sync_source: 'openclaw-usage-sync',
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
ingestedIds.add(sessionId); // prevent double-ingest within same run
|
|
115
|
+
result.sessionsIngested++;
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
result.errors.push(`${agentName}/${sessionId}: record failed — ${err.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
// ── Periodic timer ────────────────────────────────────────────────────────
|
|
125
|
+
let _syncTimer = null;
|
|
126
|
+
export function startOpenClawUsageSync() {
|
|
127
|
+
if (_syncTimer)
|
|
128
|
+
return; // already running
|
|
129
|
+
// Run once at startup (deferred 10s to let DB settle)
|
|
130
|
+
const startupDelay = setTimeout(() => {
|
|
131
|
+
syncOpenClawUsage().then(result => {
|
|
132
|
+
if (result.sessionsIngested > 0 || result.errors.length > 0) {
|
|
133
|
+
console.log(`[openclaw-usage-sync] startup: agents=${result.agentsScanned} ` +
|
|
134
|
+
`ingested=${result.sessionsIngested} skipped=${result.sessionsSkipped}` +
|
|
135
|
+
(result.errors.length > 0 ? ` errors=${result.errors.length}` : ''));
|
|
136
|
+
}
|
|
137
|
+
}).catch(err => {
|
|
138
|
+
console.warn('[openclaw-usage-sync] startup sync failed:', err.message);
|
|
139
|
+
});
|
|
140
|
+
}, 10_000);
|
|
141
|
+
startupDelay.unref();
|
|
142
|
+
// Periodic sync every 5 minutes
|
|
143
|
+
_syncTimer = setInterval(() => {
|
|
144
|
+
syncOpenClawUsage().then(result => {
|
|
145
|
+
if (result.sessionsIngested > 0) {
|
|
146
|
+
console.log(`[openclaw-usage-sync] periodic: agents=${result.agentsScanned} ` +
|
|
147
|
+
`ingested=${result.sessionsIngested} skipped=${result.sessionsSkipped}`);
|
|
148
|
+
}
|
|
149
|
+
}).catch(err => {
|
|
150
|
+
console.warn('[openclaw-usage-sync] periodic sync failed:', err.message);
|
|
151
|
+
});
|
|
152
|
+
}, SYNC_INTERVAL_MS);
|
|
153
|
+
_syncTimer.unref();
|
|
154
|
+
}
|
|
155
|
+
export function stopOpenClawUsageSync() {
|
|
156
|
+
if (_syncTimer) {
|
|
157
|
+
clearInterval(_syncTimer);
|
|
158
|
+
_syncTimer = null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=openclaw-usage-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-usage-sync.js","sourceRoot":"","sources":["../src/openclaw-usage-sync.ts"],"names":[],"mappings":"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"}
|
package/dist/policy.js
CHANGED
|
@@ -31,7 +31,7 @@ export const DEFAULT_POLICY = {
|
|
|
31
31
|
suppressRecentMin: 20,
|
|
32
32
|
shipCooldownMin: 30,
|
|
33
33
|
activeTaskMaxAgeMin: 180,
|
|
34
|
-
excluded: ['ryan', 'diag'],
|
|
34
|
+
excluded: ['ryan', 'diag', 'pm', 'coo', 'qa', 'shield', 'harmony', 'bookkeeper', 'legal-counsel'],
|
|
35
35
|
},
|
|
36
36
|
cadenceWatchdog: {
|
|
37
37
|
enabled: true,
|
package/dist/policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4BAA4B;AAE5B;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAiI3C,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,UAAU,EAAE;QACV,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,mBAAmB;KAC9B;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE;QACf,iBAAiB,EAAE,EAAE;QACrB,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,GAAG;QACxB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,4BAA4B;AAE5B;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAiI3C,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,UAAU,EAAE;QACV,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,mBAAmB;KAC9B;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE;QACf,iBAAiB,EAAE,EAAE;QACrB,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,GAAG;QACxB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,CAAC;KAClG;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,2FAA2F;QAC3F,UAAU,EAAE,EAAE;QACd,eAAe,EAAE,EAAE;QACnB,oBAAoB,EAAE,GAAG;QACzB,gBAAgB,EAAE,EAAE;KACrB;IACD,sBAAsB,EAAE,GAAG;IAC3B,aAAa,EAAE;QACb,OAAO,EAAE,IAAI;QACb,mFAAmF;QACnF,QAAQ,EAAE,CAAC;QACX,WAAW,EAAE,EAAE;QACf,iBAAiB,EAAE,CAAC;KACrB;IACD,WAAW,EAAE;QACX,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QACzB,sBAAsB,EAAE,GAAG;QAC3B,wBAAwB,EAAE,IAAI;QAC9B,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;QAChC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QACpC,aAAa,EAAE,KAAK;QACpB,MAAM,EAAE,KAAK;QACb,iBAAiB,EAAE,CAAC;KACrB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,CAAC;QACX,qFAAqF;QACrF,mFAAmF;QACnF,MAAM,EAAE,EAAE;QACV,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,SAAS;KACnB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,gBAAgB,EAAE,CAAC;QACnB,mBAAmB,EAAE,CAAC;QACtB,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,SAAS;QAClB,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,EAAE;QACjB,mBAAmB,EAAE,IAAI;KAC1B;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,mBAAmB,EAAE,EAAE,EAAS,4CAA4C;QAC5E,oBAAoB,EAAE,EAAE,EAAQ,kCAAkC;QAClE,qBAAqB,EAAE,IAAI;QAC3B,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,KAAK;KACd;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;QAC1C,eAAe,EAAE,MAAM;QACvB,UAAU,EAAE,IAAI;QAChB,iBAAiB,EAAE,EAAE,GAAG,MAAM;KAC/B;IACD,UAAU,EAAE;QACV,cAAc,EAAE,SAAS;QACzB,eAAe,EAAE,SAAS;QAC1B,aAAa,EAAE,KAAK;KACrB;IACD,eAAe,EAAE;QACf,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,EAAE;QACZ,iBAAiB,EAAE,SAAS;KAC7B;CACF,CAAA;AAED,8EAA8E;AAE9E,MAAM,aAAa;IACT,MAAM,CAAc;IACpB,QAAQ,CAAQ;IAChB,MAAM,GAAG,KAAK,CAAA;IAEtB;QACE,IAAI,CAAC,QAAQ,GAAG,OAAO,CACrB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CACvE,CAAA;QACD,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAA;IAC/C,CAAC;IAED,0EAA0E;IAC1E,IAAI;QACF,oBAAoB;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAA;YACvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,+CAA+C;QACjD,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,iBAAiB,EAAE,CAAA;QAExB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,OAAO,IAAI,CAAC,GAAG,EAAE,CAAA;IACnB,CAAC;IAED,0CAA0C;IAC1C,GAAG;QACD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,EAAE,CAAA;QAC7B,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,MAAiC;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,OAAO,IAAI,CAAC,GAAG,EAAE,CAAA;IACnB,CAAC;IAED,uCAAuC;IACvC,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,CAAA;QAC7C,IAAI,CAAC,iBAAiB,EAAE,CAAA;QACxB,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,OAAO,IAAI,CAAC,GAAG,EAAE,CAAA;IACnB,CAAC;IAED,gCAAgC;IAChC,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,0EAA0E;IAElE,OAAO;QACb,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACtD,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;QACnF,CAAC;QAAC,MAAM,CAAC;YACP,0CAA0C;QAC5C,CAAC;IACH,CAAC;IAED,0EAA0E;IAElE,KAAK,CAAC,IAAS,EAAE,OAAY;QACnC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;QAEpC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;YAC1B,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAQ;YAEjC,IACE,KAAK,KAAK,IAAI;mBACX,OAAO,KAAK,KAAK,QAAQ;mBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;mBACrB,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;mBAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;mBACpB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAC9B,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;YAC9C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,0EAA0E;IAElE,iBAAiB;QACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAA;QAEvB,cAAc;QACd,IAAI,GAAG,CAAC,4BAA4B,KAAK,SAAS;YAChD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,4BAA4B,KAAK,OAAO,CAAA;QAC/E,IAAI,GAAG,CAAC,+BAA+B;YACrC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;QAChF,IAAI,GAAG,CAAC,6BAA6B;YACnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;QAC5E,IAAI,GAAG,CAAC,uBAAuB;YAC7B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,uBAAuB,CAAA;QAE/D,aAAa;QACb,IAAI,GAAG,CAAC,kBAAkB,KAAK,SAAS;YACtC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,GAAG,CAAC,kBAAkB,KAAK,OAAO,CAAA;QACpE,IAAI,GAAG,CAAC,mBAAmB;YACzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QACjE,IAAI,GAAG,CAAC,uBAAuB;YAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;QACzE,IAAI,GAAG,CAAC,uBAAuB;YAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;QACzE,IAAI,GAAG,CAAC,8BAA8B;YACpC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QACtF,IAAI,GAAG,CAAC,4BAA4B;YAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;QAClF,IAAI,GAAG,CAAC,kCAAkC;YACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAC5F,IAAI,GAAG,CAAC,kBAAkB;YACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAErH,mBAAmB;QACnB,IAAI,GAAG,CAAC,wBAAwB,KAAK,SAAS;YAC5C,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,GAAG,GAAG,CAAC,wBAAwB,KAAK,OAAO,CAAA;QAChF,IAAI,GAAG,CAAC,mBAAmB;YACzB,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QAC1E,IAAI,GAAG,CAAC,yBAAyB;YAC/B,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QACrF,IAAI,GAAG,CAAC,gCAAgC;YACtC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QACjG,IAAI,GAAG,CAAC,0BAA0B;YAChC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;QAEvF,cAAc;QACd,IAAI,GAAG,CAAC,yBAAyB;YAC/B,IAAI,CAAC,MAAM,CAAC,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QAE5E,iBAAiB;QACjB,IAAI,GAAG,CAAC,sBAAsB,KAAK,SAAS;YAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,GAAG,GAAG,CAAC,sBAAsB,KAAK,OAAO,CAAA;QAC5E,IAAI,GAAG,CAAC,wBAAwB;YAC9B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;QAC3E,IAAI,GAAG,CAAC,2BAA2B;YACjC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;QACjF,IAAI,GAAG,CAAC,kCAAkC;YACxC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAE9F,eAAe;QACf,IAAI,GAAG,CAAC,oBAAoB,KAAK,SAAS;YACxC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,GAAG,GAAG,CAAC,oBAAoB,KAAK,OAAO,CAAA;QACxE,IAAI,GAAG,CAAC,wBAAwB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;QAC3E,IAAI,GAAG,CAAC,4BAA4B;YAClC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;QAC3F,IAAI,GAAG,CAAC,8BAA8B;YACpC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC/F,IAAI,GAAG,CAAC,+BAA+B;YACrC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;QACxF,IAAI,GAAG,CAAC,+BAA+B;YACrC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;QACxF,IAAI,GAAG,CAAC,2BAA2B;YACjC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,GAAG,GAAG,CAAC,2BAA2B,CAAA;QACzE,IAAI,GAAG,CAAC,oBAAoB,KAAK,SAAS;YACxC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,CAAC,oBAAoB,KAAK,MAAM,CAAA;QACtE,IAAI,GAAG,CAAC,wBAAwB;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;IACpF,CAAC;CACF;AAQD,8EAA8E;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale PR-link reconciler.
|
|
3
|
+
*
|
|
4
|
+
* Problem: validating tasks hold a `review_packet.pr_url` pointing at an open PR.
|
|
5
|
+
* When the PR merges, the task still shows the open-PR URL. The duplicate-closure
|
|
6
|
+
* gate requires `canonical_pr` + `canonical_commit` — but agents have to set these
|
|
7
|
+
* manually, causing friction and "duplicate closure" gate failures.
|
|
8
|
+
*
|
|
9
|
+
* Solution: a background sweep that:
|
|
10
|
+
* 1. Finds validating tasks with a PR URL in metadata
|
|
11
|
+
* 2. Calls `gh pr view --json state,mergeCommit` for each
|
|
12
|
+
* 3. For merged PRs: stamps `metadata.canonical_pr` + `metadata.canonical_commit`
|
|
13
|
+
* so the gate can auto-pass on next review attempt
|
|
14
|
+
*
|
|
15
|
+
* Safety:
|
|
16
|
+
* - Read-only GitHub call (gh CLI, no write)
|
|
17
|
+
* - Only patches metadata (never changes task status)
|
|
18
|
+
* - Best-effort: failures are logged, never thrown
|
|
19
|
+
* - Idempotent: re-running is safe (already-stamped tasks are skipped)
|
|
20
|
+
* - Rate-limited: one gh CLI call per task, max 50 tasks/sweep
|
|
21
|
+
*
|
|
22
|
+
* task-1773493504539-chjbrrww3
|
|
23
|
+
*/
|
|
24
|
+
import type { Task } from './types.js';
|
|
25
|
+
export interface ReconcileResult {
|
|
26
|
+
taskId: string;
|
|
27
|
+
prUrl: string;
|
|
28
|
+
action: 'stamped' | 'already_canonical' | 'not_merged' | 'error' | 'skipped';
|
|
29
|
+
mergeCommit?: string;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ReconcileSweepResult {
|
|
33
|
+
swept: number;
|
|
34
|
+
stamped: number;
|
|
35
|
+
skipped: number;
|
|
36
|
+
errors: number;
|
|
37
|
+
results: ReconcileResult[];
|
|
38
|
+
durationMs: number;
|
|
39
|
+
}
|
|
40
|
+
/** Extract PR URL from task metadata (qa_bundle.review_packet or review_handoff). */
|
|
41
|
+
export declare function extractPrUrl(task: Task): string | null;
|
|
42
|
+
/** Check if task already has canonical refs stamped. */
|
|
43
|
+
export declare function hasCanonicalRefs(task: Task): boolean;
|
|
44
|
+
interface PrMergeState {
|
|
45
|
+
merged: boolean;
|
|
46
|
+
mergeCommit: string | null;
|
|
47
|
+
headSha: string | null;
|
|
48
|
+
}
|
|
49
|
+
/** Fetch merge state for a PR using gh CLI. Returns null if gh unavailable or network error. */
|
|
50
|
+
export declare function fetchPrMergeState(prUrl: string): PrMergeState | null;
|
|
51
|
+
export interface ReconcilerDeps {
|
|
52
|
+
getValidatingTasks: () => Task[];
|
|
53
|
+
patchTaskMetadata: (taskId: string, patch: Record<string, unknown>) => void;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Run one reconcile sweep.
|
|
57
|
+
* Finds validating tasks with PR URLs, checks merge state, stamps canonical refs.
|
|
58
|
+
*/
|
|
59
|
+
export declare function runPrLinkReconcileSweep(deps: ReconcilerDeps, maxTasks?: number): ReconcileSweepResult;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=pr-link-reconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-link-reconciler.d.ts","sourceRoot":"","sources":["../src/pr-link-reconciler.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAEtC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,SAAS,GAAG,mBAAmB,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,CAAA;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAgBtD;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAIpD;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAqBpE;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,IAAI,EAAE,CAAA;IAChC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAC5E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,SAAK,GAAG,oBAAoB,CA8DjG"}
|