@sideboard-ai/core 0.1.326 → 0.1.328
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/{abletime-RYYFGKMU.js → abletime-NW4PJGHN.js} +4 -5
- package/dist/{abletime-RDHYSZL2.js → abletime-OW7LTFQD.js} +4 -5
- package/dist/{abletime-oauth-OYGS2DAU.js → abletime-oauth-KWQQRHOQ.js} +3 -4
- package/dist/{abletime-oauth-QR2QDVMK.js → abletime-oauth-TPR2QDRI.js} +3 -4
- package/dist/{abletime-rest-QDPTWNS4.js → abletime-rest-5DCWN3P4.js} +3 -4
- package/dist/{abletime-rest-BKYKNPTC.js → abletime-rest-UJ6SXDBN.js} +3 -4
- package/dist/agents/claude-runner.cjs +11 -0
- package/dist/agents/claude-runner.js +7 -1
- package/dist/{agents-QO7GKBYT.js → agents-IYBY3JT5.js} +8 -9
- package/dist/{agents-HANWZNI6.js → agents-XWIPONJR.js} +8 -9
- package/dist/{app-settings-RXBH7KY4.js → app-settings-A5D364JD.js} +1 -2
- package/dist/{app-settings-TUVLZNDE.js → app-settings-SA4HX3ZQ.js} +1 -2
- package/dist/{chunk-3Q4XNYHY.js → chunk-2GEUFPQQ.js} +1 -1
- package/dist/{chunk-MAW7DIG7.js → chunk-4F7THWIO.js} +2 -2
- package/dist/{chunk-K7M7MIWL.js → chunk-4G3W23X3.js} +3 -3
- package/dist/{chunk-Q3FHTGIW.js → chunk-5Y2C7Q55.js} +441 -20
- package/dist/{chunk-TMCK5TLA.js → chunk-ATQLP22S.js} +1 -1
- package/dist/{chunk-PB6HW7SA.js → chunk-CHYUUETG.js} +3 -3
- package/dist/{chunk-QPSKQP6E.js → chunk-D446IWPP.js} +48 -3
- package/dist/{chunk-C7HUCBX7.js → chunk-DACWFN4O.js} +5 -5
- package/dist/{chunk-B244TJWC.js → chunk-ECY7WL6T.js} +2 -2
- package/dist/{chunk-D744HOI5.js → chunk-EJRCHCXM.js} +18 -3
- package/dist/{chunk-KXRF6RNL.js → chunk-EUIVQAPK.js} +2 -2
- package/dist/{chunk-XLVLMQKN.js → chunk-EYDLXVED.js} +40 -25
- package/dist/{chunk-75RPUXJS.js → chunk-JKHCADKB.js} +5 -5
- package/dist/{chunk-4H5MWZ6J.js → chunk-KLVW3J2B.js} +2 -2
- package/dist/{chunk-QG4CYRA3.js → chunk-MO46K6WK.js} +14 -14
- package/dist/{chunk-F2PVRF3B.js → chunk-N6ZF3XRP.js} +2 -1
- package/dist/chunk-NJV5YEKI.js +194 -0
- package/dist/{chunk-BBNWKL4I.js → chunk-NQGLDQYB.js} +8 -8
- package/dist/{chunk-YGVGXQA7.js → chunk-Q4UPRQOS.js} +12 -12
- package/dist/{chunk-ZUAYA57W.js → chunk-QMLDR63X.js} +2 -2
- package/dist/{chunk-KECHK3ZT.js → chunk-R2C45NHT.js} +2 -2
- package/dist/{chunk-FWVUGLBG.js → chunk-RDXODLEN.js} +4 -4
- package/dist/{chunk-JM2TGOHP.js → chunk-SB5ADEZZ.js} +5 -5
- package/dist/{chunk-SO7G6O24.js → chunk-SFXGD5KJ.js} +1 -1
- package/dist/{chunk-LRHUBGEM.js → chunk-TUH4ICHQ.js} +1 -1
- package/dist/{chunk-WUCAVIIP.js → chunk-UMXBH344.js} +1 -1
- package/dist/{chunk-GP3RLZ6A.js → chunk-WD222BVP.js} +109 -491
- package/dist/{chunk-46FECFZU.js → chunk-X3XTO45Y.js} +39 -196
- package/dist/{chunk-RZVOX2MT.js → chunk-XBBZZHJY.js} +3 -3
- package/dist/{chunk-2EOLWHXH.js → chunk-XOMVOBPU.js} +127 -477
- package/dist/{chunk-ZSHS46V5.js → chunk-Y6OHM672.js} +476 -20
- package/dist/{chunk-YWQF7WAG.js → chunk-ZPBOWO64.js} +2 -2
- package/dist/{conductor-4GVTHUUB.js → conductor-G6GH5ZMU.js} +7 -7
- package/dist/{conductor-TGWI6ETZ.js → conductor-U5LGJZUJ.js} +6 -7
- package/dist/{coordinator-prompt-3E6SIDTM.js → coordinator-prompt-3PJLU3UH.js} +5 -6
- package/dist/{coordinator-prompt-WEYJREV6.js → coordinator-prompt-J7O7JB26.js} +5 -6
- package/dist/{global-workspace-UIEXAG2B.js → global-workspace-4CTLU2BV.js} +5 -6
- package/dist/{global-workspace-FPDZKUPF.js → global-workspace-Y3UDZYJX.js} +5 -6
- package/dist/index.cjs +605 -508
- package/dist/index.d.cts +23 -11
- package/dist/index.d.ts +23 -11
- package/dist/index.js +67 -65
- package/dist/{linear-6S7MK5YK.js → linear-CXWGH2TW.js} +2 -3
- package/dist/{linear-Z2T4KUAQ.js → linear-WLDCJ3AF.js} +2 -3
- package/dist/{linear-list-Q4M7AZO2.js → linear-list-52LEDEWO.js} +1 -1
- package/dist/{linear-list-A37WLUBO.js → linear-list-FGVN65JU.js} +1 -1
- package/dist/mcp/run-stdio.cjs +19762 -19682
- package/dist/mcp/run-stdio.js +33 -34
- package/dist/{optional-cli-CA4LL322.js → optional-cli-FN4MGB6W.js} +4 -5
- package/dist/{optional-cli-AANBL4U5.js → optional-cli-INRVBBBG.js} +3 -4
- package/dist/{orchestrator-RQXRZW7Z.js → orchestrator-3F53AZEN.js} +11 -12
- package/dist/{orchestrator-7FVDBE7Y.js → orchestrator-YY2JUYKD.js} +12 -12
- package/dist/{thread-store-4ZN3DS2W.js → thread-store-4WE24XA2.js} +6 -2
- package/dist/{thread-store-IC4BQXDW.js → thread-store-K2ZNGUSM.js} +7 -3
- package/dist/{workspaces-LEW4UP56.js → workspaces-MM7CQYR6.js} +5 -6
- package/dist/{workspaces-QONNLHNR.js → workspaces-WYCVZ6XH.js} +5 -6
- package/dist/{worktree-KFEJAQ2H.js → worktree-JBNEMJ5Z.js} +7 -8
- package/dist/{worktree-6GIONDQO.js → worktree-NNVRGPP4.js} +4 -5
- package/package.json +1 -1
- package/dist/chunk-77WWLBCI.js +0 -50
- package/dist/chunk-KGZBYWZ3.js +0 -23
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
parseSessionQuotaResetAt,
|
|
15
15
|
planModeTurnInstruction,
|
|
16
16
|
resolveQuotaFallbackAgent
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-MO46K6WK.js";
|
|
18
18
|
import {
|
|
19
19
|
applyWorktreePkgCacheEnv,
|
|
20
20
|
askBlockStillWaiting,
|
|
@@ -49,10 +49,11 @@ import {
|
|
|
49
49
|
startDevServer,
|
|
50
50
|
threadsSharingWorktree,
|
|
51
51
|
turnWatchedDetachedJob,
|
|
52
|
+
userRepliedAfterAgent,
|
|
52
53
|
worktreeDevProcessKey,
|
|
53
54
|
worktreeRunProcessKey,
|
|
54
55
|
worktreeSetupProcessKey
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-EYDLXVED.js";
|
|
56
57
|
import {
|
|
57
58
|
applyAgentEvent,
|
|
58
59
|
clipAgentEventForPaint,
|
|
@@ -86,7 +87,7 @@ import {
|
|
|
86
87
|
import {
|
|
87
88
|
formatOptionalServicesDirectiveForTurn,
|
|
88
89
|
formatOptionalServicesReminderForTurn
|
|
89
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-2GEUFPQQ.js";
|
|
90
91
|
import {
|
|
91
92
|
extractPresentedPlan,
|
|
92
93
|
isPresentPlanToolName,
|
|
@@ -117,7 +118,7 @@ import {
|
|
|
117
118
|
stageAbsolutePathsAsAttachments,
|
|
118
119
|
stageBuffersAsAttachments,
|
|
119
120
|
syncWorkspacesFromThreads
|
|
120
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-Q4UPRQOS.js";
|
|
121
122
|
import {
|
|
122
123
|
addPrStackLayer,
|
|
123
124
|
allocateTeamSlug,
|
|
@@ -166,7 +167,7 @@ import {
|
|
|
166
167
|
resolveRepoRoot,
|
|
167
168
|
switchWorktreeBranch,
|
|
168
169
|
withRepoGitLock
|
|
169
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-JKHCADKB.js";
|
|
170
171
|
import {
|
|
171
172
|
issueActivityKind
|
|
172
173
|
} from "./chunk-OYRN356W.js";
|
|
@@ -178,13 +179,44 @@ import {
|
|
|
178
179
|
git,
|
|
179
180
|
resolveGitDirsForLockRecovery
|
|
180
181
|
} from "./chunk-YBTSZ2SW.js";
|
|
182
|
+
import {
|
|
183
|
+
REVIEW_TAB_TITLE,
|
|
184
|
+
agentNicknameFromWorktreePath,
|
|
185
|
+
appendMessage,
|
|
186
|
+
createEmptyThread,
|
|
187
|
+
deleteSchedule,
|
|
188
|
+
deleteThreadRecord,
|
|
189
|
+
findThreadByRef,
|
|
190
|
+
formatReviewWriteGateDirective,
|
|
191
|
+
formatReviewWriteGateReminder,
|
|
192
|
+
getSchedule,
|
|
193
|
+
isPlaceholderBranch,
|
|
194
|
+
isReviewWriteGatedThread,
|
|
195
|
+
isWorktreeIdentityTitle,
|
|
196
|
+
listSchedules,
|
|
197
|
+
listThreads,
|
|
198
|
+
normalizeWorkspaceTags,
|
|
199
|
+
normalizeWorktreePath,
|
|
200
|
+
readThread,
|
|
201
|
+
recordScheduleRun,
|
|
202
|
+
setStatus,
|
|
203
|
+
teamSlugFromName,
|
|
204
|
+
ticketSlugForBranch,
|
|
205
|
+
updateThread,
|
|
206
|
+
withThreadLock,
|
|
207
|
+
workspaceTagsFromGroup,
|
|
208
|
+
worktreeDisplayLabelForGroup,
|
|
209
|
+
worktreeIdentityTitles,
|
|
210
|
+
worktreeNameFromPath,
|
|
211
|
+
worktreeSlugForTicket,
|
|
212
|
+
writeThread
|
|
213
|
+
} from "./chunk-5Y2C7Q55.js";
|
|
181
214
|
import {
|
|
182
215
|
HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
|
|
183
216
|
applyTurnUsage,
|
|
184
217
|
archivedUpdatedMs,
|
|
185
218
|
assertOrchestratorCapableAgent,
|
|
186
219
|
autoCleanupHistoryEnabled,
|
|
187
|
-
caffeinateWhileSchedulesEnabled,
|
|
188
220
|
childEnvWithAppSettings,
|
|
189
221
|
coerceOrchestratorAgent,
|
|
190
222
|
followUpBehavior,
|
|
@@ -197,7 +229,6 @@ import {
|
|
|
197
229
|
historyRetentionStubMessage,
|
|
198
230
|
isAbleTimeConnected,
|
|
199
231
|
isLinearConnected,
|
|
200
|
-
isOrchestratorCapableAgent,
|
|
201
232
|
loadAppSettings,
|
|
202
233
|
orchestrationQuotaFallbackAgent,
|
|
203
234
|
planHistoryAgePurge,
|
|
@@ -214,10 +245,7 @@ import {
|
|
|
214
245
|
usageOnLimit,
|
|
215
246
|
withTurnScopedCost,
|
|
216
247
|
writeViewerContext
|
|
217
|
-
} from "./chunk-
|
|
218
|
-
import {
|
|
219
|
-
writePrivateFile
|
|
220
|
-
} from "./chunk-NSTQ6QKD.js";
|
|
248
|
+
} from "./chunk-EJRCHCXM.js";
|
|
221
249
|
import {
|
|
222
250
|
examplePrefixedBranch,
|
|
223
251
|
sanitizeGitBranchPrefix
|
|
@@ -228,37 +256,6 @@ import {
|
|
|
228
256
|
nextManagedAccount,
|
|
229
257
|
resolveAccountForThread
|
|
230
258
|
} from "./chunk-J2LNLI4S.js";
|
|
231
|
-
import {
|
|
232
|
-
REVIEW_TAB_TITLE,
|
|
233
|
-
agentNicknameFromWorktreePath,
|
|
234
|
-
appendMessage,
|
|
235
|
-
createEmptyThread,
|
|
236
|
-
deleteThreadRecord,
|
|
237
|
-
findThreadByRef,
|
|
238
|
-
formatReviewWriteGateDirective,
|
|
239
|
-
formatReviewWriteGateReminder,
|
|
240
|
-
isPlaceholderBranch,
|
|
241
|
-
isReviewWriteGatedThread,
|
|
242
|
-
isWorktreeIdentityTitle,
|
|
243
|
-
listThreads,
|
|
244
|
-
normalizeWorkspaceTags,
|
|
245
|
-
normalizeWorktreePath,
|
|
246
|
-
readThread,
|
|
247
|
-
setStatus,
|
|
248
|
-
teamSlugFromName,
|
|
249
|
-
ticketSlugForBranch,
|
|
250
|
-
updateThread,
|
|
251
|
-
withThreadLock,
|
|
252
|
-
workspaceTagsFromGroup,
|
|
253
|
-
worktreeDisplayLabelForGroup,
|
|
254
|
-
worktreeIdentityTitles,
|
|
255
|
-
worktreeNameFromPath,
|
|
256
|
-
worktreeSlugForTicket,
|
|
257
|
-
writeThread
|
|
258
|
-
} from "./chunk-Q3FHTGIW.js";
|
|
259
|
-
import {
|
|
260
|
-
normalizeThinkingEffort
|
|
261
|
-
} from "./chunk-KGZBYWZ3.js";
|
|
262
259
|
import {
|
|
263
260
|
annotateDevAccessRuns,
|
|
264
261
|
appDataDir,
|
|
@@ -312,8 +309,8 @@ function formatInjectedNoticesForTurn(notices) {
|
|
|
312
309
|
}
|
|
313
310
|
|
|
314
311
|
// src/orchestrator/orchestrator.ts
|
|
315
|
-
import { randomUUID as
|
|
316
|
-
import { existsSync as
|
|
312
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
313
|
+
import { existsSync as existsSync13 } from "fs";
|
|
317
314
|
|
|
318
315
|
// src/agents/spawn.ts
|
|
319
316
|
import { rmSync } from "fs";
|
|
@@ -564,9 +561,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
564
561
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
565
562
|
);
|
|
566
563
|
}
|
|
567
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
564
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-Y3UDZYJX.js");
|
|
568
565
|
if (isGlobalThread2(thread)) {
|
|
569
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
566
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-J7O7JB26.js");
|
|
570
567
|
ensureGlobalCoordinatorCwd2(
|
|
571
568
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
572
569
|
);
|
|
@@ -1891,6 +1888,9 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
1891
1888
|
at
|
|
1892
1889
|
);
|
|
1893
1890
|
}
|
|
1891
|
+
function attentionOutranksAsk(existing) {
|
|
1892
|
+
return existing?.source === "reported" || existing?.source === "permission";
|
|
1893
|
+
}
|
|
1894
1894
|
function withStampedQuestions(decision, existing) {
|
|
1895
1895
|
if (decision.source !== "ask_user" || decision.questions?.length) return decision;
|
|
1896
1896
|
if (existing?.source !== "ask_user" || !existing.questions?.length) return decision;
|
|
@@ -1904,12 +1904,37 @@ function agentBlockAfterTurn(input) {
|
|
|
1904
1904
|
if (input.failed) return null;
|
|
1905
1905
|
const decision = decisionBlockFromParts(input.parts, input.planMode);
|
|
1906
1906
|
if (decision) {
|
|
1907
|
+
if (decision.source === "ask_user" && attentionOutranksAsk(input.existing)) {
|
|
1908
|
+
return input.existing ?? null;
|
|
1909
|
+
}
|
|
1907
1910
|
const next = withStampedQuestions(decision, input.existing);
|
|
1908
1911
|
if (isDismissedAskUserBlock(next, input.dismissedQuestionSignature)) {
|
|
1909
1912
|
return input.existing?.source === "reported" ? input.existing : null;
|
|
1910
1913
|
}
|
|
1911
1914
|
return next;
|
|
1912
1915
|
}
|
|
1916
|
+
const pending = extractPendingPlanQuestions(input.parts);
|
|
1917
|
+
if (pending && attentionOutranksAsk(input.existing)) {
|
|
1918
|
+
return input.existing ?? null;
|
|
1919
|
+
}
|
|
1920
|
+
if (pending) {
|
|
1921
|
+
const kept = withStampedQuestions(
|
|
1922
|
+
{
|
|
1923
|
+
...makeAgentBlock(
|
|
1924
|
+
"ask_user",
|
|
1925
|
+
formatAskUserNotifyMessage(pending.questions),
|
|
1926
|
+
input.existing?.source === "ask_user" ? input.existing.at : void 0
|
|
1927
|
+
),
|
|
1928
|
+
onScreen: true,
|
|
1929
|
+
questionSignature: pending.signature,
|
|
1930
|
+
questions: pending.questions
|
|
1931
|
+
},
|
|
1932
|
+
input.existing
|
|
1933
|
+
);
|
|
1934
|
+
if (!isDismissedAskUserBlock(kept, input.dismissedQuestionSignature)) return kept;
|
|
1935
|
+
} else if (input.existing?.source === "ask_user" && input.existing.onScreen && input.existing.questions?.length && !isDismissedAskUserBlock(input.existing, input.dismissedQuestionSignature)) {
|
|
1936
|
+
return input.existing;
|
|
1937
|
+
}
|
|
1913
1938
|
if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
|
|
1914
1939
|
return null;
|
|
1915
1940
|
}
|
|
@@ -1938,11 +1963,15 @@ function askBlocksEqual(a, b) {
|
|
|
1938
1963
|
if (!a || !b) return false;
|
|
1939
1964
|
return a.source === b.source && a.reason === b.reason && a.at === b.at && a.onScreen === b.onScreen && a.questionSignature === b.questionSignature;
|
|
1940
1965
|
}
|
|
1941
|
-
function askBlockAfterLiveParts(existing, parts) {
|
|
1966
|
+
function askBlockAfterLiveParts(existing, parts, dismissedQuestionSignature) {
|
|
1967
|
+
if (attentionOutranksAsk(existing)) return existing ?? null;
|
|
1968
|
+
if (isDismissedAskUserBlock(existing, dismissedQuestionSignature)) return null;
|
|
1969
|
+
const dismissed = dismissedQuestionSignature?.trim() ?? "";
|
|
1970
|
+
let pending = extractPendingPlanQuestions(parts);
|
|
1971
|
+
if (dismissed && pending?.signature === dismissed) pending = null;
|
|
1942
1972
|
const last = lastTopLevelTool(parts);
|
|
1943
1973
|
if (last?.type === "tool" && isAskUserToolName(last.name)) {
|
|
1944
1974
|
if (existing?.source === "ask_user" && existing.onScreen) return existing;
|
|
1945
|
-
const pending = extractPendingPlanQuestions(parts);
|
|
1946
1975
|
const questions = pending?.questions ?? existing?.questions;
|
|
1947
1976
|
if (!questions?.length) {
|
|
1948
1977
|
return existing?.source === "ask_user" ? { ...existing, onScreen: true } : existing ?? null;
|
|
@@ -1955,13 +1984,32 @@ function askBlockAfterLiveParts(existing, parts) {
|
|
|
1955
1984
|
questions
|
|
1956
1985
|
};
|
|
1957
1986
|
}
|
|
1987
|
+
if (pending) {
|
|
1988
|
+
if (existing?.source === "ask_user" && existing.onScreen && existing.questions?.length) {
|
|
1989
|
+
return existing;
|
|
1990
|
+
}
|
|
1991
|
+
const at = existing?.source === "ask_user" ? existing.at : void 0;
|
|
1992
|
+
return {
|
|
1993
|
+
...makeAgentBlock("ask_user", formatAskUserNotifyMessage(pending.questions), at),
|
|
1994
|
+
onScreen: true,
|
|
1995
|
+
questionSignature: pending.signature,
|
|
1996
|
+
questions: pending.questions
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
if (existing?.source === "ask_user" && existing.onScreen && existing.questions?.length) {
|
|
2000
|
+
return existing;
|
|
2001
|
+
}
|
|
1958
2002
|
if (last && existing?.source === "ask_user") return null;
|
|
1959
2003
|
return existing ?? null;
|
|
1960
2004
|
}
|
|
1961
2005
|
function syncAskUserBlockFromLive(threadId, parts) {
|
|
1962
2006
|
const thread = readThread(threadId);
|
|
1963
2007
|
if (!thread || thread.status === "archived") return;
|
|
1964
|
-
const next = askBlockAfterLiveParts(
|
|
2008
|
+
const next = askBlockAfterLiveParts(
|
|
2009
|
+
thread.agentBlock,
|
|
2010
|
+
parts,
|
|
2011
|
+
thread.dismissedQuestionSignature
|
|
2012
|
+
);
|
|
1965
2013
|
if (askBlocksEqual(thread.agentBlock, next)) return;
|
|
1966
2014
|
updateThread(threadId, { agentBlock: next });
|
|
1967
2015
|
}
|
|
@@ -2862,7 +2910,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2862
2910
|
});
|
|
2863
2911
|
await requireAgent(resolved.agent);
|
|
2864
2912
|
if (input.cowboy) {
|
|
2865
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
2913
|
+
const { cowboyModeEnabled } = await import("./app-settings-SA4HX3ZQ.js");
|
|
2866
2914
|
if (!cowboyModeEnabled()) {
|
|
2867
2915
|
throw new Error(
|
|
2868
2916
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -2921,7 +2969,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2921
2969
|
let sourceIsFork = false;
|
|
2922
2970
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
2923
2971
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
2924
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
2972
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-NW4PJGHN.js");
|
|
2925
2973
|
const task = await ensureAbleTimeTask({
|
|
2926
2974
|
title: title?.trim() || "Untitled work",
|
|
2927
2975
|
description: input.prompt?.trim() || void 0
|
|
@@ -3803,7 +3851,7 @@ async function adoptThread(input) {
|
|
|
3803
3851
|
messages: input.messages ?? []
|
|
3804
3852
|
});
|
|
3805
3853
|
writeThread(thread);
|
|
3806
|
-
const { addWorkspace: addWorkspace2 } = await import("./workspaces-
|
|
3854
|
+
const { addWorkspace: addWorkspace2 } = await import("./workspaces-MM7CQYR6.js");
|
|
3807
3855
|
await addWorkspace2(repoPath);
|
|
3808
3856
|
const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-P5NJODWP.js");
|
|
3809
3857
|
await ensureWorktreeSideboardIgnored(input.worktreePath);
|
|
@@ -6193,7 +6241,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
6193
6241
|
lines.push(formatDevAccessHint(opts?.activeRuns));
|
|
6194
6242
|
lines.push("");
|
|
6195
6243
|
lines.push(
|
|
6196
|
-
"Automations (sidebar, after Board): `create_schedule` / `list_schedules` (`at` / `every` / `cron` / `time`+`days`). `archiveChat=false` keeps the new chat. `chatId=self`
|
|
6244
|
+
"Automations (sidebar, after Board): `create_schedule` / `list_schedules` (`at` / `every` / `cron` / `time`+`days`). `archiveChat=false` keeps the new chat. `chatId=self` is removed when this chat is archived. Fires only while Sideboard.app is running. A future job turns on Settings \u2192 Advanced \u2192 Caffeinate while automations are enabled."
|
|
6197
6245
|
);
|
|
6198
6246
|
lines.push(
|
|
6199
6247
|
"`set_workspace_tags` labels this checkout (omit ref; replace, add, or remove). Not another checkout."
|
|
@@ -6213,7 +6261,7 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
6213
6261
|
return formatConnectedOrchestratorReminder(connectedOrchestrator(thread, find));
|
|
6214
6262
|
}
|
|
6215
6263
|
function formatWorktreeReminder() {
|
|
6216
|
-
return "Sideboard workspace: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push. Automations: create_schedule (at / every / cron, or time + days such as weekdays at 07:30; archiveChat=false leaves the new chat open; chatId=self
|
|
6264
|
+
return "Sideboard workspace: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push. Automations: create_schedule (at / every / cron, or time + days such as weekdays at 07:30; archiveChat=false leaves the new chat open; chatId=self ends with the chat). set_workspace_tags updates labels on this workspace (omit ref).";
|
|
6217
6265
|
}
|
|
6218
6266
|
function formatClaudeSubagentReminder() {
|
|
6219
6267
|
return 'Claude subagents: if Task/Agent workers will edit files, write a short plan in this chat and continue in the same turn. Do not ask the user whether to isolate, and do not set worktree.bgIsolation to none. One writer may edit this workspace. Every other writer is an Agent with isolation "worktree" and a disjoint file list (read-only explore agents may overlap). While those agents run, leave their files alone. Merge each returned branch into this workspace, then remove the temporary worktree. You stay in this cwd. If Claude says another write-capable agent is in this directory, or that writes to the shared checkout are blocked, re-spawn that agent with isolation "worktree" or make the edit yourself. That note is another worker in this chat, or a worker Claude still has marked running. Do not mention it to the user.';
|
|
@@ -6735,402 +6783,6 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
6735
6783
|
}
|
|
6736
6784
|
}
|
|
6737
6785
|
|
|
6738
|
-
// src/store/schedules.ts
|
|
6739
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
6740
|
-
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
|
|
6741
|
-
import { join as join14 } from "path";
|
|
6742
|
-
|
|
6743
|
-
// src/store/schedule-when.ts
|
|
6744
|
-
import { Cron } from "croner";
|
|
6745
|
-
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
6746
|
-
var UNIT_MS = {
|
|
6747
|
-
s: 1e3,
|
|
6748
|
-
m: 6e4,
|
|
6749
|
-
h: 36e5,
|
|
6750
|
-
d: 864e5
|
|
6751
|
-
};
|
|
6752
|
-
var DAY_ALIASES = {
|
|
6753
|
-
sun: 0,
|
|
6754
|
-
sunday: 0,
|
|
6755
|
-
mon: 1,
|
|
6756
|
-
monday: 1,
|
|
6757
|
-
tue: 2,
|
|
6758
|
-
tues: 2,
|
|
6759
|
-
tuesday: 2,
|
|
6760
|
-
wed: 3,
|
|
6761
|
-
wednesday: 3,
|
|
6762
|
-
thu: 4,
|
|
6763
|
-
thur: 4,
|
|
6764
|
-
thurs: 4,
|
|
6765
|
-
thursday: 4,
|
|
6766
|
-
fri: 5,
|
|
6767
|
-
friday: 5,
|
|
6768
|
-
sat: 6,
|
|
6769
|
-
saturday: 6
|
|
6770
|
-
};
|
|
6771
|
-
var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/;
|
|
6772
|
-
function parseDurationMs(every) {
|
|
6773
|
-
const m = every.trim().match(DURATION_RE);
|
|
6774
|
-
if (!m) return null;
|
|
6775
|
-
const n = Number.parseInt(m[1], 10);
|
|
6776
|
-
if (!Number.isFinite(n) || n <= 0) return null;
|
|
6777
|
-
const unit = m[2].toLowerCase();
|
|
6778
|
-
return n * UNIT_MS[unit];
|
|
6779
|
-
}
|
|
6780
|
-
function dayIndex(token) {
|
|
6781
|
-
const text3 = token.trim().toLowerCase();
|
|
6782
|
-
if (/^[0-6]$/.test(text3)) return Number(text3);
|
|
6783
|
-
return DAY_ALIASES[text3];
|
|
6784
|
-
}
|
|
6785
|
-
function normalizeWeekdays(days) {
|
|
6786
|
-
const set = /* @__PURE__ */ new Set();
|
|
6787
|
-
for (const day of days) {
|
|
6788
|
-
if (!Number.isInteger(day) || day < 0 || day > 6) {
|
|
6789
|
-
throw new Error("Days must be 0 (Sunday) through 6 (Saturday)");
|
|
6790
|
-
}
|
|
6791
|
-
set.add(day);
|
|
6792
|
-
}
|
|
6793
|
-
if (set.size === 0) throw new Error("Pick at least one day");
|
|
6794
|
-
return [...set].sort((a, b) => a - b);
|
|
6795
|
-
}
|
|
6796
|
-
function parseWeeklyDays(raw) {
|
|
6797
|
-
const text3 = raw.trim().toLowerCase();
|
|
6798
|
-
if (!text3) throw new Error("Pick at least one day");
|
|
6799
|
-
if (text3 === "daily" || text3 === "all" || text3 === "every day" || text3 === "everyday") {
|
|
6800
|
-
return [0, 1, 2, 3, 4, 5, 6];
|
|
6801
|
-
}
|
|
6802
|
-
if (text3 === "weekdays" || text3 === "weekday") return [1, 2, 3, 4, 5];
|
|
6803
|
-
if (text3 === "weekends" || text3 === "weekend") return [0, 6];
|
|
6804
|
-
const days = [];
|
|
6805
|
-
for (const part of text3.split(/[\s,]+/).filter(Boolean)) {
|
|
6806
|
-
const range = part.split("-");
|
|
6807
|
-
if (range.length === 2 && range[0] && range[1]) {
|
|
6808
|
-
const start = dayIndex(range[0]);
|
|
6809
|
-
const end = dayIndex(range[1]);
|
|
6810
|
-
if (start === void 0 || end === void 0) {
|
|
6811
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
6812
|
-
}
|
|
6813
|
-
if (start <= end) {
|
|
6814
|
-
for (let d = start; d <= end; d++) days.push(d);
|
|
6815
|
-
} else {
|
|
6816
|
-
for (let d = start; d <= 6; d++) days.push(d);
|
|
6817
|
-
for (let d = 0; d <= end; d++) days.push(d);
|
|
6818
|
-
}
|
|
6819
|
-
continue;
|
|
6820
|
-
}
|
|
6821
|
-
const n = dayIndex(part);
|
|
6822
|
-
if (n === void 0) {
|
|
6823
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
6824
|
-
}
|
|
6825
|
-
days.push(n);
|
|
6826
|
-
}
|
|
6827
|
-
return normalizeWeekdays(days);
|
|
6828
|
-
}
|
|
6829
|
-
function normalizeWeeklyTime(raw) {
|
|
6830
|
-
const m = raw.trim().match(TIME_RE);
|
|
6831
|
-
if (!m) throw new Error(`Invalid time: ${raw} (use HH:mm, 24-hour)`);
|
|
6832
|
-
return `${m[1]}:${m[2]}`;
|
|
6833
|
-
}
|
|
6834
|
-
function weeklyCronExpr(when) {
|
|
6835
|
-
const time = normalizeWeeklyTime(when.time);
|
|
6836
|
-
const [hh, mm] = time.split(":");
|
|
6837
|
-
const days = normalizeWeekdays(when.days);
|
|
6838
|
-
return `${Number(mm)} ${Number(hh)} * * ${days.join(",")}`;
|
|
6839
|
-
}
|
|
6840
|
-
function computeNextRunAt(when, from = /* @__PURE__ */ new Date()) {
|
|
6841
|
-
if (when.kind === "once") {
|
|
6842
|
-
const at = new Date(when.at);
|
|
6843
|
-
if (Number.isNaN(at.getTime())) {
|
|
6844
|
-
throw new Error(`Invalid once-at datetime: ${when.at}`);
|
|
6845
|
-
}
|
|
6846
|
-
return at;
|
|
6847
|
-
}
|
|
6848
|
-
if (when.kind === "every") {
|
|
6849
|
-
const ms = parseDurationMs(when.every);
|
|
6850
|
-
if (!ms) {
|
|
6851
|
-
throw new Error(`Invalid interval: ${when.every} (use 15m, 1h, 6h, 1d)`);
|
|
6852
|
-
}
|
|
6853
|
-
return new Date(from.getTime() + ms);
|
|
6854
|
-
}
|
|
6855
|
-
if (when.kind === "weekly") {
|
|
6856
|
-
return computeNextRunAt(
|
|
6857
|
-
{ kind: "cron", expr: weeklyCronExpr(when), tz: when.tz },
|
|
6858
|
-
from
|
|
6859
|
-
);
|
|
6860
|
-
}
|
|
6861
|
-
try {
|
|
6862
|
-
const job = new Cron(when.expr, {
|
|
6863
|
-
timezone: when.tz?.trim() || void 0,
|
|
6864
|
-
paused: true
|
|
6865
|
-
});
|
|
6866
|
-
const next = job.nextRun(from);
|
|
6867
|
-
if (!next) {
|
|
6868
|
-
throw new Error(`Cron expression has no next run: ${when.expr}`);
|
|
6869
|
-
}
|
|
6870
|
-
return next;
|
|
6871
|
-
} catch (err) {
|
|
6872
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6873
|
-
throw new Error(`Invalid cron: ${message}`);
|
|
6874
|
-
}
|
|
6875
|
-
}
|
|
6876
|
-
function normalizeWhen(raw) {
|
|
6877
|
-
if (!raw || typeof raw !== "object") {
|
|
6878
|
-
throw new Error("Schedule is missing `when`");
|
|
6879
|
-
}
|
|
6880
|
-
const rec = raw;
|
|
6881
|
-
const kind = rec.kind;
|
|
6882
|
-
if (kind === "once" && typeof rec.at === "string") {
|
|
6883
|
-
return { kind: "once", at: rec.at };
|
|
6884
|
-
}
|
|
6885
|
-
if (kind === "every" && typeof rec.every === "string") {
|
|
6886
|
-
return { kind: "every", every: rec.every };
|
|
6887
|
-
}
|
|
6888
|
-
if (kind === "cron" && typeof rec.expr === "string") {
|
|
6889
|
-
return {
|
|
6890
|
-
kind: "cron",
|
|
6891
|
-
expr: rec.expr,
|
|
6892
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
6893
|
-
};
|
|
6894
|
-
}
|
|
6895
|
-
if (kind === "weekly" && Array.isArray(rec.days) && typeof rec.time === "string") {
|
|
6896
|
-
return {
|
|
6897
|
-
kind: "weekly",
|
|
6898
|
-
days: normalizeWeekdays(rec.days.map((day) => Number(day))),
|
|
6899
|
-
time: normalizeWeeklyTime(rec.time),
|
|
6900
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
6901
|
-
};
|
|
6902
|
-
}
|
|
6903
|
-
throw new Error("Schedule `when` must be once, every, weekly, or cron");
|
|
6904
|
-
}
|
|
6905
|
-
|
|
6906
|
-
// src/store/schedules.ts
|
|
6907
|
-
function schedulesPath() {
|
|
6908
|
-
return join14(appDataDir(), "schedules.json");
|
|
6909
|
-
}
|
|
6910
|
-
function defaultScheduleName(prompt) {
|
|
6911
|
-
const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
6912
|
-
if (!line) return "Untitled automation";
|
|
6913
|
-
return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
|
|
6914
|
-
}
|
|
6915
|
-
function resolveScheduleThreadId(raw, env = process.env) {
|
|
6916
|
-
const value = raw?.trim() || "";
|
|
6917
|
-
if (!value) return null;
|
|
6918
|
-
if (value.toLowerCase() === "self") {
|
|
6919
|
-
return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
|
|
6920
|
-
}
|
|
6921
|
-
return value;
|
|
6922
|
-
}
|
|
6923
|
-
function nowIso(d = /* @__PURE__ */ new Date()) {
|
|
6924
|
-
return d.toISOString();
|
|
6925
|
-
}
|
|
6926
|
-
var ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
|
|
6927
|
-
"transcript",
|
|
6928
|
-
"file",
|
|
6929
|
-
"issue",
|
|
6930
|
-
"workspace",
|
|
6931
|
-
"diff-comment",
|
|
6932
|
-
"code-ref"
|
|
6933
|
-
]);
|
|
6934
|
-
function normalizeOptionalBool(raw) {
|
|
6935
|
-
if (raw === true || raw === false) return raw;
|
|
6936
|
-
return null;
|
|
6937
|
-
}
|
|
6938
|
-
function normalizeAutonomy(raw) {
|
|
6939
|
-
return raw === "default" || raw === "full" ? raw : null;
|
|
6940
|
-
}
|
|
6941
|
-
function normalizeAttachments(raw) {
|
|
6942
|
-
if (!Array.isArray(raw)) return [];
|
|
6943
|
-
const out = [];
|
|
6944
|
-
for (const item of raw) {
|
|
6945
|
-
if (!item || typeof item !== "object") continue;
|
|
6946
|
-
const row = item;
|
|
6947
|
-
if (typeof row.id !== "string" || !row.id.trim()) continue;
|
|
6948
|
-
if (typeof row.name !== "string" || !row.name) continue;
|
|
6949
|
-
if (typeof row.content !== "string") continue;
|
|
6950
|
-
if (!ATTACHMENT_KINDS.has(row.kind)) continue;
|
|
6951
|
-
const next = {
|
|
6952
|
-
id: row.id,
|
|
6953
|
-
name: row.name,
|
|
6954
|
-
kind: row.kind,
|
|
6955
|
-
content: row.content
|
|
6956
|
-
};
|
|
6957
|
-
if (typeof row.path === "string" && row.path) next.path = row.path;
|
|
6958
|
-
if (typeof row.previewDataUrl === "string" && row.previewDataUrl) {
|
|
6959
|
-
next.previewDataUrl = row.previewDataUrl;
|
|
6960
|
-
}
|
|
6961
|
-
out.push(next);
|
|
6962
|
-
}
|
|
6963
|
-
return out;
|
|
6964
|
-
}
|
|
6965
|
-
function normalizeTask(raw) {
|
|
6966
|
-
const when = normalizeWhen(raw.when);
|
|
6967
|
-
const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
|
|
6968
|
-
return {
|
|
6969
|
-
id: raw.id,
|
|
6970
|
-
name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : defaultScheduleName(raw.prompt),
|
|
6971
|
-
prompt: String(raw.prompt ?? ""),
|
|
6972
|
-
enabled: Boolean(raw.enabled),
|
|
6973
|
-
when,
|
|
6974
|
-
threadId: raw.threadId?.trim() || null,
|
|
6975
|
-
agent,
|
|
6976
|
-
model: raw.model?.trim() || null,
|
|
6977
|
-
effort: normalizeThinkingEffort(raw.effort),
|
|
6978
|
-
fast: normalizeOptionalBool(raw.fast),
|
|
6979
|
-
planMode: normalizeOptionalBool(raw.planMode),
|
|
6980
|
-
autonomy: normalizeAutonomy(raw.autonomy),
|
|
6981
|
-
attachments: normalizeAttachments(raw.attachments),
|
|
6982
|
-
archiveChat: raw.archiveChat !== false,
|
|
6983
|
-
nextRunAt: raw.nextRunAt,
|
|
6984
|
-
lastRunAt: raw.lastRunAt ?? null,
|
|
6985
|
-
lastThreadId: raw.lastThreadId ?? null,
|
|
6986
|
-
lastError: raw.lastError ?? null,
|
|
6987
|
-
createdBy: raw.createdBy === "mcp" || raw.createdBy === "cli" || raw.createdBy === "ui" ? raw.createdBy : "ui",
|
|
6988
|
-
createdAt: raw.createdAt,
|
|
6989
|
-
updatedAt: raw.updatedAt
|
|
6990
|
-
};
|
|
6991
|
-
}
|
|
6992
|
-
function readAll() {
|
|
6993
|
-
const path = schedulesPath();
|
|
6994
|
-
if (!existsSync13(path)) return [];
|
|
6995
|
-
try {
|
|
6996
|
-
const parsed = JSON.parse(readFileSync8(path, "utf8"));
|
|
6997
|
-
if (!Array.isArray(parsed)) return [];
|
|
6998
|
-
return parsed.map((row) => {
|
|
6999
|
-
try {
|
|
7000
|
-
return normalizeTask(row);
|
|
7001
|
-
} catch {
|
|
7002
|
-
return null;
|
|
7003
|
-
}
|
|
7004
|
-
}).filter((row) => Boolean(row?.id && row.prompt));
|
|
7005
|
-
} catch {
|
|
7006
|
-
return [];
|
|
7007
|
-
}
|
|
7008
|
-
}
|
|
7009
|
-
function writeAll(rows) {
|
|
7010
|
-
writePrivateFile(schedulesPath(), `${JSON.stringify(rows, null, 2)}
|
|
7011
|
-
`);
|
|
7012
|
-
}
|
|
7013
|
-
function buildTask(input, now) {
|
|
7014
|
-
const prompt = input.prompt.trim();
|
|
7015
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
7016
|
-
const when = normalizeWhen(input.when);
|
|
7017
|
-
const nextRunAt = computeNextRunAt(when, now).toISOString();
|
|
7018
|
-
const ts = nowIso(now);
|
|
7019
|
-
const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
|
|
7020
|
-
return {
|
|
7021
|
-
id: randomUUID4(),
|
|
7022
|
-
name: input.name?.trim() || defaultScheduleName(prompt),
|
|
7023
|
-
prompt,
|
|
7024
|
-
enabled: input.enabled !== false,
|
|
7025
|
-
when,
|
|
7026
|
-
threadId: input.threadId?.trim() || null,
|
|
7027
|
-
agent,
|
|
7028
|
-
model: input.model?.trim() || null,
|
|
7029
|
-
effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
|
|
7030
|
-
fast: normalizeOptionalBool(input.fast),
|
|
7031
|
-
planMode: normalizeOptionalBool(input.planMode),
|
|
7032
|
-
autonomy: normalizeAutonomy(input.autonomy),
|
|
7033
|
-
attachments: normalizeAttachments(input.attachments),
|
|
7034
|
-
archiveChat: input.archiveChat !== false,
|
|
7035
|
-
nextRunAt,
|
|
7036
|
-
lastRunAt: null,
|
|
7037
|
-
lastThreadId: null,
|
|
7038
|
-
lastError: null,
|
|
7039
|
-
createdBy: input.createdBy,
|
|
7040
|
-
createdAt: ts,
|
|
7041
|
-
updatedAt: ts
|
|
7042
|
-
};
|
|
7043
|
-
}
|
|
7044
|
-
function listSchedules() {
|
|
7045
|
-
return readAll().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
|
|
7046
|
-
}
|
|
7047
|
-
function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
|
|
7048
|
-
if (!task.enabled) return false;
|
|
7049
|
-
const at = new Date(task.nextRunAt);
|
|
7050
|
-
if (Number.isNaN(at.getTime())) return false;
|
|
7051
|
-
return at.getTime() > now.getTime();
|
|
7052
|
-
}
|
|
7053
|
-
function ensureCaffeinateForFutureSchedule(task) {
|
|
7054
|
-
if (!scheduleNeedsCaffeinate(task)) return;
|
|
7055
|
-
if (caffeinateWhileSchedulesEnabled()) return;
|
|
7056
|
-
updateAdvancedSettings({ caffeinateWhileSchedules: true });
|
|
7057
|
-
}
|
|
7058
|
-
function getSchedule(id) {
|
|
7059
|
-
const key = id.trim();
|
|
7060
|
-
if (!key) return null;
|
|
7061
|
-
return readAll().find(
|
|
7062
|
-
(row) => row.id === key || row.id.startsWith(key) && key.length >= 8
|
|
7063
|
-
) ?? null;
|
|
7064
|
-
}
|
|
7065
|
-
function createSchedule(input) {
|
|
7066
|
-
const task = buildTask(input, /* @__PURE__ */ new Date());
|
|
7067
|
-
const rows = readAll();
|
|
7068
|
-
rows.push(task);
|
|
7069
|
-
writeAll(rows);
|
|
7070
|
-
ensureCaffeinateForFutureSchedule(task);
|
|
7071
|
-
return task;
|
|
7072
|
-
}
|
|
7073
|
-
function updateSchedule(id, patch) {
|
|
7074
|
-
const rows = readAll();
|
|
7075
|
-
const idx = rows.findIndex((row) => row.id === id || id.length >= 8 && row.id.startsWith(id));
|
|
7076
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
7077
|
-
const prev = rows[idx];
|
|
7078
|
-
const when = patch.when ? normalizeWhen(patch.when) : prev.when;
|
|
7079
|
-
const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
|
|
7080
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
7081
|
-
const whenChanged = patch.when !== void 0;
|
|
7082
|
-
const next = {
|
|
7083
|
-
...prev,
|
|
7084
|
-
name: patch.name !== void 0 ? patch.name.trim() || defaultScheduleName(prompt) : prev.name,
|
|
7085
|
-
prompt,
|
|
7086
|
-
enabled: patch.enabled ?? prev.enabled,
|
|
7087
|
-
when,
|
|
7088
|
-
threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
|
|
7089
|
-
agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
|
|
7090
|
-
model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
|
|
7091
|
-
effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
|
|
7092
|
-
fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
|
|
7093
|
-
planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
|
|
7094
|
-
autonomy: patch.autonomy !== void 0 ? normalizeAutonomy(patch.autonomy) : prev.autonomy,
|
|
7095
|
-
attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
|
|
7096
|
-
archiveChat: patch.archiveChat !== void 0 ? patch.archiveChat !== false : prev.archiveChat,
|
|
7097
|
-
nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
|
|
7098
|
-
lastError: whenChanged ? null : prev.lastError,
|
|
7099
|
-
updatedAt: nowIso()
|
|
7100
|
-
};
|
|
7101
|
-
rows[idx] = next;
|
|
7102
|
-
writeAll(rows);
|
|
7103
|
-
ensureCaffeinateForFutureSchedule(next);
|
|
7104
|
-
return next;
|
|
7105
|
-
}
|
|
7106
|
-
function deleteSchedule(id) {
|
|
7107
|
-
const rows = readAll();
|
|
7108
|
-
const next = rows.filter(
|
|
7109
|
-
(row) => row.id !== id && !(id.length >= 8 && row.id.startsWith(id))
|
|
7110
|
-
);
|
|
7111
|
-
if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
|
|
7112
|
-
writeAll(next);
|
|
7113
|
-
}
|
|
7114
|
-
function recordScheduleRun(id, result) {
|
|
7115
|
-
const rows = readAll();
|
|
7116
|
-
const idx = rows.findIndex((row) => row.id === id);
|
|
7117
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
7118
|
-
const prev = rows[idx];
|
|
7119
|
-
const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
|
|
7120
|
-
const next = {
|
|
7121
|
-
...prev,
|
|
7122
|
-
enabled: prev.when.kind === "once" ? false : prev.enabled,
|
|
7123
|
-
nextRunAt: prev.when.kind === "once" ? prev.nextRunAt : computeNextRunAt(prev.when, firedAt).toISOString(),
|
|
7124
|
-
lastRunAt: nowIso(firedAt),
|
|
7125
|
-
lastThreadId: result.lastThreadId !== void 0 ? result.lastThreadId : prev.lastThreadId,
|
|
7126
|
-
lastError: result.lastError ?? null,
|
|
7127
|
-
updatedAt: nowIso(firedAt)
|
|
7128
|
-
};
|
|
7129
|
-
rows[idx] = next;
|
|
7130
|
-
writeAll(rows);
|
|
7131
|
-
return next;
|
|
7132
|
-
}
|
|
7133
|
-
|
|
7134
6786
|
// src/orchestrator/schedule-runner.ts
|
|
7135
6787
|
var SET_TIMEOUT_MAX = 2147483647;
|
|
7136
6788
|
var fireHooks = null;
|
|
@@ -7141,7 +6793,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7141
6793
|
${prompt}`;
|
|
7142
6794
|
}
|
|
7143
6795
|
async function defaultDeps() {
|
|
7144
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6796
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-3F53AZEN.js");
|
|
7145
6797
|
const orch = getOrchestrator2();
|
|
7146
6798
|
return {
|
|
7147
6799
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7197,7 +6849,15 @@ async function fireSchedule(id) {
|
|
|
7197
6849
|
const deps = fireHooks ?? await defaultDeps();
|
|
7198
6850
|
const prompt = formatScheduledPrompt(schedule.name, schedule.prompt);
|
|
7199
6851
|
const target = schedule.threadId ? deps.findThread(schedule.threadId) : null;
|
|
7200
|
-
if (
|
|
6852
|
+
if (schedule.threadId && (!target || target.status === "archived")) {
|
|
6853
|
+
deleteSchedule(schedule.id);
|
|
6854
|
+
return {
|
|
6855
|
+
...schedule,
|
|
6856
|
+
enabled: false,
|
|
6857
|
+
lastError: "Removed because its chat is archived or gone."
|
|
6858
|
+
};
|
|
6859
|
+
}
|
|
6860
|
+
if (target) {
|
|
7201
6861
|
const sent = await deps.send(target.id, prompt, {
|
|
7202
6862
|
attachments: schedule.attachments,
|
|
7203
6863
|
options: scheduleSendOptions(schedule)
|
|
@@ -7207,8 +6867,7 @@ async function fireSchedule(id) {
|
|
|
7207
6867
|
lastError: null
|
|
7208
6868
|
});
|
|
7209
6869
|
}
|
|
7210
|
-
const
|
|
7211
|
-
const archiveFresh = schedule.archiveChat !== false && !pinReplacement;
|
|
6870
|
+
const archiveFresh = schedule.archiveChat !== false;
|
|
7212
6871
|
const created = await deps.startOrchestration({
|
|
7213
6872
|
goal: prompt,
|
|
7214
6873
|
agent: pickAgent(schedule),
|
|
@@ -7221,9 +6880,6 @@ async function fireSchedule(id) {
|
|
|
7221
6880
|
...archiveFresh ? { ephemeralAutomationId: schedule.id } : {},
|
|
7222
6881
|
ephemeralTitle: schedule.name
|
|
7223
6882
|
});
|
|
7224
|
-
if (pinReplacement) {
|
|
7225
|
-
updateSchedule(schedule.id, { threadId: created.id });
|
|
7226
|
-
}
|
|
7227
6883
|
return recordScheduleRun(schedule.id, {
|
|
7228
6884
|
lastThreadId: created.id,
|
|
7229
6885
|
lastError: null
|
|
@@ -7426,7 +7082,7 @@ var Orchestrator = class {
|
|
|
7426
7082
|
this.lightReconcileAt.set(repoPath, Date.now());
|
|
7427
7083
|
for (const thread of listThreads()) {
|
|
7428
7084
|
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
7429
|
-
if (!
|
|
7085
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
7430
7086
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7431
7087
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7432
7088
|
}
|
|
@@ -7455,7 +7111,7 @@ var Orchestrator = class {
|
|
|
7455
7111
|
}
|
|
7456
7112
|
continue;
|
|
7457
7113
|
}
|
|
7458
|
-
if (!
|
|
7114
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
7459
7115
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7460
7116
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7461
7117
|
continue;
|
|
@@ -7492,7 +7148,7 @@ var Orchestrator = class {
|
|
|
7492
7148
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
7493
7149
|
});
|
|
7494
7150
|
}
|
|
7495
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
7151
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-SA4HX3ZQ.js");
|
|
7496
7152
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
7497
7153
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
7498
7154
|
}
|
|
@@ -7886,7 +7542,7 @@ var Orchestrator = class {
|
|
|
7886
7542
|
}
|
|
7887
7543
|
await setup;
|
|
7888
7544
|
if (skipSetup) return;
|
|
7889
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
7545
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-SA4HX3ZQ.js");
|
|
7890
7546
|
if (autoRunAfterSetupEnabled()) {
|
|
7891
7547
|
try {
|
|
7892
7548
|
await this.startDev(threadId);
|
|
@@ -8271,7 +7927,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
8271
7927
|
}
|
|
8272
7928
|
const isBrightsy = fresh.agent === "brightsy";
|
|
8273
7929
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
8274
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-
|
|
7930
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-SA4HX3ZQ.js");
|
|
8275
7931
|
const gitAuthMode = getGithubGitAuthMode();
|
|
8276
7932
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
8277
7933
|
githubSlug: turnOrigin?.forge === "github" ? turnOrigin.slug : await withTimeout(resolveGithubRepoSlug(fresh.worktreePath), 8e3, "resolveGithubRepoSlug").catch(() => null),
|
|
@@ -8905,7 +8561,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
8905
8561
|
const request = sameIntent ? pending : {
|
|
8906
8562
|
op,
|
|
8907
8563
|
scriptName: scriptName ?? null,
|
|
8908
|
-
requestId:
|
|
8564
|
+
requestId: randomUUID4(),
|
|
8909
8565
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8910
8566
|
};
|
|
8911
8567
|
if (!sameIntent) {
|
|
@@ -9357,7 +9013,9 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9357
9013
|
const taskState = deriveTaskState({
|
|
9358
9014
|
status: thread.status,
|
|
9359
9015
|
stillRunning,
|
|
9360
|
-
lastAgentParts: lastAgent?.parts
|
|
9016
|
+
lastAgentParts: lastAgent?.parts,
|
|
9017
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature,
|
|
9018
|
+
userAnswered: userRepliedAfterAgent(thread.messages, lastAgent)
|
|
9361
9019
|
});
|
|
9362
9020
|
const block = thread.agentBlock?.reason?.trim() ? thread.agentBlock : null;
|
|
9363
9021
|
return {
|
|
@@ -9611,7 +9269,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9611
9269
|
if (Object.keys(patch).length === 0) continue;
|
|
9612
9270
|
updateThread(t.id, patch);
|
|
9613
9271
|
}
|
|
9614
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
9272
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-SA4HX3ZQ.js");
|
|
9615
9273
|
const latest = this.requireThread(thread.id);
|
|
9616
9274
|
if (!shouldAutoArchiveOnPrMerge({
|
|
9617
9275
|
previousPrState: prevState || null,
|
|
@@ -9935,7 +9593,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9935
9593
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
9936
9594
|
} catch {
|
|
9937
9595
|
}
|
|
9938
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
9596
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-SA4HX3ZQ.js");
|
|
9939
9597
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
9940
9598
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
9941
9599
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -9957,7 +9615,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9957
9615
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
9958
9616
|
return restored2;
|
|
9959
9617
|
}
|
|
9960
|
-
if (!
|
|
9618
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
9961
9619
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
9962
9620
|
throw new Error(
|
|
9963
9621
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -10073,7 +9731,7 @@ async function startOrchestration(opts) {
|
|
|
10073
9731
|
sourceRef: "default",
|
|
10074
9732
|
...createOpts
|
|
10075
9733
|
}).catch(async () => {
|
|
10076
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9734
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-JBNEMJ5Z.js");
|
|
10077
9735
|
const repo = await resolveRepoRoot2(repoPath);
|
|
10078
9736
|
const def = await resolveDefaultBranch2(repo);
|
|
10079
9737
|
return orch.createThread({
|
|
@@ -10083,7 +9741,7 @@ async function startOrchestration(opts) {
|
|
|
10083
9741
|
repoPath: repo
|
|
10084
9742
|
});
|
|
10085
9743
|
});
|
|
10086
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
9744
|
+
const { updateThread: upd } = await import("./thread-store-4WE24XA2.js");
|
|
10087
9745
|
const updated = upd(thread.id, {
|
|
10088
9746
|
sourceType: "orchestration",
|
|
10089
9747
|
sourceRef: goal
|
|
@@ -10140,14 +9798,6 @@ export {
|
|
|
10140
9798
|
formatListedIssuesForMcp,
|
|
10141
9799
|
mcpJson,
|
|
10142
9800
|
registerViewerContextTools,
|
|
10143
|
-
parseWeeklyDays,
|
|
10144
|
-
resolveScheduleThreadId,
|
|
10145
|
-
listSchedules,
|
|
10146
|
-
scheduleNeedsCaffeinate,
|
|
10147
|
-
getSchedule,
|
|
10148
|
-
createSchedule,
|
|
10149
|
-
updateSchedule,
|
|
10150
|
-
deleteSchedule,
|
|
10151
9801
|
fireSchedule,
|
|
10152
9802
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
10153
9803
|
RUN_SCRIPT_DESKTOP_ADOPT_MS,
|