@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
formatOptionalServicesDirectiveForTurn,
|
|
3
3
|
formatOptionalServicesReminderForTurn
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ECY7WL6T.js";
|
|
5
5
|
import {
|
|
6
6
|
extractPresentedPlan,
|
|
7
7
|
isPresentPlanToolName,
|
|
@@ -21,22 +21,19 @@ import {
|
|
|
21
21
|
parseSessionQuotaResetAt,
|
|
22
22
|
planModeTurnInstruction,
|
|
23
23
|
resolveQuotaFallbackAgent
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-NQGLDQYB.js";
|
|
25
25
|
import {
|
|
26
26
|
applyWorktreePkgCacheEnv,
|
|
27
|
-
askBlockStillWaiting,
|
|
28
27
|
buildBrightsySessionSeed,
|
|
29
28
|
buildForkTranscriptAttachment,
|
|
30
29
|
buildSessionSeed,
|
|
31
30
|
copyConfiguredFiles,
|
|
32
31
|
createChatTab,
|
|
33
32
|
deriveTaskState,
|
|
34
|
-
extractPendingPlanQuestions,
|
|
35
33
|
forkChatTab,
|
|
36
34
|
forkMessageSlice,
|
|
37
35
|
getDefaultRunScript,
|
|
38
36
|
getRunMode,
|
|
39
|
-
isAskUserToolName,
|
|
40
37
|
isJobContinuePrompt,
|
|
41
38
|
isWorktreeRunProcessKey,
|
|
42
39
|
killDetachedRunTree,
|
|
@@ -46,9 +43,7 @@ import {
|
|
|
46
43
|
listRunningDetachedJobs,
|
|
47
44
|
maybeCompactContext,
|
|
48
45
|
mergeWorktreeActiveRuns,
|
|
49
|
-
parsePlanQuestionsInput,
|
|
50
46
|
planJobContinue,
|
|
51
|
-
planQuestionsSignature,
|
|
52
47
|
requestReview,
|
|
53
48
|
resolveWorktreeSetupLog,
|
|
54
49
|
runArchiveScript,
|
|
@@ -56,10 +51,11 @@ import {
|
|
|
56
51
|
startDevServer,
|
|
57
52
|
threadsSharingWorktree,
|
|
58
53
|
turnWatchedDetachedJob,
|
|
54
|
+
userRepliedAfterAgent,
|
|
59
55
|
worktreeDevProcessKey,
|
|
60
56
|
worktreeRunProcessKey,
|
|
61
57
|
worktreeSetupProcessKey
|
|
62
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-X3XTO45Y.js";
|
|
63
59
|
import {
|
|
64
60
|
applyAgentEvent,
|
|
65
61
|
clipAgentEventForPaint,
|
|
@@ -102,7 +98,7 @@ import {
|
|
|
102
98
|
stageAbsolutePathsAsAttachments,
|
|
103
99
|
stageBuffersAsAttachments,
|
|
104
100
|
syncWorkspacesFromThreads
|
|
105
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-RDXODLEN.js";
|
|
106
102
|
import {
|
|
107
103
|
addPrStackLayer,
|
|
108
104
|
allocateTeamSlug,
|
|
@@ -153,23 +149,27 @@ import {
|
|
|
153
149
|
resolveRepoRoot,
|
|
154
150
|
switchWorktreeBranch,
|
|
155
151
|
withRepoGitLock
|
|
156
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-R2C45NHT.js";
|
|
157
153
|
import {
|
|
158
154
|
REVIEW_TAB_TITLE,
|
|
159
155
|
agentNicknameFromWorktreePath,
|
|
160
156
|
appendMessage,
|
|
161
157
|
createEmptyThread,
|
|
158
|
+
deleteSchedule,
|
|
162
159
|
deleteThreadRecord,
|
|
163
160
|
findThreadByRef,
|
|
164
161
|
formatReviewWriteGateDirective,
|
|
165
162
|
formatReviewWriteGateReminder,
|
|
163
|
+
getSchedule,
|
|
166
164
|
isPlaceholderBranch,
|
|
167
165
|
isReviewWriteGatedThread,
|
|
168
166
|
isWorktreeIdentityTitle,
|
|
167
|
+
listSchedules,
|
|
169
168
|
listThreads,
|
|
170
169
|
normalizeWorkspaceTags,
|
|
171
170
|
normalizeWorktreePath,
|
|
172
171
|
readThread,
|
|
172
|
+
recordScheduleRun,
|
|
173
173
|
setStatus,
|
|
174
174
|
teamSlugFromName,
|
|
175
175
|
ticketSlugForBranch,
|
|
@@ -181,11 +181,18 @@ import {
|
|
|
181
181
|
worktreeNameFromPath,
|
|
182
182
|
worktreeSlugForTicket,
|
|
183
183
|
writeThread
|
|
184
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-Y6OHM672.js";
|
|
185
|
+
import {
|
|
186
|
+
askBlockStillWaiting,
|
|
187
|
+
extractPendingPlanQuestions,
|
|
188
|
+
isAskUserToolName,
|
|
189
|
+
parsePlanQuestionsInput,
|
|
190
|
+
planQuestionsSignature
|
|
191
|
+
} from "./chunk-NJV5YEKI.js";
|
|
185
192
|
import {
|
|
186
193
|
mcpServerIdForPermission,
|
|
187
194
|
mcpServerPermissionUpdate
|
|
188
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-N6ZF3XRP.js";
|
|
189
196
|
import {
|
|
190
197
|
createAgentStreamCoalescer
|
|
191
198
|
} from "./chunk-AXQ4ZWHK.js";
|
|
@@ -222,7 +229,6 @@ import {
|
|
|
222
229
|
archivedUpdatedMs,
|
|
223
230
|
assertOrchestratorCapableAgent,
|
|
224
231
|
autoCleanupHistoryEnabled,
|
|
225
|
-
caffeinateWhileSchedulesEnabled,
|
|
226
232
|
childEnvWithAppSettings,
|
|
227
233
|
coerceOrchestratorAgent,
|
|
228
234
|
followUpBehavior,
|
|
@@ -235,7 +241,6 @@ import {
|
|
|
235
241
|
historyRetentionStubMessage,
|
|
236
242
|
isAbleTimeConnected,
|
|
237
243
|
isLinearConnected,
|
|
238
|
-
isOrchestratorCapableAgent,
|
|
239
244
|
loadAppSettings,
|
|
240
245
|
orchestrationQuotaFallbackAgent,
|
|
241
246
|
planHistoryAgePurge,
|
|
@@ -252,10 +257,7 @@ import {
|
|
|
252
257
|
usageOnLimit,
|
|
253
258
|
withTurnScopedCost,
|
|
254
259
|
writeViewerContext
|
|
255
|
-
} from "./chunk-
|
|
256
|
-
import {
|
|
257
|
-
normalizeThinkingEffort
|
|
258
|
-
} from "./chunk-77WWLBCI.js";
|
|
260
|
+
} from "./chunk-D446IWPP.js";
|
|
259
261
|
import {
|
|
260
262
|
examplePrefixedBranch,
|
|
261
263
|
sanitizeGitBranchPrefix
|
|
@@ -269,9 +271,6 @@ import {
|
|
|
269
271
|
import {
|
|
270
272
|
releaseCaffeinateHoldForThread
|
|
271
273
|
} from "./chunk-LAWLUOWQ.js";
|
|
272
|
-
import {
|
|
273
|
-
writePrivateFile
|
|
274
|
-
} from "./chunk-JT7R45JB.js";
|
|
275
274
|
import {
|
|
276
275
|
annotateDevAccessRuns,
|
|
277
276
|
appDataDir,
|
|
@@ -325,8 +324,8 @@ function formatInjectedNoticesForTurn(notices) {
|
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
// src/orchestrator/orchestrator.ts
|
|
328
|
-
import { randomUUID as
|
|
329
|
-
import { existsSync as
|
|
327
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
328
|
+
import { existsSync as existsSync13 } from "fs";
|
|
330
329
|
|
|
331
330
|
// src/agents/spawn.ts
|
|
332
331
|
import { rmSync } from "fs";
|
|
@@ -518,9 +517,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
518
517
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
519
518
|
);
|
|
520
519
|
}
|
|
521
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
520
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4CTLU2BV.js");
|
|
522
521
|
if (isGlobalThread2(thread)) {
|
|
523
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
522
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-3PJLU3UH.js");
|
|
524
523
|
ensureGlobalCoordinatorCwd2(
|
|
525
524
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
526
525
|
);
|
|
@@ -2013,6 +2012,9 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
2013
2012
|
at
|
|
2014
2013
|
);
|
|
2015
2014
|
}
|
|
2015
|
+
function attentionOutranksAsk(existing) {
|
|
2016
|
+
return existing?.source === "reported" || existing?.source === "permission";
|
|
2017
|
+
}
|
|
2016
2018
|
function withStampedQuestions(decision, existing) {
|
|
2017
2019
|
if (decision.source !== "ask_user" || decision.questions?.length) return decision;
|
|
2018
2020
|
if (existing?.source !== "ask_user" || !existing.questions?.length) return decision;
|
|
@@ -2026,12 +2028,37 @@ function agentBlockAfterTurn(input) {
|
|
|
2026
2028
|
if (input.failed) return null;
|
|
2027
2029
|
const decision = decisionBlockFromParts(input.parts, input.planMode);
|
|
2028
2030
|
if (decision) {
|
|
2031
|
+
if (decision.source === "ask_user" && attentionOutranksAsk(input.existing)) {
|
|
2032
|
+
return input.existing ?? null;
|
|
2033
|
+
}
|
|
2029
2034
|
const next = withStampedQuestions(decision, input.existing);
|
|
2030
2035
|
if (isDismissedAskUserBlock(next, input.dismissedQuestionSignature)) {
|
|
2031
2036
|
return input.existing?.source === "reported" ? input.existing : null;
|
|
2032
2037
|
}
|
|
2033
2038
|
return next;
|
|
2034
2039
|
}
|
|
2040
|
+
const pending = extractPendingPlanQuestions(input.parts);
|
|
2041
|
+
if (pending && attentionOutranksAsk(input.existing)) {
|
|
2042
|
+
return input.existing ?? null;
|
|
2043
|
+
}
|
|
2044
|
+
if (pending) {
|
|
2045
|
+
const kept = withStampedQuestions(
|
|
2046
|
+
{
|
|
2047
|
+
...makeAgentBlock(
|
|
2048
|
+
"ask_user",
|
|
2049
|
+
formatAskUserNotifyMessage(pending.questions),
|
|
2050
|
+
input.existing?.source === "ask_user" ? input.existing.at : void 0
|
|
2051
|
+
),
|
|
2052
|
+
onScreen: true,
|
|
2053
|
+
questionSignature: pending.signature,
|
|
2054
|
+
questions: pending.questions
|
|
2055
|
+
},
|
|
2056
|
+
input.existing
|
|
2057
|
+
);
|
|
2058
|
+
if (!isDismissedAskUserBlock(kept, input.dismissedQuestionSignature)) return kept;
|
|
2059
|
+
} else if (input.existing?.source === "ask_user" && input.existing.onScreen && input.existing.questions?.length && !isDismissedAskUserBlock(input.existing, input.dismissedQuestionSignature)) {
|
|
2060
|
+
return input.existing;
|
|
2061
|
+
}
|
|
2035
2062
|
if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
|
|
2036
2063
|
return null;
|
|
2037
2064
|
}
|
|
@@ -2060,11 +2087,15 @@ function askBlocksEqual(a, b) {
|
|
|
2060
2087
|
if (!a || !b) return false;
|
|
2061
2088
|
return a.source === b.source && a.reason === b.reason && a.at === b.at && a.onScreen === b.onScreen && a.questionSignature === b.questionSignature;
|
|
2062
2089
|
}
|
|
2063
|
-
function askBlockAfterLiveParts(existing, parts) {
|
|
2090
|
+
function askBlockAfterLiveParts(existing, parts, dismissedQuestionSignature) {
|
|
2091
|
+
if (attentionOutranksAsk(existing)) return existing ?? null;
|
|
2092
|
+
if (isDismissedAskUserBlock(existing, dismissedQuestionSignature)) return null;
|
|
2093
|
+
const dismissed = dismissedQuestionSignature?.trim() ?? "";
|
|
2094
|
+
let pending = extractPendingPlanQuestions(parts);
|
|
2095
|
+
if (dismissed && pending?.signature === dismissed) pending = null;
|
|
2064
2096
|
const last = lastTopLevelTool(parts);
|
|
2065
2097
|
if (last?.type === "tool" && isAskUserToolName(last.name)) {
|
|
2066
2098
|
if (existing?.source === "ask_user" && existing.onScreen) return existing;
|
|
2067
|
-
const pending = extractPendingPlanQuestions(parts);
|
|
2068
2099
|
const questions = pending?.questions ?? existing?.questions;
|
|
2069
2100
|
if (!questions?.length) {
|
|
2070
2101
|
return existing?.source === "ask_user" ? { ...existing, onScreen: true } : existing ?? null;
|
|
@@ -2077,13 +2108,32 @@ function askBlockAfterLiveParts(existing, parts) {
|
|
|
2077
2108
|
questions
|
|
2078
2109
|
};
|
|
2079
2110
|
}
|
|
2111
|
+
if (pending) {
|
|
2112
|
+
if (existing?.source === "ask_user" && existing.onScreen && existing.questions?.length) {
|
|
2113
|
+
return existing;
|
|
2114
|
+
}
|
|
2115
|
+
const at = existing?.source === "ask_user" ? existing.at : void 0;
|
|
2116
|
+
return {
|
|
2117
|
+
...makeAgentBlock("ask_user", formatAskUserNotifyMessage(pending.questions), at),
|
|
2118
|
+
onScreen: true,
|
|
2119
|
+
questionSignature: pending.signature,
|
|
2120
|
+
questions: pending.questions
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
if (existing?.source === "ask_user" && existing.onScreen && existing.questions?.length) {
|
|
2124
|
+
return existing;
|
|
2125
|
+
}
|
|
2080
2126
|
if (last && existing?.source === "ask_user") return null;
|
|
2081
2127
|
return existing ?? null;
|
|
2082
2128
|
}
|
|
2083
2129
|
function syncAskUserBlockFromLive(threadId, parts) {
|
|
2084
2130
|
const thread = readThread(threadId);
|
|
2085
2131
|
if (!thread || thread.status === "archived") return;
|
|
2086
|
-
const next = askBlockAfterLiveParts(
|
|
2132
|
+
const next = askBlockAfterLiveParts(
|
|
2133
|
+
thread.agentBlock,
|
|
2134
|
+
parts,
|
|
2135
|
+
thread.dismissedQuestionSignature
|
|
2136
|
+
);
|
|
2087
2137
|
if (askBlocksEqual(thread.agentBlock, next)) return;
|
|
2088
2138
|
updateThread(threadId, { agentBlock: next });
|
|
2089
2139
|
}
|
|
@@ -3163,7 +3213,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3163
3213
|
});
|
|
3164
3214
|
await requireAgent(resolved.agent);
|
|
3165
3215
|
if (input.cowboy) {
|
|
3166
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3216
|
+
const { cowboyModeEnabled } = await import("./app-settings-A5D364JD.js");
|
|
3167
3217
|
if (!cowboyModeEnabled()) {
|
|
3168
3218
|
throw new Error(
|
|
3169
3219
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -3222,7 +3272,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3222
3272
|
let sourceIsFork = false;
|
|
3223
3273
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3224
3274
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3225
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3275
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-OW7LTFQD.js");
|
|
3226
3276
|
const task = await ensureAbleTimeTask({
|
|
3227
3277
|
title: title?.trim() || "Untitled work",
|
|
3228
3278
|
description: input.prompt?.trim() || void 0
|
|
@@ -3333,7 +3383,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3333
3383
|
return readThread(thread.id) ?? thread;
|
|
3334
3384
|
}
|
|
3335
3385
|
async function listLinearIssues(agent, repoPath) {
|
|
3336
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3386
|
+
const { getAdapter: getAdapter2 } = await import("./agents-IYBY3JT5.js");
|
|
3337
3387
|
await requireAgent(agent, { requireLinear: true });
|
|
3338
3388
|
const adapter = getAdapter2(agent);
|
|
3339
3389
|
if (!adapter.listLinearIssues) {
|
|
@@ -4116,7 +4166,7 @@ async function adoptThread(input) {
|
|
|
4116
4166
|
messages: input.messages ?? []
|
|
4117
4167
|
});
|
|
4118
4168
|
writeThread(thread);
|
|
4119
|
-
const { addWorkspace: addWorkspace2 } = await import("./workspaces-
|
|
4169
|
+
const { addWorkspace: addWorkspace2 } = await import("./workspaces-WYCVZ6XH.js");
|
|
4120
4170
|
await addWorkspace2(repoPath);
|
|
4121
4171
|
const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-INRDQFWV.js");
|
|
4122
4172
|
await ensureWorktreeSideboardIgnored(input.worktreePath);
|
|
@@ -6519,7 +6569,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
6519
6569
|
lines.push(formatDevAccessHint(opts?.activeRuns));
|
|
6520
6570
|
lines.push("");
|
|
6521
6571
|
lines.push(
|
|
6522
|
-
"Automations (sidebar, after Board): `create_schedule` / `list_schedules` (`at` / `every` / `cron` / `time`+`days`). `archiveChat=false` keeps the new chat. `chatId=self`
|
|
6572
|
+
"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."
|
|
6523
6573
|
);
|
|
6524
6574
|
lines.push(
|
|
6525
6575
|
"`set_workspace_tags` labels this checkout (omit ref; replace, add, or remove). Not another checkout."
|
|
@@ -6539,7 +6589,7 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
6539
6589
|
return formatConnectedOrchestratorReminder(connectedOrchestrator(thread, find));
|
|
6540
6590
|
}
|
|
6541
6591
|
function formatWorktreeReminder() {
|
|
6542
|
-
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
|
|
6592
|
+
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).";
|
|
6543
6593
|
}
|
|
6544
6594
|
function formatClaudeSubagentReminder() {
|
|
6545
6595
|
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.';
|
|
@@ -7083,424 +7133,6 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
7083
7133
|
}
|
|
7084
7134
|
}
|
|
7085
7135
|
|
|
7086
|
-
// src/store/schedules.ts
|
|
7087
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
7088
|
-
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
|
|
7089
|
-
import { join as join14 } from "path";
|
|
7090
|
-
|
|
7091
|
-
// src/store/schedule-when.ts
|
|
7092
|
-
import { Cron } from "croner";
|
|
7093
|
-
var WEEKDAY_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
7094
|
-
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
7095
|
-
var UNIT_MS = {
|
|
7096
|
-
s: 1e3,
|
|
7097
|
-
m: 6e4,
|
|
7098
|
-
h: 36e5,
|
|
7099
|
-
d: 864e5
|
|
7100
|
-
};
|
|
7101
|
-
var DAY_ALIASES = {
|
|
7102
|
-
sun: 0,
|
|
7103
|
-
sunday: 0,
|
|
7104
|
-
mon: 1,
|
|
7105
|
-
monday: 1,
|
|
7106
|
-
tue: 2,
|
|
7107
|
-
tues: 2,
|
|
7108
|
-
tuesday: 2,
|
|
7109
|
-
wed: 3,
|
|
7110
|
-
wednesday: 3,
|
|
7111
|
-
thu: 4,
|
|
7112
|
-
thur: 4,
|
|
7113
|
-
thurs: 4,
|
|
7114
|
-
thursday: 4,
|
|
7115
|
-
fri: 5,
|
|
7116
|
-
friday: 5,
|
|
7117
|
-
sat: 6,
|
|
7118
|
-
saturday: 6
|
|
7119
|
-
};
|
|
7120
|
-
var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/;
|
|
7121
|
-
function parseDurationMs(every) {
|
|
7122
|
-
const m = every.trim().match(DURATION_RE);
|
|
7123
|
-
if (!m) return null;
|
|
7124
|
-
const n = Number.parseInt(m[1], 10);
|
|
7125
|
-
if (!Number.isFinite(n) || n <= 0) return null;
|
|
7126
|
-
const unit = m[2].toLowerCase();
|
|
7127
|
-
return n * UNIT_MS[unit];
|
|
7128
|
-
}
|
|
7129
|
-
function dayIndex(token) {
|
|
7130
|
-
const text3 = token.trim().toLowerCase();
|
|
7131
|
-
if (/^[0-6]$/.test(text3)) return Number(text3);
|
|
7132
|
-
return DAY_ALIASES[text3];
|
|
7133
|
-
}
|
|
7134
|
-
function normalizeWeekdays(days) {
|
|
7135
|
-
const set = /* @__PURE__ */ new Set();
|
|
7136
|
-
for (const day of days) {
|
|
7137
|
-
if (!Number.isInteger(day) || day < 0 || day > 6) {
|
|
7138
|
-
throw new Error("Days must be 0 (Sunday) through 6 (Saturday)");
|
|
7139
|
-
}
|
|
7140
|
-
set.add(day);
|
|
7141
|
-
}
|
|
7142
|
-
if (set.size === 0) throw new Error("Pick at least one day");
|
|
7143
|
-
return [...set].sort((a, b) => a - b);
|
|
7144
|
-
}
|
|
7145
|
-
function parseWeeklyDays(raw) {
|
|
7146
|
-
const text3 = raw.trim().toLowerCase();
|
|
7147
|
-
if (!text3) throw new Error("Pick at least one day");
|
|
7148
|
-
if (text3 === "daily" || text3 === "all" || text3 === "every day" || text3 === "everyday") {
|
|
7149
|
-
return [0, 1, 2, 3, 4, 5, 6];
|
|
7150
|
-
}
|
|
7151
|
-
if (text3 === "weekdays" || text3 === "weekday") return [1, 2, 3, 4, 5];
|
|
7152
|
-
if (text3 === "weekends" || text3 === "weekend") return [0, 6];
|
|
7153
|
-
const days = [];
|
|
7154
|
-
for (const part of text3.split(/[\s,]+/).filter(Boolean)) {
|
|
7155
|
-
const range = part.split("-");
|
|
7156
|
-
if (range.length === 2 && range[0] && range[1]) {
|
|
7157
|
-
const start = dayIndex(range[0]);
|
|
7158
|
-
const end = dayIndex(range[1]);
|
|
7159
|
-
if (start === void 0 || end === void 0) {
|
|
7160
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
7161
|
-
}
|
|
7162
|
-
if (start <= end) {
|
|
7163
|
-
for (let d = start; d <= end; d++) days.push(d);
|
|
7164
|
-
} else {
|
|
7165
|
-
for (let d = start; d <= 6; d++) days.push(d);
|
|
7166
|
-
for (let d = 0; d <= end; d++) days.push(d);
|
|
7167
|
-
}
|
|
7168
|
-
continue;
|
|
7169
|
-
}
|
|
7170
|
-
const n = dayIndex(part);
|
|
7171
|
-
if (n === void 0) {
|
|
7172
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
7173
|
-
}
|
|
7174
|
-
days.push(n);
|
|
7175
|
-
}
|
|
7176
|
-
return normalizeWeekdays(days);
|
|
7177
|
-
}
|
|
7178
|
-
function normalizeWeeklyTime(raw) {
|
|
7179
|
-
const m = raw.trim().match(TIME_RE);
|
|
7180
|
-
if (!m) throw new Error(`Invalid time: ${raw} (use HH:mm, 24-hour)`);
|
|
7181
|
-
return `${m[1]}:${m[2]}`;
|
|
7182
|
-
}
|
|
7183
|
-
function formatWeeklyDays(days) {
|
|
7184
|
-
const key = normalizeWeekdays(days).join(",");
|
|
7185
|
-
if (key === "0,1,2,3,4,5,6") return "daily";
|
|
7186
|
-
if (key === "1,2,3,4,5") return "weekdays";
|
|
7187
|
-
if (key === "0,6") return "weekends";
|
|
7188
|
-
return normalizeWeekdays(days).map((day) => WEEKDAY_LABELS[day]).join(", ");
|
|
7189
|
-
}
|
|
7190
|
-
function weeklyCronExpr(when) {
|
|
7191
|
-
const time = normalizeWeeklyTime(when.time);
|
|
7192
|
-
const [hh, mm] = time.split(":");
|
|
7193
|
-
const days = normalizeWeekdays(when.days);
|
|
7194
|
-
return `${Number(mm)} ${Number(hh)} * * ${days.join(",")}`;
|
|
7195
|
-
}
|
|
7196
|
-
function computeNextRunAt(when, from = /* @__PURE__ */ new Date()) {
|
|
7197
|
-
if (when.kind === "once") {
|
|
7198
|
-
const at = new Date(when.at);
|
|
7199
|
-
if (Number.isNaN(at.getTime())) {
|
|
7200
|
-
throw new Error(`Invalid once-at datetime: ${when.at}`);
|
|
7201
|
-
}
|
|
7202
|
-
return at;
|
|
7203
|
-
}
|
|
7204
|
-
if (when.kind === "every") {
|
|
7205
|
-
const ms = parseDurationMs(when.every);
|
|
7206
|
-
if (!ms) {
|
|
7207
|
-
throw new Error(`Invalid interval: ${when.every} (use 15m, 1h, 6h, 1d)`);
|
|
7208
|
-
}
|
|
7209
|
-
return new Date(from.getTime() + ms);
|
|
7210
|
-
}
|
|
7211
|
-
if (when.kind === "weekly") {
|
|
7212
|
-
return computeNextRunAt(
|
|
7213
|
-
{ kind: "cron", expr: weeklyCronExpr(when), tz: when.tz },
|
|
7214
|
-
from
|
|
7215
|
-
);
|
|
7216
|
-
}
|
|
7217
|
-
try {
|
|
7218
|
-
const job = new Cron(when.expr, {
|
|
7219
|
-
timezone: when.tz?.trim() || void 0,
|
|
7220
|
-
paused: true
|
|
7221
|
-
});
|
|
7222
|
-
const next = job.nextRun(from);
|
|
7223
|
-
if (!next) {
|
|
7224
|
-
throw new Error(`Cron expression has no next run: ${when.expr}`);
|
|
7225
|
-
}
|
|
7226
|
-
return next;
|
|
7227
|
-
} catch (err) {
|
|
7228
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
7229
|
-
throw new Error(`Invalid cron: ${message}`);
|
|
7230
|
-
}
|
|
7231
|
-
}
|
|
7232
|
-
function formatScheduleWhen(when) {
|
|
7233
|
-
if (when.kind === "once") return `once at ${when.at}`;
|
|
7234
|
-
if (when.kind === "every") return `every ${when.every}`;
|
|
7235
|
-
if (when.kind === "weekly") {
|
|
7236
|
-
const label = `${formatWeeklyDays(when.days)} at ${normalizeWeeklyTime(when.time)}`;
|
|
7237
|
-
const tz2 = when.tz?.trim();
|
|
7238
|
-
return tz2 ? `${label} (${tz2})` : label;
|
|
7239
|
-
}
|
|
7240
|
-
const tz = when.tz?.trim();
|
|
7241
|
-
return tz ? `cron ${when.expr} (${tz})` : `cron ${when.expr}`;
|
|
7242
|
-
}
|
|
7243
|
-
function normalizeWhen(raw) {
|
|
7244
|
-
if (!raw || typeof raw !== "object") {
|
|
7245
|
-
throw new Error("Schedule is missing `when`");
|
|
7246
|
-
}
|
|
7247
|
-
const rec = raw;
|
|
7248
|
-
const kind = rec.kind;
|
|
7249
|
-
if (kind === "once" && typeof rec.at === "string") {
|
|
7250
|
-
return { kind: "once", at: rec.at };
|
|
7251
|
-
}
|
|
7252
|
-
if (kind === "every" && typeof rec.every === "string") {
|
|
7253
|
-
return { kind: "every", every: rec.every };
|
|
7254
|
-
}
|
|
7255
|
-
if (kind === "cron" && typeof rec.expr === "string") {
|
|
7256
|
-
return {
|
|
7257
|
-
kind: "cron",
|
|
7258
|
-
expr: rec.expr,
|
|
7259
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
7260
|
-
};
|
|
7261
|
-
}
|
|
7262
|
-
if (kind === "weekly" && Array.isArray(rec.days) && typeof rec.time === "string") {
|
|
7263
|
-
return {
|
|
7264
|
-
kind: "weekly",
|
|
7265
|
-
days: normalizeWeekdays(rec.days.map((day) => Number(day))),
|
|
7266
|
-
time: normalizeWeeklyTime(rec.time),
|
|
7267
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
7268
|
-
};
|
|
7269
|
-
}
|
|
7270
|
-
throw new Error("Schedule `when` must be once, every, weekly, or cron");
|
|
7271
|
-
}
|
|
7272
|
-
|
|
7273
|
-
// src/store/schedules.ts
|
|
7274
|
-
function schedulesPath() {
|
|
7275
|
-
return join14(appDataDir(), "schedules.json");
|
|
7276
|
-
}
|
|
7277
|
-
function defaultScheduleName(prompt) {
|
|
7278
|
-
const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
7279
|
-
if (!line) return "Untitled automation";
|
|
7280
|
-
return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
|
|
7281
|
-
}
|
|
7282
|
-
function resolveScheduleThreadId(raw, env = process.env) {
|
|
7283
|
-
const value = raw?.trim() || "";
|
|
7284
|
-
if (!value) return null;
|
|
7285
|
-
if (value.toLowerCase() === "self") {
|
|
7286
|
-
return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
|
|
7287
|
-
}
|
|
7288
|
-
return value;
|
|
7289
|
-
}
|
|
7290
|
-
function nowIso(d = /* @__PURE__ */ new Date()) {
|
|
7291
|
-
return d.toISOString();
|
|
7292
|
-
}
|
|
7293
|
-
var ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
|
|
7294
|
-
"transcript",
|
|
7295
|
-
"file",
|
|
7296
|
-
"issue",
|
|
7297
|
-
"workspace",
|
|
7298
|
-
"diff-comment",
|
|
7299
|
-
"code-ref"
|
|
7300
|
-
]);
|
|
7301
|
-
function normalizeOptionalBool(raw) {
|
|
7302
|
-
if (raw === true || raw === false) return raw;
|
|
7303
|
-
return null;
|
|
7304
|
-
}
|
|
7305
|
-
function normalizeAutonomy(raw) {
|
|
7306
|
-
return raw === "default" || raw === "full" ? raw : null;
|
|
7307
|
-
}
|
|
7308
|
-
function normalizeAttachments(raw) {
|
|
7309
|
-
if (!Array.isArray(raw)) return [];
|
|
7310
|
-
const out = [];
|
|
7311
|
-
for (const item of raw) {
|
|
7312
|
-
if (!item || typeof item !== "object") continue;
|
|
7313
|
-
const row = item;
|
|
7314
|
-
if (typeof row.id !== "string" || !row.id.trim()) continue;
|
|
7315
|
-
if (typeof row.name !== "string" || !row.name) continue;
|
|
7316
|
-
if (typeof row.content !== "string") continue;
|
|
7317
|
-
if (!ATTACHMENT_KINDS.has(row.kind)) continue;
|
|
7318
|
-
const next = {
|
|
7319
|
-
id: row.id,
|
|
7320
|
-
name: row.name,
|
|
7321
|
-
kind: row.kind,
|
|
7322
|
-
content: row.content
|
|
7323
|
-
};
|
|
7324
|
-
if (typeof row.path === "string" && row.path) next.path = row.path;
|
|
7325
|
-
if (typeof row.previewDataUrl === "string" && row.previewDataUrl) {
|
|
7326
|
-
next.previewDataUrl = row.previewDataUrl;
|
|
7327
|
-
}
|
|
7328
|
-
out.push(next);
|
|
7329
|
-
}
|
|
7330
|
-
return out;
|
|
7331
|
-
}
|
|
7332
|
-
function normalizeTask(raw) {
|
|
7333
|
-
const when = normalizeWhen(raw.when);
|
|
7334
|
-
const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
|
|
7335
|
-
return {
|
|
7336
|
-
id: raw.id,
|
|
7337
|
-
name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : defaultScheduleName(raw.prompt),
|
|
7338
|
-
prompt: String(raw.prompt ?? ""),
|
|
7339
|
-
enabled: Boolean(raw.enabled),
|
|
7340
|
-
when,
|
|
7341
|
-
threadId: raw.threadId?.trim() || null,
|
|
7342
|
-
agent,
|
|
7343
|
-
model: raw.model?.trim() || null,
|
|
7344
|
-
effort: normalizeThinkingEffort(raw.effort),
|
|
7345
|
-
fast: normalizeOptionalBool(raw.fast),
|
|
7346
|
-
planMode: normalizeOptionalBool(raw.planMode),
|
|
7347
|
-
autonomy: normalizeAutonomy(raw.autonomy),
|
|
7348
|
-
attachments: normalizeAttachments(raw.attachments),
|
|
7349
|
-
archiveChat: raw.archiveChat !== false,
|
|
7350
|
-
nextRunAt: raw.nextRunAt,
|
|
7351
|
-
lastRunAt: raw.lastRunAt ?? null,
|
|
7352
|
-
lastThreadId: raw.lastThreadId ?? null,
|
|
7353
|
-
lastError: raw.lastError ?? null,
|
|
7354
|
-
createdBy: raw.createdBy === "mcp" || raw.createdBy === "cli" || raw.createdBy === "ui" ? raw.createdBy : "ui",
|
|
7355
|
-
createdAt: raw.createdAt,
|
|
7356
|
-
updatedAt: raw.updatedAt
|
|
7357
|
-
};
|
|
7358
|
-
}
|
|
7359
|
-
function readAll() {
|
|
7360
|
-
const path = schedulesPath();
|
|
7361
|
-
if (!existsSync13(path)) return [];
|
|
7362
|
-
try {
|
|
7363
|
-
const parsed = JSON.parse(readFileSync8(path, "utf8"));
|
|
7364
|
-
if (!Array.isArray(parsed)) return [];
|
|
7365
|
-
return parsed.map((row) => {
|
|
7366
|
-
try {
|
|
7367
|
-
return normalizeTask(row);
|
|
7368
|
-
} catch {
|
|
7369
|
-
return null;
|
|
7370
|
-
}
|
|
7371
|
-
}).filter((row) => Boolean(row?.id && row.prompt));
|
|
7372
|
-
} catch {
|
|
7373
|
-
return [];
|
|
7374
|
-
}
|
|
7375
|
-
}
|
|
7376
|
-
function writeAll(rows) {
|
|
7377
|
-
writePrivateFile(schedulesPath(), `${JSON.stringify(rows, null, 2)}
|
|
7378
|
-
`);
|
|
7379
|
-
}
|
|
7380
|
-
function buildTask(input, now) {
|
|
7381
|
-
const prompt = input.prompt.trim();
|
|
7382
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
7383
|
-
const when = normalizeWhen(input.when);
|
|
7384
|
-
const nextRunAt = computeNextRunAt(when, now).toISOString();
|
|
7385
|
-
const ts = nowIso(now);
|
|
7386
|
-
const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
|
|
7387
|
-
return {
|
|
7388
|
-
id: randomUUID4(),
|
|
7389
|
-
name: input.name?.trim() || defaultScheduleName(prompt),
|
|
7390
|
-
prompt,
|
|
7391
|
-
enabled: input.enabled !== false,
|
|
7392
|
-
when,
|
|
7393
|
-
threadId: input.threadId?.trim() || null,
|
|
7394
|
-
agent,
|
|
7395
|
-
model: input.model?.trim() || null,
|
|
7396
|
-
effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
|
|
7397
|
-
fast: normalizeOptionalBool(input.fast),
|
|
7398
|
-
planMode: normalizeOptionalBool(input.planMode),
|
|
7399
|
-
autonomy: normalizeAutonomy(input.autonomy),
|
|
7400
|
-
attachments: normalizeAttachments(input.attachments),
|
|
7401
|
-
archiveChat: input.archiveChat !== false,
|
|
7402
|
-
nextRunAt,
|
|
7403
|
-
lastRunAt: null,
|
|
7404
|
-
lastThreadId: null,
|
|
7405
|
-
lastError: null,
|
|
7406
|
-
createdBy: input.createdBy,
|
|
7407
|
-
createdAt: ts,
|
|
7408
|
-
updatedAt: ts
|
|
7409
|
-
};
|
|
7410
|
-
}
|
|
7411
|
-
function listSchedules() {
|
|
7412
|
-
return readAll().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
|
|
7413
|
-
}
|
|
7414
|
-
function hasEnabledSchedules() {
|
|
7415
|
-
return listSchedules().some((row) => row.enabled);
|
|
7416
|
-
}
|
|
7417
|
-
function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
|
|
7418
|
-
if (!task.enabled) return false;
|
|
7419
|
-
const at = new Date(task.nextRunAt);
|
|
7420
|
-
if (Number.isNaN(at.getTime())) return false;
|
|
7421
|
-
return at.getTime() > now.getTime();
|
|
7422
|
-
}
|
|
7423
|
-
function ensureCaffeinateForFutureSchedule(task) {
|
|
7424
|
-
if (!scheduleNeedsCaffeinate(task)) return;
|
|
7425
|
-
if (caffeinateWhileSchedulesEnabled()) return;
|
|
7426
|
-
updateAdvancedSettings({ caffeinateWhileSchedules: true });
|
|
7427
|
-
}
|
|
7428
|
-
function getSchedule(id) {
|
|
7429
|
-
const key = id.trim();
|
|
7430
|
-
if (!key) return null;
|
|
7431
|
-
return readAll().find(
|
|
7432
|
-
(row) => row.id === key || row.id.startsWith(key) && key.length >= 8
|
|
7433
|
-
) ?? null;
|
|
7434
|
-
}
|
|
7435
|
-
function createSchedule(input) {
|
|
7436
|
-
const task = buildTask(input, /* @__PURE__ */ new Date());
|
|
7437
|
-
const rows = readAll();
|
|
7438
|
-
rows.push(task);
|
|
7439
|
-
writeAll(rows);
|
|
7440
|
-
ensureCaffeinateForFutureSchedule(task);
|
|
7441
|
-
return task;
|
|
7442
|
-
}
|
|
7443
|
-
function updateSchedule(id, patch) {
|
|
7444
|
-
const rows = readAll();
|
|
7445
|
-
const idx = rows.findIndex((row) => row.id === id || id.length >= 8 && row.id.startsWith(id));
|
|
7446
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
7447
|
-
const prev = rows[idx];
|
|
7448
|
-
const when = patch.when ? normalizeWhen(patch.when) : prev.when;
|
|
7449
|
-
const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
|
|
7450
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
7451
|
-
const whenChanged = patch.when !== void 0;
|
|
7452
|
-
const next = {
|
|
7453
|
-
...prev,
|
|
7454
|
-
name: patch.name !== void 0 ? patch.name.trim() || defaultScheduleName(prompt) : prev.name,
|
|
7455
|
-
prompt,
|
|
7456
|
-
enabled: patch.enabled ?? prev.enabled,
|
|
7457
|
-
when,
|
|
7458
|
-
threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
|
|
7459
|
-
agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
|
|
7460
|
-
model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
|
|
7461
|
-
effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
|
|
7462
|
-
fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
|
|
7463
|
-
planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
|
|
7464
|
-
autonomy: patch.autonomy !== void 0 ? normalizeAutonomy(patch.autonomy) : prev.autonomy,
|
|
7465
|
-
attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
|
|
7466
|
-
archiveChat: patch.archiveChat !== void 0 ? patch.archiveChat !== false : prev.archiveChat,
|
|
7467
|
-
nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
|
|
7468
|
-
lastError: whenChanged ? null : prev.lastError,
|
|
7469
|
-
updatedAt: nowIso()
|
|
7470
|
-
};
|
|
7471
|
-
rows[idx] = next;
|
|
7472
|
-
writeAll(rows);
|
|
7473
|
-
ensureCaffeinateForFutureSchedule(next);
|
|
7474
|
-
return next;
|
|
7475
|
-
}
|
|
7476
|
-
function deleteSchedule(id) {
|
|
7477
|
-
const rows = readAll();
|
|
7478
|
-
const next = rows.filter(
|
|
7479
|
-
(row) => row.id !== id && !(id.length >= 8 && row.id.startsWith(id))
|
|
7480
|
-
);
|
|
7481
|
-
if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
|
|
7482
|
-
writeAll(next);
|
|
7483
|
-
}
|
|
7484
|
-
function recordScheduleRun(id, result) {
|
|
7485
|
-
const rows = readAll();
|
|
7486
|
-
const idx = rows.findIndex((row) => row.id === id);
|
|
7487
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
7488
|
-
const prev = rows[idx];
|
|
7489
|
-
const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
|
|
7490
|
-
const next = {
|
|
7491
|
-
...prev,
|
|
7492
|
-
enabled: prev.when.kind === "once" ? false : prev.enabled,
|
|
7493
|
-
nextRunAt: prev.when.kind === "once" ? prev.nextRunAt : computeNextRunAt(prev.when, firedAt).toISOString(),
|
|
7494
|
-
lastRunAt: nowIso(firedAt),
|
|
7495
|
-
lastThreadId: result.lastThreadId !== void 0 ? result.lastThreadId : prev.lastThreadId,
|
|
7496
|
-
lastError: result.lastError ?? null,
|
|
7497
|
-
updatedAt: nowIso(firedAt)
|
|
7498
|
-
};
|
|
7499
|
-
rows[idx] = next;
|
|
7500
|
-
writeAll(rows);
|
|
7501
|
-
return next;
|
|
7502
|
-
}
|
|
7503
|
-
|
|
7504
7136
|
// src/orchestrator/schedule-runner.ts
|
|
7505
7137
|
var SET_TIMEOUT_MAX = 2147483647;
|
|
7506
7138
|
var fireHooks = null;
|
|
@@ -7511,7 +7143,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7511
7143
|
${prompt}`;
|
|
7512
7144
|
}
|
|
7513
7145
|
async function defaultDeps() {
|
|
7514
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7146
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-YY2JUYKD.js");
|
|
7515
7147
|
const orch = getOrchestrator2();
|
|
7516
7148
|
return {
|
|
7517
7149
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7567,7 +7199,15 @@ async function fireSchedule(id) {
|
|
|
7567
7199
|
const deps = fireHooks ?? await defaultDeps();
|
|
7568
7200
|
const prompt = formatScheduledPrompt(schedule.name, schedule.prompt);
|
|
7569
7201
|
const target = schedule.threadId ? deps.findThread(schedule.threadId) : null;
|
|
7570
|
-
if (
|
|
7202
|
+
if (schedule.threadId && (!target || target.status === "archived")) {
|
|
7203
|
+
deleteSchedule(schedule.id);
|
|
7204
|
+
return {
|
|
7205
|
+
...schedule,
|
|
7206
|
+
enabled: false,
|
|
7207
|
+
lastError: "Removed because its chat is archived or gone."
|
|
7208
|
+
};
|
|
7209
|
+
}
|
|
7210
|
+
if (target) {
|
|
7571
7211
|
const sent = await deps.send(target.id, prompt, {
|
|
7572
7212
|
attachments: schedule.attachments,
|
|
7573
7213
|
options: scheduleSendOptions(schedule)
|
|
@@ -7577,8 +7217,7 @@ async function fireSchedule(id) {
|
|
|
7577
7217
|
lastError: null
|
|
7578
7218
|
});
|
|
7579
7219
|
}
|
|
7580
|
-
const
|
|
7581
|
-
const archiveFresh = schedule.archiveChat !== false && !pinReplacement;
|
|
7220
|
+
const archiveFresh = schedule.archiveChat !== false;
|
|
7582
7221
|
const created = await deps.startOrchestration({
|
|
7583
7222
|
goal: prompt,
|
|
7584
7223
|
agent: pickAgent(schedule),
|
|
@@ -7591,9 +7230,6 @@ async function fireSchedule(id) {
|
|
|
7591
7230
|
...archiveFresh ? { ephemeralAutomationId: schedule.id } : {},
|
|
7592
7231
|
ephemeralTitle: schedule.name
|
|
7593
7232
|
});
|
|
7594
|
-
if (pinReplacement) {
|
|
7595
|
-
updateSchedule(schedule.id, { threadId: created.id });
|
|
7596
|
-
}
|
|
7597
7233
|
return recordScheduleRun(schedule.id, {
|
|
7598
7234
|
lastThreadId: created.id,
|
|
7599
7235
|
lastError: null
|
|
@@ -7796,7 +7432,7 @@ var Orchestrator = class {
|
|
|
7796
7432
|
this.lightReconcileAt.set(repoPath, Date.now());
|
|
7797
7433
|
for (const thread of listThreads()) {
|
|
7798
7434
|
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
7799
|
-
if (!
|
|
7435
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
7800
7436
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7801
7437
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7802
7438
|
}
|
|
@@ -7825,7 +7461,7 @@ var Orchestrator = class {
|
|
|
7825
7461
|
}
|
|
7826
7462
|
continue;
|
|
7827
7463
|
}
|
|
7828
|
-
if (!
|
|
7464
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
7829
7465
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
7830
7466
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
7831
7467
|
continue;
|
|
@@ -7862,7 +7498,7 @@ var Orchestrator = class {
|
|
|
7862
7498
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
7863
7499
|
});
|
|
7864
7500
|
}
|
|
7865
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
7501
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-A5D364JD.js");
|
|
7866
7502
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
7867
7503
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
7868
7504
|
}
|
|
@@ -8256,7 +7892,7 @@ var Orchestrator = class {
|
|
|
8256
7892
|
}
|
|
8257
7893
|
await setup;
|
|
8258
7894
|
if (skipSetup) return;
|
|
8259
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
7895
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-A5D364JD.js");
|
|
8260
7896
|
if (autoRunAfterSetupEnabled()) {
|
|
8261
7897
|
try {
|
|
8262
7898
|
await this.startDev(threadId);
|
|
@@ -8641,7 +8277,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
8641
8277
|
}
|
|
8642
8278
|
const isBrightsy = fresh.agent === "brightsy";
|
|
8643
8279
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
8644
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-
|
|
8280
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-A5D364JD.js");
|
|
8645
8281
|
const gitAuthMode = getGithubGitAuthMode();
|
|
8646
8282
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
8647
8283
|
githubSlug: turnOrigin?.forge === "github" ? turnOrigin.slug : await withTimeout(resolveGithubRepoSlug(fresh.worktreePath), 8e3, "resolveGithubRepoSlug").catch(() => null),
|
|
@@ -9275,7 +8911,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9275
8911
|
const request = sameIntent ? pending : {
|
|
9276
8912
|
op,
|
|
9277
8913
|
scriptName: scriptName ?? null,
|
|
9278
|
-
requestId:
|
|
8914
|
+
requestId: randomUUID4(),
|
|
9279
8915
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9280
8916
|
};
|
|
9281
8917
|
if (!sameIntent) {
|
|
@@ -9727,7 +9363,9 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9727
9363
|
const taskState = deriveTaskState({
|
|
9728
9364
|
status: thread.status,
|
|
9729
9365
|
stillRunning,
|
|
9730
|
-
lastAgentParts: lastAgent?.parts
|
|
9366
|
+
lastAgentParts: lastAgent?.parts,
|
|
9367
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature,
|
|
9368
|
+
userAnswered: userRepliedAfterAgent(thread.messages, lastAgent)
|
|
9731
9369
|
});
|
|
9732
9370
|
const block = thread.agentBlock?.reason?.trim() ? thread.agentBlock : null;
|
|
9733
9371
|
return {
|
|
@@ -9981,7 +9619,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
9981
9619
|
if (Object.keys(patch).length === 0) continue;
|
|
9982
9620
|
updateThread(t.id, patch);
|
|
9983
9621
|
}
|
|
9984
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
9622
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-A5D364JD.js");
|
|
9985
9623
|
const latest = this.requireThread(thread.id);
|
|
9986
9624
|
if (!shouldAutoArchiveOnPrMerge({
|
|
9987
9625
|
previousPrState: prevState || null,
|
|
@@ -10305,7 +9943,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
10305
9943
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
10306
9944
|
} catch {
|
|
10307
9945
|
}
|
|
10308
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
9946
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-A5D364JD.js");
|
|
10309
9947
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
10310
9948
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
10311
9949
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -10327,7 +9965,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
10327
9965
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
10328
9966
|
return restored2;
|
|
10329
9967
|
}
|
|
10330
|
-
if (!
|
|
9968
|
+
if (!existsSync13(thread.worktreePath)) {
|
|
10331
9969
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
10332
9970
|
throw new Error(
|
|
10333
9971
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -10443,7 +10081,7 @@ async function startOrchestration(opts) {
|
|
|
10443
10081
|
sourceRef: "default",
|
|
10444
10082
|
...createOpts
|
|
10445
10083
|
}).catch(async () => {
|
|
10446
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
10084
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-NNVRGPP4.js");
|
|
10447
10085
|
const repo = await resolveRepoRoot2(repoPath);
|
|
10448
10086
|
const def = await resolveDefaultBranch2(repo);
|
|
10449
10087
|
return orch.createThread({
|
|
@@ -10453,7 +10091,7 @@ async function startOrchestration(opts) {
|
|
|
10453
10091
|
repoPath: repo
|
|
10454
10092
|
});
|
|
10455
10093
|
});
|
|
10456
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
10094
|
+
const { updateThread: upd } = await import("./thread-store-K2ZNGUSM.js");
|
|
10457
10095
|
const updated = upd(thread.id, {
|
|
10458
10096
|
sourceType: "orchestration",
|
|
10459
10097
|
sourceRef: goal
|
|
@@ -10509,26 +10147,6 @@ export {
|
|
|
10509
10147
|
emptyRunLog,
|
|
10510
10148
|
sliceRunLogOutput,
|
|
10511
10149
|
readRunLog,
|
|
10512
|
-
WEEKDAY_LABELS,
|
|
10513
|
-
parseDurationMs,
|
|
10514
|
-
normalizeWeekdays,
|
|
10515
|
-
parseWeeklyDays,
|
|
10516
|
-
normalizeWeeklyTime,
|
|
10517
|
-
formatWeeklyDays,
|
|
10518
|
-
weeklyCronExpr,
|
|
10519
|
-
computeNextRunAt,
|
|
10520
|
-
formatScheduleWhen,
|
|
10521
|
-
schedulesPath,
|
|
10522
|
-
defaultScheduleName,
|
|
10523
|
-
resolveScheduleThreadId,
|
|
10524
|
-
listSchedules,
|
|
10525
|
-
hasEnabledSchedules,
|
|
10526
|
-
scheduleNeedsCaffeinate,
|
|
10527
|
-
getSchedule,
|
|
10528
|
-
createSchedule,
|
|
10529
|
-
updateSchedule,
|
|
10530
|
-
deleteSchedule,
|
|
10531
|
-
recordScheduleRun,
|
|
10532
10150
|
desktopHostPidPath,
|
|
10533
10151
|
claimDesktopHost,
|
|
10534
10152
|
releaseDesktopHost,
|