@sideboard-ai/core 0.1.122 → 0.1.125
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/agents/cursor-runner.cjs +50 -9
- package/dist/agents/cursor-runner.js +13 -12
- package/dist/{agents-DRJMECCE.js → agents-DCXXLTXF.js} +2 -2
- package/dist/{agents-U5PWL3AJ.js → agents-DPR2TDNF.js} +1 -1
- package/dist/{chunk-QHST4DZQ.js → chunk-7Y3AYQWT.js} +1 -1
- package/dist/{chunk-EQHXMN7O.js → chunk-ED27HCPV.js} +9 -80
- package/dist/{chunk-KRM3A5UK.js → chunk-GKY2GR2J.js} +8 -63
- package/dist/{chunk-3M5CVKHK.js → chunk-IUJOI7KK.js} +41 -0
- package/dist/index.cjs +6 -80
- package/dist/index.d.cts +73 -95
- package/dist/index.d.ts +73 -95
- package/dist/index.js +6 -12
- package/dist/mcp/run-stdio.cjs +4 -59
- package/dist/mcp/run-stdio.js +4 -4
- package/dist/{orchestrator-EYU7OUFA.js → orchestrator-FZYM7I42.js} +2 -2
- package/dist/{orchestrator-JE5MSVED.js → orchestrator-HN3LYHFN.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-OEBYW4TO.js → chunk-JNAIKICO.js} +0 -0
|
@@ -349,6 +349,46 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
349
349
|
if (!(delta >= 0) || !Number.isFinite(delta)) return void 0;
|
|
350
350
|
return delta / 100;
|
|
351
351
|
}
|
|
352
|
+
function costUsdFromRunSnapshot(usage, runId) {
|
|
353
|
+
if (!usage?.runs?.length || !runId.trim()) return void 0;
|
|
354
|
+
const row = usage.runs.find((r) => r.runId === runId);
|
|
355
|
+
const cents = preferredCursorCostCents(row?.cost);
|
|
356
|
+
return cents != null ? cents / 100 : void 0;
|
|
357
|
+
}
|
|
358
|
+
function cursorGetUsageRunId(runId) {
|
|
359
|
+
const id = runId?.trim();
|
|
360
|
+
if (!id || id.startsWith("run-")) return void 0;
|
|
361
|
+
return id;
|
|
362
|
+
}
|
|
363
|
+
var CURSOR_COST_POLL_MS = [0, 400, 800, 1600, 3200];
|
|
364
|
+
function sleep(ms) {
|
|
365
|
+
return new Promise((resolve) => {
|
|
366
|
+
setTimeout(resolve, ms);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
async function fetchCursorTurnCostUsd(getUsage, usageBefore, opts) {
|
|
370
|
+
const lookupRunId = cursorGetUsageRunId(opts?.runId);
|
|
371
|
+
for (const delay of CURSOR_COST_POLL_MS) {
|
|
372
|
+
if (delay > 0) await sleep(delay);
|
|
373
|
+
try {
|
|
374
|
+
if (lookupRunId) {
|
|
375
|
+
const scoped = await getUsage({ runId: lookupRunId });
|
|
376
|
+
const direct = costUsdFromRunSnapshot(scoped, lookupRunId);
|
|
377
|
+
if (direct != null) return direct;
|
|
378
|
+
}
|
|
379
|
+
const after = await getUsage();
|
|
380
|
+
const delta = turnCostUsdFromCursorUsage(usageBefore, after);
|
|
381
|
+
if (delta != null) return delta;
|
|
382
|
+
} catch (err) {
|
|
383
|
+
if (isCursorUsageUnavailableError(err)) return void 0;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return void 0;
|
|
387
|
+
}
|
|
388
|
+
function isCursorUsageUnavailableError(err) {
|
|
389
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
390
|
+
return /feature_unavailable|feature unavailable|not available for your account/i.test(msg);
|
|
391
|
+
}
|
|
352
392
|
function cursorCostOnlyUsageEvent(costUsd) {
|
|
353
393
|
return {
|
|
354
394
|
type: "usage",
|
|
@@ -782,6 +822,7 @@ async function main() {
|
|
|
782
822
|
usageBefore = await agent.getUsage();
|
|
783
823
|
} catch {
|
|
784
824
|
}
|
|
825
|
+
let lastUsageRunId;
|
|
785
826
|
const run2 = await sendPrompt(agent, {
|
|
786
827
|
onDelta: ({ update }) => {
|
|
787
828
|
bump();
|
|
@@ -807,6 +848,10 @@ async function main() {
|
|
|
807
848
|
activity
|
|
808
849
|
)) {
|
|
809
850
|
bump();
|
|
851
|
+
const sdkMsg = msg;
|
|
852
|
+
if (sdkMsg.type === "usage" && typeof sdkMsg.run_id === "string" && sdkMsg.run_id.trim()) {
|
|
853
|
+
lastUsageRunId = sdkMsg.run_id.trim();
|
|
854
|
+
}
|
|
810
855
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
811
856
|
stream.push(event);
|
|
812
857
|
}
|
|
@@ -828,15 +873,11 @@ async function main() {
|
|
|
828
873
|
}
|
|
829
874
|
if (result.status === "cancelled") return 0;
|
|
830
875
|
try {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
});
|
|
837
|
-
usageAfter = await agent.getUsage();
|
|
838
|
-
costUsd = turnCostUsdFromCursorUsage(usageBefore, usageAfter);
|
|
839
|
-
}
|
|
876
|
+
const costUsd = await fetchCursorTurnCostUsd(
|
|
877
|
+
(opts) => agent.getUsage(opts),
|
|
878
|
+
usageBefore,
|
|
879
|
+
{ runId: lastUsageRunId }
|
|
880
|
+
);
|
|
840
881
|
if (costUsd != null) {
|
|
841
882
|
emit(cursorCostOnlyUsageEvent(costUsd));
|
|
842
883
|
}
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
cursorDeltaToEvents,
|
|
11
11
|
cursorSdkMessageToEvents,
|
|
12
12
|
ensureCursorRipgrepPath,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "../chunk-
|
|
13
|
+
fetchCursorTurnCostUsd,
|
|
14
|
+
formatUnknownDetail
|
|
15
|
+
} from "../chunk-IUJOI7KK.js";
|
|
16
16
|
import {
|
|
17
17
|
dropNestedElectronEnvFromProcess
|
|
18
18
|
} from "../chunk-4TR3HZFT.js";
|
|
@@ -266,6 +266,7 @@ async function main() {
|
|
|
266
266
|
usageBefore = await agent.getUsage();
|
|
267
267
|
} catch {
|
|
268
268
|
}
|
|
269
|
+
let lastUsageRunId;
|
|
269
270
|
const run = await sendPrompt(agent, {
|
|
270
271
|
onDelta: ({ update }) => {
|
|
271
272
|
bump();
|
|
@@ -291,6 +292,10 @@ async function main() {
|
|
|
291
292
|
activity
|
|
292
293
|
)) {
|
|
293
294
|
bump();
|
|
295
|
+
const sdkMsg = msg;
|
|
296
|
+
if (sdkMsg.type === "usage" && typeof sdkMsg.run_id === "string" && sdkMsg.run_id.trim()) {
|
|
297
|
+
lastUsageRunId = sdkMsg.run_id.trim();
|
|
298
|
+
}
|
|
294
299
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
295
300
|
stream.push(event);
|
|
296
301
|
}
|
|
@@ -312,15 +317,11 @@ async function main() {
|
|
|
312
317
|
}
|
|
313
318
|
if (result.status === "cancelled") return 0;
|
|
314
319
|
try {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
});
|
|
321
|
-
usageAfter = await agent.getUsage();
|
|
322
|
-
costUsd = turnCostUsdFromCursorUsage(usageBefore, usageAfter);
|
|
323
|
-
}
|
|
320
|
+
const costUsd = await fetchCursorTurnCostUsd(
|
|
321
|
+
(opts) => agent.getUsage(opts),
|
|
322
|
+
usageBefore,
|
|
323
|
+
{ runId: lastUsageRunId }
|
|
324
|
+
);
|
|
324
325
|
if (costUsd != null) {
|
|
325
326
|
emit(cursorCostOnlyUsageEvent(costUsd));
|
|
326
327
|
}
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
resolveCursorModelId,
|
|
29
29
|
resolveLoginCommand,
|
|
30
30
|
resolveQuotaFallbackAgent
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-7Y3AYQWT.js";
|
|
32
32
|
import "./chunk-EKIDHL2T.js";
|
|
33
33
|
import {
|
|
34
34
|
ORCHESTRATOR_AGENT_KINDS,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
parseCursorRunnerLine,
|
|
43
43
|
preferredCursorCostCents,
|
|
44
44
|
turnCostUsdFromCursorUsage
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-IUJOI7KK.js";
|
|
46
46
|
import "./chunk-UAVZ2JSO.js";
|
|
47
47
|
import "./chunk-FKOIHGKV.js";
|
|
48
48
|
import "./chunk-FXQPY2KU.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
stripBrightsyNdjsonNoise,
|
|
19
19
|
sumUsageList,
|
|
20
20
|
toolDescription
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-7Y3AYQWT.js";
|
|
22
22
|
import {
|
|
23
23
|
addWorkspace,
|
|
24
24
|
ensureWorkspace,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
shouldRetryFailedAgentTurn,
|
|
65
65
|
summarizeTurnStderr,
|
|
66
66
|
turnFailChatText
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-IUJOI7KK.js";
|
|
68
68
|
import {
|
|
69
69
|
releaseCaffeinateHoldForThread
|
|
70
70
|
} from "./chunk-DCOZABNT.js";
|
|
@@ -364,26 +364,9 @@ function storePath3() {
|
|
|
364
364
|
function watchId(teamId, channelId, ts) {
|
|
365
365
|
return `${teamId}:${channelId}:${ts}`;
|
|
366
366
|
}
|
|
367
|
-
function badgeId(teamId, userId) {
|
|
368
|
-
return `${teamId}:${userId}`;
|
|
369
|
-
}
|
|
370
367
|
function slackArchiveUrl(channelId, ts) {
|
|
371
368
|
return `https://slack.com/archives/${channelId}/p${ts.replace(".", "")}`;
|
|
372
369
|
}
|
|
373
|
-
function initialsFromName(name) {
|
|
374
|
-
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
375
|
-
if (parts.length === 0) return "?";
|
|
376
|
-
if (parts.length === 1) {
|
|
377
|
-
const w = parts[0];
|
|
378
|
-
return (w.slice(0, 2) || "?").toUpperCase();
|
|
379
|
-
}
|
|
380
|
-
return `${parts[0][0] ?? ""}${parts[parts.length - 1][0] ?? ""}`.toUpperCase();
|
|
381
|
-
}
|
|
382
|
-
function hueFromId(id) {
|
|
383
|
-
let h = 0;
|
|
384
|
-
for (const c of id) h = h * 31 + c.charCodeAt(0) >>> 0;
|
|
385
|
-
return h % 360;
|
|
386
|
-
}
|
|
387
370
|
function tsNewer(a, b) {
|
|
388
371
|
return Number(a) > Number(b);
|
|
389
372
|
}
|
|
@@ -456,7 +439,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
456
439
|
await continueOnReply(threadId, prompt);
|
|
457
440
|
return;
|
|
458
441
|
}
|
|
459
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
442
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-HN3LYHFN.js");
|
|
460
443
|
await getOrchestrator2().send(threadId, prompt);
|
|
461
444
|
} catch {
|
|
462
445
|
}
|
|
@@ -540,7 +523,6 @@ function recordSlackOutboundWatch(input) {
|
|
|
540
523
|
sourceThreadId: input.sourceThreadId?.trim() || void 0,
|
|
541
524
|
postedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
542
525
|
lastSeenTs: ts,
|
|
543
|
-
unread: false,
|
|
544
526
|
permalink: slackArchiveUrl(channelId, ts),
|
|
545
527
|
injectedReplyTs: [],
|
|
546
528
|
replies: []
|
|
@@ -627,49 +609,9 @@ async function fetchMessages(token, watch, fetchImpl) {
|
|
|
627
609
|
}
|
|
628
610
|
return out;
|
|
629
611
|
}
|
|
630
|
-
function
|
|
631
|
-
const unread = readStore3().filter((w) => w.unread && w.replyUserId && w.permalink);
|
|
632
|
-
const byUser = /* @__PURE__ */ new Map();
|
|
633
|
-
for (const w of unread) {
|
|
634
|
-
const id = badgeId(w.teamId, w.replyUserId);
|
|
635
|
-
const prev = byUser.get(id);
|
|
636
|
-
if (!prev || tsNewer(w.replyTs || "", prev.replyTs || "")) {
|
|
637
|
-
byUser.set(id, w);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
return [...byUser.entries()].map(([id, w]) => {
|
|
641
|
-
const userName = w.replyUserName || w.toLabel || "Slack";
|
|
642
|
-
return {
|
|
643
|
-
id,
|
|
644
|
-
userId: w.replyUserId,
|
|
645
|
-
userName,
|
|
646
|
-
initials: initialsFromName(userName),
|
|
647
|
-
hue: hueFromId(w.replyUserId),
|
|
648
|
-
permalink: w.permalink || slackArchiveUrl(w.channelId, w.replyTs || w.ts),
|
|
649
|
-
label: w.toLabel,
|
|
650
|
-
preview: w.replyPreview,
|
|
651
|
-
repliedAt: w.replyTs || w.postedAt
|
|
652
|
-
};
|
|
653
|
-
}).sort((a, b) => b.repliedAt.localeCompare(a.repliedAt));
|
|
654
|
-
}
|
|
655
|
-
function dismissSlackReplyBadge(badgeKey) {
|
|
656
|
-
const key = badgeKey.trim();
|
|
657
|
-
const watches = readStore3().map((w) => {
|
|
658
|
-
if (!w.unread || !w.replyUserId) return w;
|
|
659
|
-
if (badgeId(w.teamId, w.replyUserId) !== key) return w;
|
|
660
|
-
return { ...w, unread: false };
|
|
661
|
-
});
|
|
662
|
-
writeStore2(watches);
|
|
663
|
-
return listSlackReplyBadges();
|
|
664
|
-
}
|
|
665
|
-
function permalinkForSlackReplyBadge(badgeKey) {
|
|
666
|
-
return listSlackReplyBadges().find((b) => b.id === badgeKey)?.permalink ?? null;
|
|
667
|
-
}
|
|
668
|
-
async function refreshSlackReplyBadges(opts) {
|
|
612
|
+
async function pollSlackOutboundWatches(opts) {
|
|
669
613
|
const now = opts?.now ?? Date.now();
|
|
670
|
-
if (!opts?.force && now - lastPollMs < POLL_INTERVAL_MS)
|
|
671
|
-
return listSlackReplyBadges();
|
|
672
|
-
}
|
|
614
|
+
if (!opts?.force && now - lastPollMs < POLL_INTERVAL_MS) return;
|
|
673
615
|
lastPollMs = now;
|
|
674
616
|
const existing = readStore3();
|
|
675
617
|
let watches = pruneWatches(existing, now);
|
|
@@ -680,7 +622,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
680
622
|
if (!ws) continue;
|
|
681
623
|
let token;
|
|
682
624
|
try {
|
|
683
|
-
token = slackTokenFor(ws, "
|
|
625
|
+
token = slackTokenFor(ws, "write");
|
|
684
626
|
} catch {
|
|
685
627
|
continue;
|
|
686
628
|
}
|
|
@@ -690,9 +632,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
690
632
|
const injected = new Set(watch.injectedReplyTs ?? []);
|
|
691
633
|
const collected = [...watch.replies ?? []];
|
|
692
634
|
let lastSeenTs = watch.lastSeenTs;
|
|
693
|
-
let latestUser;
|
|
694
635
|
let latestName;
|
|
695
|
-
let latestText = "";
|
|
696
636
|
let latestPermalink = watch.permalink;
|
|
697
637
|
let newlyInjected = 0;
|
|
698
638
|
for (const msg of replies) {
|
|
@@ -718,9 +658,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
718
658
|
text: msg.text ?? ""
|
|
719
659
|
};
|
|
720
660
|
if (!collected.some((r) => r.ts === ts)) collected.push(reply);
|
|
721
|
-
latestUser = user;
|
|
722
661
|
latestName = replyUserName;
|
|
723
|
-
latestText = reply.text;
|
|
724
662
|
latestPermalink = permalink;
|
|
725
663
|
if (injected.has(ts)) {
|
|
726
664
|
lastSeenTs = ts;
|
|
@@ -751,11 +689,6 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
751
689
|
watches[i] = {
|
|
752
690
|
...watch,
|
|
753
691
|
lastSeenTs,
|
|
754
|
-
unread: true,
|
|
755
|
-
replyUserId: latestUser,
|
|
756
|
-
replyUserName: latestName,
|
|
757
|
-
replyTs: lastSeenTs,
|
|
758
|
-
replyPreview: latestText.slice(0, 140),
|
|
759
692
|
permalink: latestPermalink,
|
|
760
693
|
injectedReplyTs: [...injected],
|
|
761
694
|
replies: collected.slice(-MAX_REPLIES_PER_WATCH)
|
|
@@ -763,7 +696,6 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
763
696
|
changed = true;
|
|
764
697
|
}
|
|
765
698
|
if (changed) writeStore2(watches);
|
|
766
|
-
return listSlackReplyBadges();
|
|
767
699
|
}
|
|
768
700
|
|
|
769
701
|
// src/orchestrator/orchestrator.ts
|
|
@@ -2487,7 +2419,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2487
2419
|
return readThread(thread.id) ?? thread;
|
|
2488
2420
|
}
|
|
2489
2421
|
async function listLinearIssues(agent, repoPath) {
|
|
2490
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2422
|
+
const { getAdapter: getAdapter2 } = await import("./agents-DCXXLTXF.js");
|
|
2491
2423
|
await requireAgent(agent, { requireLinear: true });
|
|
2492
2424
|
const adapter = getAdapter2(agent);
|
|
2493
2425
|
if (!adapter.listLinearIssues) {
|
|
@@ -5156,7 +5088,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5156
5088
|
${prompt}`;
|
|
5157
5089
|
}
|
|
5158
5090
|
async function defaultDeps() {
|
|
5159
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5091
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-HN3LYHFN.js");
|
|
5160
5092
|
const orch = getOrchestrator2();
|
|
5161
5093
|
return {
|
|
5162
5094
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7145,10 +7077,7 @@ export {
|
|
|
7145
7077
|
formatSlackReplyContinuePrompt,
|
|
7146
7078
|
listSlackOutboundWatches,
|
|
7147
7079
|
recordSlackOutboundWatch,
|
|
7148
|
-
|
|
7149
|
-
dismissSlackReplyBadge,
|
|
7150
|
-
permalinkForSlackReplyBadge,
|
|
7151
|
-
refreshSlackReplyBadges,
|
|
7080
|
+
pollSlackOutboundWatches,
|
|
7152
7081
|
applyPromptCacheTtlEnv,
|
|
7153
7082
|
spawnAgentTurn,
|
|
7154
7083
|
AGENT_GIT_ACTIONS,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
summarizeTurnStderr,
|
|
30
30
|
toolDescription,
|
|
31
31
|
turnFailChatText
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-JNAIKICO.js";
|
|
33
33
|
import {
|
|
34
34
|
addWorkspace,
|
|
35
35
|
ensureWorkspace,
|
|
@@ -303,26 +303,9 @@ function storePath3() {
|
|
|
303
303
|
function watchId(teamId, channelId, ts) {
|
|
304
304
|
return `${teamId}:${channelId}:${ts}`;
|
|
305
305
|
}
|
|
306
|
-
function badgeId(teamId, userId) {
|
|
307
|
-
return `${teamId}:${userId}`;
|
|
308
|
-
}
|
|
309
306
|
function slackArchiveUrl(channelId, ts) {
|
|
310
307
|
return `https://slack.com/archives/${channelId}/p${ts.replace(".", "")}`;
|
|
311
308
|
}
|
|
312
|
-
function initialsFromName(name) {
|
|
313
|
-
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
314
|
-
if (parts.length === 0) return "?";
|
|
315
|
-
if (parts.length === 1) {
|
|
316
|
-
const w = parts[0];
|
|
317
|
-
return (w.slice(0, 2) || "?").toUpperCase();
|
|
318
|
-
}
|
|
319
|
-
return `${parts[0][0] ?? ""}${parts[parts.length - 1][0] ?? ""}`.toUpperCase();
|
|
320
|
-
}
|
|
321
|
-
function hueFromId(id) {
|
|
322
|
-
let h = 0;
|
|
323
|
-
for (const c of id) h = h * 31 + c.charCodeAt(0) >>> 0;
|
|
324
|
-
return h % 360;
|
|
325
|
-
}
|
|
326
309
|
function tsNewer(a, b) {
|
|
327
310
|
return Number(a) > Number(b);
|
|
328
311
|
}
|
|
@@ -395,7 +378,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
395
378
|
await continueOnReply(threadId, prompt);
|
|
396
379
|
return;
|
|
397
380
|
}
|
|
398
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
381
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-FZYM7I42.js");
|
|
399
382
|
await getOrchestrator2().send(threadId, prompt);
|
|
400
383
|
} catch {
|
|
401
384
|
}
|
|
@@ -479,7 +462,6 @@ function recordSlackOutboundWatch(input) {
|
|
|
479
462
|
sourceThreadId: input.sourceThreadId?.trim() || void 0,
|
|
480
463
|
postedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
481
464
|
lastSeenTs: ts,
|
|
482
|
-
unread: false,
|
|
483
465
|
permalink: slackArchiveUrl(channelId, ts),
|
|
484
466
|
injectedReplyTs: [],
|
|
485
467
|
replies: []
|
|
@@ -566,36 +548,9 @@ async function fetchMessages(token, watch, fetchImpl) {
|
|
|
566
548
|
}
|
|
567
549
|
return out;
|
|
568
550
|
}
|
|
569
|
-
function
|
|
570
|
-
const unread = readStore3().filter((w) => w.unread && w.replyUserId && w.permalink);
|
|
571
|
-
const byUser = /* @__PURE__ */ new Map();
|
|
572
|
-
for (const w of unread) {
|
|
573
|
-
const id = badgeId(w.teamId, w.replyUserId);
|
|
574
|
-
const prev = byUser.get(id);
|
|
575
|
-
if (!prev || tsNewer(w.replyTs || "", prev.replyTs || "")) {
|
|
576
|
-
byUser.set(id, w);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
return [...byUser.entries()].map(([id, w]) => {
|
|
580
|
-
const userName = w.replyUserName || w.toLabel || "Slack";
|
|
581
|
-
return {
|
|
582
|
-
id,
|
|
583
|
-
userId: w.replyUserId,
|
|
584
|
-
userName,
|
|
585
|
-
initials: initialsFromName(userName),
|
|
586
|
-
hue: hueFromId(w.replyUserId),
|
|
587
|
-
permalink: w.permalink || slackArchiveUrl(w.channelId, w.replyTs || w.ts),
|
|
588
|
-
label: w.toLabel,
|
|
589
|
-
preview: w.replyPreview,
|
|
590
|
-
repliedAt: w.replyTs || w.postedAt
|
|
591
|
-
};
|
|
592
|
-
}).sort((a, b) => b.repliedAt.localeCompare(a.repliedAt));
|
|
593
|
-
}
|
|
594
|
-
async function refreshSlackReplyBadges(opts) {
|
|
551
|
+
async function pollSlackOutboundWatches(opts) {
|
|
595
552
|
const now = opts?.now ?? Date.now();
|
|
596
|
-
if (!opts?.force && now - lastPollMs < POLL_INTERVAL_MS)
|
|
597
|
-
return listSlackReplyBadges();
|
|
598
|
-
}
|
|
553
|
+
if (!opts?.force && now - lastPollMs < POLL_INTERVAL_MS) return;
|
|
599
554
|
lastPollMs = now;
|
|
600
555
|
const existing = readStore3();
|
|
601
556
|
let watches = pruneWatches(existing, now);
|
|
@@ -606,7 +561,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
606
561
|
if (!ws) continue;
|
|
607
562
|
let token;
|
|
608
563
|
try {
|
|
609
|
-
token = slackTokenFor(ws, "
|
|
564
|
+
token = slackTokenFor(ws, "write");
|
|
610
565
|
} catch {
|
|
611
566
|
continue;
|
|
612
567
|
}
|
|
@@ -616,9 +571,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
616
571
|
const injected = new Set(watch.injectedReplyTs ?? []);
|
|
617
572
|
const collected = [...watch.replies ?? []];
|
|
618
573
|
let lastSeenTs = watch.lastSeenTs;
|
|
619
|
-
let latestUser;
|
|
620
574
|
let latestName;
|
|
621
|
-
let latestText = "";
|
|
622
575
|
let latestPermalink = watch.permalink;
|
|
623
576
|
let newlyInjected = 0;
|
|
624
577
|
for (const msg of replies) {
|
|
@@ -644,9 +597,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
644
597
|
text: msg.text ?? ""
|
|
645
598
|
};
|
|
646
599
|
if (!collected.some((r) => r.ts === ts)) collected.push(reply);
|
|
647
|
-
latestUser = user;
|
|
648
600
|
latestName = replyUserName;
|
|
649
|
-
latestText = reply.text;
|
|
650
601
|
latestPermalink = permalink;
|
|
651
602
|
if (injected.has(ts)) {
|
|
652
603
|
lastSeenTs = ts;
|
|
@@ -677,11 +628,6 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
677
628
|
watches[i] = {
|
|
678
629
|
...watch,
|
|
679
630
|
lastSeenTs,
|
|
680
|
-
unread: true,
|
|
681
|
-
replyUserId: latestUser,
|
|
682
|
-
replyUserName: latestName,
|
|
683
|
-
replyTs: lastSeenTs,
|
|
684
|
-
replyPreview: latestText.slice(0, 140),
|
|
685
631
|
permalink: latestPermalink,
|
|
686
632
|
injectedReplyTs: [...injected],
|
|
687
633
|
replies: collected.slice(-MAX_REPLIES_PER_WATCH)
|
|
@@ -689,7 +635,6 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
689
635
|
changed = true;
|
|
690
636
|
}
|
|
691
637
|
if (changed) writeStore(watches);
|
|
692
|
-
return listSlackReplyBadges();
|
|
693
638
|
}
|
|
694
639
|
|
|
695
640
|
// src/orchestrator/orchestrator.ts
|
|
@@ -2442,7 +2387,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2442
2387
|
return readThread(thread.id) ?? thread;
|
|
2443
2388
|
}
|
|
2444
2389
|
async function listLinearIssues(agent, repoPath) {
|
|
2445
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2390
|
+
const { getAdapter: getAdapter2 } = await import("./agents-DPR2TDNF.js");
|
|
2446
2391
|
await requireAgent(agent, { requireLinear: true });
|
|
2447
2392
|
const adapter = getAdapter2(agent);
|
|
2448
2393
|
if (!adapter.listLinearIssues) {
|
|
@@ -4985,7 +4930,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
4985
4930
|
${prompt}`;
|
|
4986
4931
|
}
|
|
4987
4932
|
async function defaultDeps() {
|
|
4988
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
4933
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-FZYM7I42.js");
|
|
4989
4934
|
const orch = getOrchestrator2();
|
|
4990
4935
|
return {
|
|
4991
4936
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6941,7 +6886,7 @@ export {
|
|
|
6941
6886
|
requireSlackWorkspace,
|
|
6942
6887
|
listSlackOutboundWatches,
|
|
6943
6888
|
recordSlackOutboundWatch,
|
|
6944
|
-
|
|
6889
|
+
pollSlackOutboundWatches,
|
|
6945
6890
|
AGENT_GIT_ACTIONS,
|
|
6946
6891
|
listLinearIssues,
|
|
6947
6892
|
readTurnLive,
|
|
@@ -520,6 +520,46 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
520
520
|
if (!(delta >= 0) || !Number.isFinite(delta)) return void 0;
|
|
521
521
|
return delta / 100;
|
|
522
522
|
}
|
|
523
|
+
function costUsdFromRunSnapshot(usage, runId) {
|
|
524
|
+
if (!usage?.runs?.length || !runId.trim()) return void 0;
|
|
525
|
+
const row = usage.runs.find((r) => r.runId === runId);
|
|
526
|
+
const cents = preferredCursorCostCents(row?.cost);
|
|
527
|
+
return cents != null ? cents / 100 : void 0;
|
|
528
|
+
}
|
|
529
|
+
function cursorGetUsageRunId(runId) {
|
|
530
|
+
const id = runId?.trim();
|
|
531
|
+
if (!id || id.startsWith("run-")) return void 0;
|
|
532
|
+
return id;
|
|
533
|
+
}
|
|
534
|
+
var CURSOR_COST_POLL_MS = [0, 400, 800, 1600, 3200];
|
|
535
|
+
function sleep(ms) {
|
|
536
|
+
return new Promise((resolve) => {
|
|
537
|
+
setTimeout(resolve, ms);
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
async function fetchCursorTurnCostUsd(getUsage, usageBefore, opts) {
|
|
541
|
+
const lookupRunId = cursorGetUsageRunId(opts?.runId);
|
|
542
|
+
for (const delay of CURSOR_COST_POLL_MS) {
|
|
543
|
+
if (delay > 0) await sleep(delay);
|
|
544
|
+
try {
|
|
545
|
+
if (lookupRunId) {
|
|
546
|
+
const scoped = await getUsage({ runId: lookupRunId });
|
|
547
|
+
const direct = costUsdFromRunSnapshot(scoped, lookupRunId);
|
|
548
|
+
if (direct != null) return direct;
|
|
549
|
+
}
|
|
550
|
+
const after = await getUsage();
|
|
551
|
+
const delta = turnCostUsdFromCursorUsage(usageBefore, after);
|
|
552
|
+
if (delta != null) return delta;
|
|
553
|
+
} catch (err) {
|
|
554
|
+
if (isCursorUsageUnavailableError(err)) return void 0;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return void 0;
|
|
558
|
+
}
|
|
559
|
+
function isCursorUsageUnavailableError(err) {
|
|
560
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
561
|
+
return /feature_unavailable|feature unavailable|not available for your account/i.test(msg);
|
|
562
|
+
}
|
|
523
563
|
function cursorCostOnlyUsageEvent(costUsd) {
|
|
524
564
|
return {
|
|
525
565
|
type: "usage",
|
|
@@ -831,6 +871,7 @@ export {
|
|
|
831
871
|
resolveNodeLaunch,
|
|
832
872
|
preferredCursorCostCents,
|
|
833
873
|
turnCostUsdFromCursorUsage,
|
|
874
|
+
fetchCursorTurnCostUsd,
|
|
834
875
|
cursorCostOnlyUsageEvent,
|
|
835
876
|
cursorSdkMessageToEvents,
|
|
836
877
|
cursorDeltaToEvents,
|