@cuongtran001/kanna 1.2.0 → 1.3.1
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/client/assets/{arc-BLk1CZKB.js → arc-DXtN3EWJ.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-B01ZQYte.js → architectureDiagram-3BPJPVTR-CIGqW1z-.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-diL6a3cq.js → blockDiagram-GPEHLZMM-BafNS_H6.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BY1verL8.js → c4Diagram-AAUBKEIU-YdAgRSis.js} +1 -1
- package/dist/client/assets/channel-BEYTrUAm.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-psdZuajw.js → chunk-2J33WTMH-eiP5y5G-.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-CrwQVBc5.js → chunk-4BX2VUAB-CvLGzPMF.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-9-aj4jKO.js → chunk-55IACEB6-Y-S9Fb8A.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-1FNK9_nB.js → chunk-727SXJPM-6sJH1RI9.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DFhvd_Ek.js → chunk-AQP2D5EJ-hV1r_IXO.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-B7MLrDa7.js → chunk-FMBD7UC4-CC3L28S5.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-D4Df05QE.js → chunk-ND2GUHAM-BZ3czhdH.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-Iq17Dznm.js → chunk-QZHKN3VN-Bjyd6Yr-.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CvnF5Ud6.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CvnF5Ud6.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-BmaZhtXy.js → cose-bilkent-S5V4N54A-CfxdDghE.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-BCmpfnfP.js → dagre-BM42HDAG-B8CddsbB.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BIEcKowS.js → diagram-2AECGRRQ-F0yS0fVB.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-CRBABBfv.js → diagram-5GNKFQAL-cW0i0qlh.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BRxUk16N.js → diagram-KO2AKTUF-BzAKMeJT.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DPBs4xl1.js → diagram-LMA3HP47-qdC4XqIl.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BE9rgVv8.js → diagram-OG6HWLK6-CGcpi6Dh.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-D3vgA1xJ.js → erDiagram-TEJ5UH35-CxNTDicM.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-Cgu-8XXC.js → flowDiagram-I6XJVG4X-qkGa5TqY.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CgjXVyTR.js → ganttDiagram-6RSMTGT7-D9mVPoQi.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-zD5D8B-i.js → gitGraphDiagram-PVQCEYII-DA0grAXe.js} +1 -1
- package/dist/client/assets/{index-DBTdhMbJ.js → index-BqUY1Bm4.js} +1 -1
- package/dist/client/assets/index-CLsOWXff.css +32 -0
- package/dist/client/assets/{index-zQLLeAfl.js → index-TU1k6ov6.js} +253 -243
- package/dist/client/assets/{infoDiagram-5YYISTIA-BaFHqT4u.js → infoDiagram-5YYISTIA-CGljtLs3.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-2yAC1br2.js → ishikawaDiagram-YF4QCWOH-CtC0xrmG.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DacQ-ND5.js → journeyDiagram-JHISSGLW-URLnVZeN.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-Qlbwm3z4.js → kanban-definition-UN3LZRKU-C2Q6aqQh.js} +1 -1
- package/dist/client/assets/{linear-DeafqpgO.js → linear-ByKHtsIx.js} +1 -1
- package/dist/client/assets/{mermaid.core-KYiCPJDj.js → mermaid.core-Dl_f2KLc.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-B1V-T6d3.js → mindmap-definition-RKZ34NQL-CaJ9IDLI.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DOF9OFRu.js → pieDiagram-4H26LBE5-mmYaf2Oa.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-lH1mB7ko.js → quadrantDiagram-W4KKPZXB-B_PO6OCC.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-BaTsJ_sS.js → requirementDiagram-4Y6WPE33-M4huwJt1.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Pfxib5iI.js → sankeyDiagram-5OEKKPKP-B0hb1sWh.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BQMEKkBC.js → sequenceDiagram-3UESZ5HK-BAqSptnA.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-CuldNnzp.js → stateDiagram-AJRCARHV-DTNkvPi5.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CVN3oGTF.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DP7u0YAg.js → timeline-definition-PNZ67QCA-MgAjHz8Q.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-QlrjpNeQ.js → vennDiagram-CIIHVFJN-DmKoO51W.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-BqdJ_sAM.js → wardley-L42UT6IY-CWcyHnYs.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Wi3kaQ5X.js → wardleyDiagram-YWT4CUSO-BGIGmFP9.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-D-KXMyCG.js → xychartDiagram-2RQKCTM6-D20YIvEl.js} +1 -1
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
- package/src/server/agent-coordinator-types.ts +158 -0
- package/src/server/agent-coordinator.ts +919 -0
- package/src/server/agent-deps-builders.ts +425 -0
- package/src/server/agent.oauth-rotation.test.ts +101 -0
- package/src/server/agent.test.ts +24 -8
- package/src/server/agent.ts +35 -4963
- package/src/server/auto-continue/read-model.test.ts +2 -2
- package/src/server/auto-continue/read-model.ts +4 -1
- package/src/server/claude-autocontinue-commands.test.ts +494 -0
- package/src/server/claude-autocontinue-commands.ts +256 -0
- package/src/server/claude-cancel-handler.test.ts +472 -0
- package/src/server/claude-cancel-handler.ts +241 -0
- package/src/server/claude-chat-management.test.ts +395 -0
- package/src/server/claude-chat-management.ts +251 -0
- package/src/server/claude-harness-stream.test.ts +273 -0
- package/src/server/claude-harness-stream.ts +158 -0
- package/src/server/claude-loop-orch-commands.test.ts +579 -0
- package/src/server/claude-loop-orch-commands.ts +466 -0
- package/src/server/claude-message-normalizer.test.ts +213 -0
- package/src/server/claude-message-normalizer.ts +436 -0
- package/src/server/claude-prompt-helpers.test.ts +248 -0
- package/src/server/claude-prompt-helpers.ts +139 -0
- package/src/server/claude-sdk-queue.test.ts +169 -0
- package/src/server/claude-sdk-queue.ts +82 -0
- package/src/server/claude-send-command.test.ts +414 -0
- package/src/server/claude-send-command.ts +420 -0
- package/src/server/claude-session-config-helpers.test.ts +279 -0
- package/src/server/claude-session-config-helpers.ts +151 -0
- package/src/server/claude-session-config.test.ts +250 -0
- package/src/server/claude-session-config.ts +159 -0
- package/src/server/claude-session-error-handler.test.ts +498 -0
- package/src/server/claude-session-error-handler.ts +361 -0
- package/src/server/claude-session-lifecycle.test.ts +669 -0
- package/src/server/claude-session-lifecycle.ts +283 -0
- package/src/server/claude-session-rebuild.test.ts +224 -0
- package/src/server/claude-session-rebuild.ts +101 -0
- package/src/server/claude-session-runner.test.ts +523 -0
- package/src/server/claude-session-runner.ts +521 -0
- package/src/server/claude-session-spawner.test.ts +401 -0
- package/src/server/claude-session-spawner.ts +401 -0
- package/src/server/claude-session-start.test.ts +205 -0
- package/src/server/claude-session-start.ts +277 -0
- package/src/server/claude-session-state-queries.test.ts +344 -0
- package/src/server/claude-session-state-queries.ts +160 -0
- package/src/server/claude-session-state.ts +104 -0
- package/src/server/claude-slash-commands.test.ts +277 -0
- package/src/server/claude-slash-commands.ts +234 -0
- package/src/server/claude-spawn-helpers.test.ts +221 -0
- package/src/server/claude-spawn-helpers.ts +179 -0
- package/src/server/claude-steer-log.test.ts +243 -0
- package/src/server/claude-steer-log.ts +58 -0
- package/src/server/claude-subagent-tool-response.test.ts +213 -0
- package/src/server/claude-subagent-tool-response.ts +165 -0
- package/src/server/claude-subagent-wiring.test.ts +263 -0
- package/src/server/claude-subagent-wiring.ts +324 -0
- package/src/server/claude-tool-respond.test.ts +321 -0
- package/src/server/claude-tool-respond.ts +142 -0
- package/src/server/claude-turn-runner.test.ts +310 -0
- package/src/server/claude-turn-runner.ts +228 -0
- package/src/server/claude-turn-starter.test.ts +266 -0
- package/src/server/claude-turn-starter.ts +566 -0
- package/src/server/claude-usage-math.test.ts +169 -0
- package/src/server/claude-usage-math.ts +132 -0
- package/src/server/diff-store-branch-ops.adapter.test.ts +332 -0
- package/src/server/diff-store-branch-ops.adapter.ts +602 -0
- package/src/server/diff-store-commit-ops.adapter.test.ts +358 -0
- package/src/server/diff-store-commit-ops.adapter.ts +258 -0
- package/src/server/diff-store-errors.ts +85 -0
- package/src/server/diff-store-file-ops.adapter.ts +212 -0
- package/src/server/diff-store-git-branch.adapter.ts +686 -0
- package/src/server/diff-store-io.adapter.ts +27 -0
- package/src/server/diff-store-parse.test.ts +212 -0
- package/src/server/diff-store-parse.ts +122 -0
- package/src/server/diff-store-state.ts +82 -0
- package/src/server/diff-store.ts +76 -1854
- package/src/server/event-store-apply.test.ts +280 -0
- package/src/server/event-store-apply.ts +132 -0
- package/src/server/event-store-chat-lifecycle.test.ts +408 -0
- package/src/server/event-store-chat-lifecycle.ts +441 -0
- package/src/server/event-store-entity-write.ts +356 -0
- package/src/server/event-store-helpers.test.ts +230 -0
- package/src/server/event-store-helpers.ts +235 -0
- package/src/server/event-store-init.ts +276 -0
- package/src/server/event-store-messages.adapter.test.ts +365 -0
- package/src/server/event-store-messages.adapter.ts +213 -0
- package/src/server/event-store-orch-subscription.ts +124 -0
- package/src/server/event-store-orch.test.ts +462 -0
- package/src/server/event-store-orch.ts +312 -0
- package/src/server/event-store-peripheral-events.adapter.test.ts +254 -0
- package/src/server/event-store-peripheral-events.adapter.ts +105 -0
- package/src/server/event-store-snapshot.test.ts +597 -0
- package/src/server/event-store-snapshot.ts +658 -0
- package/src/server/event-store-subagent.test.ts +408 -0
- package/src/server/event-store-subagent.ts +198 -0
- package/src/server/event-store-tool-requests.test.ts +210 -0
- package/src/server/event-store-tool-requests.ts +131 -0
- package/src/server/event-store-transcript-write.adapter.ts +285 -0
- package/src/server/event-store-write-ops.test.ts +554 -0
- package/src/server/event-store-write-ops.ts +529 -0
- package/src/server/event-store.test.ts +35 -0
- package/src/server/event-store.ts +251 -2284
- package/src/server/events.ts +3 -0
- package/src/server/harness-types.ts +15 -1
- package/src/server/oauth-errors.ts +19 -0
- package/src/server/read-models.ts +26 -1
- package/src/server/subagent-orchestrator.ts +3 -0
- package/src/server/ws-router-agent-ctrl.test.ts +187 -0
- package/src/server/ws-router-agent-ctrl.ts +137 -0
- package/src/server/ws-router-broadcast.ts +488 -0
- package/src/server/ws-router-chat.test.ts +461 -0
- package/src/server/ws-router-chat.ts +279 -0
- package/src/server/ws-router-defaults.test.ts +283 -0
- package/src/server/ws-router-defaults.ts +434 -0
- package/src/server/ws-router-diff.test.ts +167 -0
- package/src/server/ws-router-diff.ts +250 -0
- package/src/server/ws-router-envelope.ts +329 -0
- package/src/server/ws-router-misc.test.ts +422 -0
- package/src/server/ws-router-misc.ts +265 -0
- package/src/server/ws-router-orch.test.ts +190 -0
- package/src/server/ws-router-orch.ts +93 -0
- package/src/server/ws-router-project.test.ts +403 -0
- package/src/server/ws-router-project.ts +256 -0
- package/src/server/ws-router-push.test.ts +193 -0
- package/src/server/ws-router-push.ts +120 -0
- package/src/server/ws-router-settings.test.ts +173 -0
- package/src/server/ws-router-settings.ts +416 -0
- package/src/server/ws-router-skills.test.ts +194 -0
- package/src/server/ws-router-skills.ts +204 -0
- package/src/server/ws-router-utils.ts +224 -0
- package/src/server/ws-router.ts +339 -2254
- package/src/shared/app-settings-types.ts +365 -0
- package/src/shared/core-types.ts +27 -0
- package/src/shared/git-diff-types.ts +165 -0
- package/src/shared/loop-progress.test.ts +106 -0
- package/src/shared/loop-progress.ts +88 -0
- package/src/shared/mcp-types.ts +105 -0
- package/src/shared/provider-model-types.ts +437 -0
- package/src/shared/subagent-types.ts +198 -0
- package/src/shared/tool-call-types.ts +314 -0
- package/src/shared/transcript-types.ts +270 -0
- package/src/shared/types.ts +27 -1668
- package/dist/client/assets/channel-BMkhjiLI.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-C5Kg1XOD.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C5Kg1XOD.js +0 -1
- package/dist/client/assets/index-H6C-f2Vp.css +0 -32
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Ca2U11af.js +0 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone auto-continue command handlers for AgentCoordinator.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from agent.ts so the eight related private/public methods live in
|
|
5
|
+
* their own testable module. The coordinator delegates to these functions by
|
|
6
|
+
* passing an object literal that satisfies `AutoContinueCommandDeps`.
|
|
7
|
+
*
|
|
8
|
+
* Side-effect seal: this module contains NO direct IO (no node:fs, no HTTP
|
|
9
|
+
* calls, no Bun primitives). Every effectful operation is injected through
|
|
10
|
+
* the deps interface.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ChatAttachment, QueuedChatMessage, TranscriptEntry } from "../shared/types"
|
|
14
|
+
import { AUTO_CONTINUE_EVENT_VERSION, type AutoContinueEvent } from "./auto-continue/events"
|
|
15
|
+
import { deriveChatSchedules } from "./auto-continue/read-model"
|
|
16
|
+
import type { SendMessageOptions } from "./claude-steer-log"
|
|
17
|
+
import { timestamped } from "./claude-message-normalizer"
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Structural sub-interfaces — only the operations this module calls.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/** Minimal schedule-manager surface used by emitAutoContinueEvent. */
|
|
24
|
+
interface AutoContinueScheduleManager {
|
|
25
|
+
onEvent(event: AutoContinueEvent): void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Subset of EventStore used by these handlers. */
|
|
29
|
+
interface AutoContinueCommandStore {
|
|
30
|
+
appendAutoContinueEvent(event: AutoContinueEvent): Promise<void>
|
|
31
|
+
getAutoContinueEvents(chatId: string): AutoContinueEvent[]
|
|
32
|
+
/** Returns null/undefined when the chat does not exist. */
|
|
33
|
+
getChat(chatId: string): { id: string } | null | undefined
|
|
34
|
+
appendMessage(chatId: string, entry: TranscriptEntry): Promise<void>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Dependency bundle injected by AgentCoordinator
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
export interface AutoContinueCommandDeps {
|
|
42
|
+
/**
|
|
43
|
+
* Per-chat auto-resume override. A `boolean` value in the map takes
|
|
44
|
+
* precedence over the global preference; absence falls back to
|
|
45
|
+
* `getAutoResumePreference()`.
|
|
46
|
+
*/
|
|
47
|
+
autoResumeByChat: Pick<Map<string, boolean>, "get">
|
|
48
|
+
|
|
49
|
+
/** Returns the global auto-resume preference when no per-chat override exists. */
|
|
50
|
+
getAutoResumePreference(): boolean
|
|
51
|
+
|
|
52
|
+
/** EventStore — subset used by these handlers. */
|
|
53
|
+
store: AutoContinueCommandStore
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Optional schedule manager that must be notified after every event so it
|
|
57
|
+
* can arm/disarm real timers. Null when no manager is configured.
|
|
58
|
+
*/
|
|
59
|
+
scheduleManager: AutoContinueScheduleManager | null
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Emit a state-change event for the given chat. Propagated to WebSocket
|
|
63
|
+
* subscribers so the UI can refresh.
|
|
64
|
+
*/
|
|
65
|
+
emitStateChange(chatId: string): void
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Enqueue a prompt as if the user sent it. Used by `fireAutoContinue` to
|
|
69
|
+
* replay the schedule's stored prompt.
|
|
70
|
+
*/
|
|
71
|
+
enqueueMessage(
|
|
72
|
+
chatId: string,
|
|
73
|
+
content: string,
|
|
74
|
+
attachments: ChatAttachment[],
|
|
75
|
+
options?: SendMessageOptions,
|
|
76
|
+
): Promise<QueuedChatMessage>
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Start the next queued message for the chat if there is no active turn.
|
|
80
|
+
* Returns `true` when a message was dequeued and started.
|
|
81
|
+
*/
|
|
82
|
+
maybeStartNextQueuedMessage(chatId: string): Promise<boolean>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Exported standalone functions
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Return the auto-resume preference for a specific chat.
|
|
91
|
+
* Per-chat overrides (set when the chat was created / the send command was
|
|
92
|
+
* issued) take precedence over the global preference.
|
|
93
|
+
*/
|
|
94
|
+
export function resolveAutoResumeFor(deps: AutoContinueCommandDeps, chatId: string): boolean {
|
|
95
|
+
const cached = deps.autoResumeByChat.get(chatId)
|
|
96
|
+
if (typeof cached === "boolean") return cached
|
|
97
|
+
return deps.getAutoResumePreference()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Append an auto-continue event to the store, notify the schedule manager so
|
|
102
|
+
* it can arm/disarm timers, and emit a state-change event.
|
|
103
|
+
*/
|
|
104
|
+
export async function emitAutoContinueEvent(
|
|
105
|
+
deps: AutoContinueCommandDeps,
|
|
106
|
+
event: AutoContinueEvent,
|
|
107
|
+
): Promise<void> {
|
|
108
|
+
await deps.store.appendAutoContinueEvent(event)
|
|
109
|
+
deps.scheduleManager?.onEvent(event)
|
|
110
|
+
deps.emitStateChange(event.chatId)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Derive the live schedule entry for a given `scheduleId` within a chat.
|
|
115
|
+
* Returns `undefined` when the schedule does not exist.
|
|
116
|
+
*/
|
|
117
|
+
export function getChatSchedule(
|
|
118
|
+
deps: AutoContinueCommandDeps,
|
|
119
|
+
chatId: string,
|
|
120
|
+
scheduleId: string,
|
|
121
|
+
) {
|
|
122
|
+
const events = deps.store.getAutoContinueEvents(chatId)
|
|
123
|
+
return deriveChatSchedules(events, chatId).schedules[scheduleId]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Guard: throws when `scheduledAt` is not strictly in the future.
|
|
128
|
+
* All acceptance / reschedule paths call this before persisting the event.
|
|
129
|
+
*/
|
|
130
|
+
export function requireFuture(scheduledAt: number): void {
|
|
131
|
+
if (scheduledAt <= Date.now()) throw new Error("scheduledAt must be in the future")
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Fire a scheduled auto-continue: replay the stored prompt and start the
|
|
136
|
+
* next queued message. If any step fails, a synthetic error result is
|
|
137
|
+
* appended to the transcript so the failure is visible in the UI.
|
|
138
|
+
*/
|
|
139
|
+
export async function fireAutoContinue(
|
|
140
|
+
deps: AutoContinueCommandDeps,
|
|
141
|
+
chatId: string,
|
|
142
|
+
scheduleId: string,
|
|
143
|
+
): Promise<void> {
|
|
144
|
+
if (!deps.store.getChat(chatId)) return
|
|
145
|
+
|
|
146
|
+
// `subagent_background` deliveries carry the "Read PROGRESS.md" prompt;
|
|
147
|
+
// provider-failure schedules carry none and fall back to the literal "continue".
|
|
148
|
+
const schedule = getChatSchedule(deps, chatId, scheduleId)
|
|
149
|
+
const promptToReplay = schedule?.prompt ?? "continue"
|
|
150
|
+
|
|
151
|
+
const event: AutoContinueEvent = {
|
|
152
|
+
v: AUTO_CONTINUE_EVENT_VERSION,
|
|
153
|
+
kind: "auto_continue_fired",
|
|
154
|
+
timestamp: Date.now(),
|
|
155
|
+
chatId,
|
|
156
|
+
scheduleId,
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
await deps.store.appendAutoContinueEvent(event)
|
|
160
|
+
await deps.enqueueMessage(chatId, promptToReplay, [], { autoContinue: { scheduleId } })
|
|
161
|
+
await deps.maybeStartNextQueuedMessage(chatId)
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
164
|
+
await deps.store.appendMessage(
|
|
165
|
+
chatId,
|
|
166
|
+
timestamped({
|
|
167
|
+
kind: "result",
|
|
168
|
+
subtype: "error",
|
|
169
|
+
isError: true,
|
|
170
|
+
durationMs: 0,
|
|
171
|
+
result: `Auto-continue failed: ${message}`,
|
|
172
|
+
}),
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
deps.emitStateChange(chatId)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Accept a proposed auto-continue schedule (user or pool-rotation acceptance).
|
|
181
|
+
* Validates that the schedule exists, is still in the `proposed` state, and
|
|
182
|
+
* that `scheduledAt` is in the future before persisting the acceptance event.
|
|
183
|
+
*/
|
|
184
|
+
export async function acceptAutoContinue(
|
|
185
|
+
deps: AutoContinueCommandDeps,
|
|
186
|
+
chatId: string,
|
|
187
|
+
scheduleId: string,
|
|
188
|
+
scheduledAt: number,
|
|
189
|
+
): Promise<void> {
|
|
190
|
+
const schedule = getChatSchedule(deps, chatId, scheduleId)
|
|
191
|
+
if (!schedule) throw new Error("Schedule not found")
|
|
192
|
+
if (schedule.state !== "proposed") throw new Error("Schedule not pending")
|
|
193
|
+
requireFuture(scheduledAt)
|
|
194
|
+
|
|
195
|
+
await emitAutoContinueEvent(deps, {
|
|
196
|
+
v: AUTO_CONTINUE_EVENT_VERSION,
|
|
197
|
+
kind: "auto_continue_accepted",
|
|
198
|
+
timestamp: Date.now(),
|
|
199
|
+
chatId,
|
|
200
|
+
scheduleId,
|
|
201
|
+
scheduledAt,
|
|
202
|
+
tz: schedule.tz,
|
|
203
|
+
source: "user",
|
|
204
|
+
resetAt: schedule.resetAt,
|
|
205
|
+
detectedAt: schedule.detectedAt,
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Reschedule an active (`scheduled`) auto-continue to a new time.
|
|
211
|
+
* Throws when the schedule does not exist or is not in the `scheduled` state.
|
|
212
|
+
*/
|
|
213
|
+
export async function rescheduleAutoContinue(
|
|
214
|
+
deps: AutoContinueCommandDeps,
|
|
215
|
+
chatId: string,
|
|
216
|
+
scheduleId: string,
|
|
217
|
+
scheduledAt: number,
|
|
218
|
+
): Promise<void> {
|
|
219
|
+
const schedule = getChatSchedule(deps, chatId, scheduleId)
|
|
220
|
+
if (!schedule || schedule.state !== "scheduled") throw new Error("Schedule not active")
|
|
221
|
+
requireFuture(scheduledAt)
|
|
222
|
+
|
|
223
|
+
await emitAutoContinueEvent(deps, {
|
|
224
|
+
v: AUTO_CONTINUE_EVENT_VERSION,
|
|
225
|
+
kind: "auto_continue_rescheduled",
|
|
226
|
+
timestamp: Date.now(),
|
|
227
|
+
chatId,
|
|
228
|
+
scheduleId,
|
|
229
|
+
scheduledAt,
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Cancel a proposed or scheduled auto-continue.
|
|
235
|
+
* No-ops silently when the schedule does not exist or is already in a terminal
|
|
236
|
+
* state (`fired` / `cancelled`).
|
|
237
|
+
*/
|
|
238
|
+
export async function cancelAutoContinue(
|
|
239
|
+
deps: AutoContinueCommandDeps,
|
|
240
|
+
chatId: string,
|
|
241
|
+
scheduleId: string,
|
|
242
|
+
reason: "user" | "chat_deleted",
|
|
243
|
+
): Promise<void> {
|
|
244
|
+
const schedule = getChatSchedule(deps, chatId, scheduleId)
|
|
245
|
+
if (!schedule) return
|
|
246
|
+
if (schedule.state !== "proposed" && schedule.state !== "scheduled") return
|
|
247
|
+
|
|
248
|
+
await emitAutoContinueEvent(deps, {
|
|
249
|
+
v: AUTO_CONTINUE_EVENT_VERSION,
|
|
250
|
+
kind: "auto_continue_cancelled",
|
|
251
|
+
timestamp: Date.now(),
|
|
252
|
+
chatId,
|
|
253
|
+
scheduleId,
|
|
254
|
+
reason,
|
|
255
|
+
})
|
|
256
|
+
}
|