@telora/daemon 0.22.87 → 0.22.97
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/build-info.json +6 -3
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/resolve.d.ts +37 -8
- package/dist/backends/resolve.d.ts.map +1 -1
- package/dist/backends/resolve.js +62 -28
- package/dist/backends/resolve.js.map +1 -1
- package/dist/cli/connect/config-write.d.ts +7 -4
- package/dist/cli/connect/config-write.d.ts.map +1 -1
- package/dist/cli/connect/config-write.js +13 -7
- package/dist/cli/connect/config-write.js.map +1 -1
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +11 -1
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/update-commands.d.ts.map +1 -1
- package/dist/cli/update-commands.js +2 -1
- package/dist/cli/update-commands.js.map +1 -1
- package/dist/completion/event-phases.js +5 -5
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts +7 -0
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +2 -1
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/delivery/external-hold.js +1 -1
- package/dist/delivery/external-hold.js.map +1 -1
- package/dist/delivery/operator-hold.d.ts +14 -0
- package/dist/delivery/operator-hold.d.ts.map +1 -1
- package/dist/delivery/operator-hold.js +31 -1
- package/dist/delivery/operator-hold.js.map +1 -1
- package/dist/directive/directive-dispatch.js +2 -2
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +2 -1
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/directive/directive-verify-hold-gate.d.ts +32 -8
- package/dist/directive/directive-verify-hold-gate.d.ts.map +1 -1
- package/dist/directive/directive-verify-hold-gate.js +20 -21
- package/dist/directive/directive-verify-hold-gate.js.map +1 -1
- package/dist/drift/staleness-sensor.d.ts +6 -0
- package/dist/drift/staleness-sensor.d.ts.map +1 -1
- package/dist/drift/staleness-sensor.js +24 -20
- package/dist/drift/staleness-sensor.js.map +1 -1
- package/dist/drift/staleness.d.ts +18 -5
- package/dist/drift/staleness.d.ts.map +1 -1
- package/dist/drift/staleness.js +28 -15
- package/dist/drift/staleness.js.map +1 -1
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +6 -9
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/focus-executor.js +2 -2
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts +31 -0
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +44 -22
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +4 -0
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/team-actionable-work.d.ts +76 -20
- package/dist/focus/team-actionable-work.d.ts.map +1 -1
- package/dist/focus/team-actionable-work.js +85 -20
- package/dist/focus/team-actionable-work.js.map +1 -1
- package/dist/nexus/incoming.js +1 -1
- package/dist/nexus/incoming.js.map +1 -1
- package/dist/nexus/pending-returns.d.ts +124 -0
- package/dist/nexus/pending-returns.d.ts.map +1 -0
- package/dist/nexus/pending-returns.js +194 -0
- package/dist/nexus/pending-returns.js.map +1 -0
- package/dist/nexus/return-routing.d.ts +89 -0
- package/dist/nexus/return-routing.d.ts.map +1 -0
- package/dist/nexus/return-routing.js +148 -0
- package/dist/nexus/return-routing.js.map +1 -0
- package/dist/nexus/return.d.ts +66 -89
- package/dist/nexus/return.d.ts.map +1 -1
- package/dist/nexus/return.js +116 -279
- package/dist/nexus/return.js.map +1 -1
- package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
- package/dist/prompt/focus-prompt-builder.js +1 -0
- package/dist/prompt/focus-prompt-builder.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +23 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +31 -4
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/focus-discovery.d.ts +7 -1
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +9 -3
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/requests.d.ts +51 -3
- package/dist/queries/requests.d.ts.map +1 -1
- package/dist/queries/requests.js +63 -10
- package/dist/queries/requests.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/verification.d.ts.map +1 -1
- package/dist/queries/verification.js +1 -0
- package/dist/queries/verification.js.map +1 -1
- package/dist/shell/heartbeat-metadata.d.ts +18 -0
- package/dist/shell/heartbeat-metadata.d.ts.map +1 -1
- package/dist/shell/heartbeat-metadata.js +24 -0
- package/dist/shell/heartbeat-metadata.js.map +1 -1
- package/dist/shell/heartbeat.d.ts.map +1 -1
- package/dist/shell/heartbeat.js +6 -17
- package/dist/shell/heartbeat.js.map +1 -1
- package/dist/shell/model-resolution.d.ts +9 -4
- package/dist/shell/model-resolution.d.ts.map +1 -1
- package/dist/shell/model-resolution.js +46 -7
- package/dist/shell/model-resolution.js.map +1 -1
- package/dist/shell/unified-init.d.ts +24 -0
- package/dist/shell/unified-init.d.ts.map +1 -1
- package/dist/shell/unified-init.js +22 -17
- package/dist/shell/unified-init.js.map +1 -1
- package/dist/spawn/model-id-guards.d.ts +50 -0
- package/dist/spawn/model-id-guards.d.ts.map +1 -0
- package/dist/spawn/model-id-guards.js +110 -0
- package/dist/spawn/model-id-guards.js.map +1 -0
- package/dist/spawn/model-routing.d.ts +1 -43
- package/dist/spawn/model-routing.d.ts.map +1 -1
- package/dist/spawn/model-routing.js +3 -94
- package/dist/spawn/model-routing.js.map +1 -1
- package/dist/spawn/prompt-assembly.js +1 -1
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/respawn-cycle-escalation.d.ts.map +1 -1
- package/dist/spawn/respawn-cycle-escalation.js +11 -3
- package/dist/spawn/respawn-cycle-escalation.js.map +1 -1
- package/dist/spawn/review-hold-park.d.ts +31 -0
- package/dist/spawn/review-hold-park.d.ts.map +1 -0
- package/dist/spawn/review-hold-park.js +120 -0
- package/dist/spawn/review-hold-park.js.map +1 -0
- package/dist/spawn/shared.d.ts +1 -1
- package/dist/spawn/shared.d.ts.map +1 -1
- package/dist/spawn/spawn-cooldown.d.ts +27 -4
- package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
- package/dist/spawn/spawn-cooldown.js +88 -3
- package/dist/spawn/spawn-cooldown.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts +1 -0
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +7 -0
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/spawn/worktree-session.d.ts +4 -0
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +19 -15
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/update/auto-update-idle.d.ts.map +1 -1
- package/dist/update/auto-update-idle.js +2 -1
- package/dist/update/auto-update-idle.js.map +1 -1
- package/dist/update/auto-update.d.ts +20 -3
- package/dist/update/auto-update.d.ts.map +1 -1
- package/dist/update/auto-update.js +8 -24
- package/dist/update/auto-update.js.map +1 -1
- package/dist/update/self-update.d.ts +43 -4
- package/dist/update/self-update.d.ts.map +1 -1
- package/dist/update/self-update.js +61 -38
- package/dist/update/self-update.js.map +1 -1
- package/dist/update/version-check.d.ts +29 -45
- package/dist/update/version-check.d.ts.map +1 -1
- package/dist/update/version-check.js +48 -79
- package/dist/update/version-check.js.map +1 -1
- package/dist/verify/failure-signature.d.ts.map +1 -1
- package/dist/verify/failure-signature.js +1 -0
- package/dist/verify/failure-signature.js.map +1 -1
- package/dist/verify/verification-checkout.d.ts +58 -0
- package/dist/verify/verification-checkout.d.ts.map +1 -0
- package/dist/verify/verification-checkout.js +266 -0
- package/dist/verify/verification-checkout.js.map +1 -0
- package/dist/verify/verification-default-on.d.ts +27 -3
- package/dist/verify/verification-default-on.d.ts.map +1 -1
- package/dist/verify/verification-default-on.js +98 -5
- package/dist/verify/verification-default-on.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +11 -0
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.d.ts +22 -1
- package/dist/verify/verification-deterministic.d.ts.map +1 -1
- package/dist/verify/verification-deterministic.js +6 -7
- package/dist/verify/verification-deterministic.js.map +1 -1
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +10 -8
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verification-feedback.d.ts +3 -0
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +5 -2
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/worktree/verify-interlock.d.ts +9 -1
- package/dist/worktree/verify-interlock.d.ts.map +1 -1
- package/dist/worktree/verify-interlock.js +40 -3
- package/dist/worktree/verify-interlock.js.map +1 -1
- package/package.json +3 -3
|
@@ -14,17 +14,42 @@ export interface FocusHoldDeps {
|
|
|
14
14
|
/**
|
|
15
15
|
* Whether the focus's worktree is currently held by an in-flight verify command.
|
|
16
16
|
*
|
|
17
|
-
* The daemon runs a product's configured verify command
|
|
18
|
-
*
|
|
17
|
+
* The daemon runs a product's configured verify command for a delivery of this
|
|
18
|
+
* focus and commits from the focus worktree; the verify interlock
|
|
19
19
|
* (worktree/verify-interlock.ts) serialises the two. While the hold is held the
|
|
20
20
|
* daemon defers the coding->verify advance (delivery/delivery-advance-block.ts)
|
|
21
|
-
* rather than snapshot a mid-verify tree
|
|
22
|
-
* nothing a freshly-spawned coding team could commit or advance.
|
|
21
|
+
* rather than snapshot a mid-verify tree.
|
|
23
22
|
*
|
|
24
23
|
* A focus with no registered worktree is not held: no verify can run without a
|
|
25
24
|
* worktree to run it in.
|
|
26
25
|
*/
|
|
27
26
|
export declare function focusUnderVerifyHold(focusId: string, deps?: FocusHoldDeps): boolean;
|
|
27
|
+
/** The delivery slice the outside-hold work fact reads (structural). */
|
|
28
|
+
export interface HoldWorkDelivery {
|
|
29
|
+
id: string;
|
|
30
|
+
executionStatus?: string | null;
|
|
31
|
+
}
|
|
32
|
+
/** The issue slice the outside-hold work fact reads (structural). */
|
|
33
|
+
export interface HoldWorkIssue {
|
|
34
|
+
deliveryId: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Whether a delivery OUTSIDE the verified set carries open work a coding team
|
|
39
|
+
* could act on: an agent-actionable delivery (queued / coding / verify_failed)
|
|
40
|
+
* that is not being judged by an in-flight verify, holding an open issue. The
|
|
41
|
+
* same "open issue on an agent-actionable delivery" fact the team-exit reads
|
|
42
|
+
* (computeCompletionFacts postHasActionableOpen), minus the held deliveries.
|
|
43
|
+
*
|
|
44
|
+
* A coding delivery whose advance the hold defers has every issue terminal (that
|
|
45
|
+
* is why it is advancing), so it contributes nothing -- the 2026-09-06 storm
|
|
46
|
+
* shape stays "no actionable work".
|
|
47
|
+
*/
|
|
48
|
+
export declare function hasTeamWorkOutsideVerify(input: {
|
|
49
|
+
deliveries: readonly HoldWorkDelivery[];
|
|
50
|
+
issues: readonly HoldWorkIssue[];
|
|
51
|
+
heldDeliveryIds: ReadonlySet<string>;
|
|
52
|
+
}): boolean;
|
|
28
53
|
/** Facts the actionable-work question is decided from. */
|
|
29
54
|
export interface TeamActionableWorkInput {
|
|
30
55
|
/**
|
|
@@ -36,12 +61,18 @@ export interface TeamActionableWorkInput {
|
|
|
36
61
|
*/
|
|
37
62
|
hasUnheldActionableWork: boolean;
|
|
38
63
|
/**
|
|
39
|
-
* Whether a verify command is currently running
|
|
64
|
+
* Whether a verify command is currently running for a delivery of this focus
|
|
40
65
|
* (focusUnderVerifyHold). While held, the daemon is deferring this focus's
|
|
41
|
-
* advance
|
|
42
|
-
* would run one turn and terminate.
|
|
66
|
+
* advance.
|
|
43
67
|
*/
|
|
44
68
|
underVerifyHold: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Under a hold: whether a delivery OUTSIDE the verified set still carries open
|
|
71
|
+
* work ({@link hasTeamWorkOutsideVerify}). Absent reads as false -- a caller
|
|
72
|
+
* that cannot see sibling work keeps the storm-safe "held = no work" verdict.
|
|
73
|
+
* Ignored when there is no hold.
|
|
74
|
+
*/
|
|
75
|
+
workOutsideVerifyHold?: boolean;
|
|
45
76
|
/**
|
|
46
77
|
* Whether the daemon has sent THIS team a merge-conflict resolution request it
|
|
47
78
|
* has not yet answered (teamState.resolvingMergeConflict, set in
|
|
@@ -58,23 +89,30 @@ export interface TeamActionableWorkInput {
|
|
|
58
89
|
* The one predicate. An outstanding merge-conflict resolution request the daemon
|
|
59
90
|
* sent this team IS actionable work regardless of delivery state -- it takes
|
|
60
91
|
* precedence so a team finishing its last delivery is never torn down mid-merge.
|
|
61
|
-
* Otherwise a
|
|
62
|
-
*
|
|
63
|
-
* actionable-work fact stands. Pure, so
|
|
64
|
-
*
|
|
92
|
+
* Otherwise, under a verify hold the focus is actionable only when work exists
|
|
93
|
+
* OUTSIDE the delivery being verified (never more than the caller's own fact);
|
|
94
|
+
* with no hold, the caller's own actionable-work fact stands. Pure, so every
|
|
95
|
+
* controller reads the identical answer for a given state.
|
|
65
96
|
*/
|
|
66
97
|
export declare function focusHasTeamActionableWork(input: TeamActionableWorkInput): boolean;
|
|
67
98
|
/**
|
|
68
99
|
* Resolve the verify hold for a focus whose worktree path is already known, and
|
|
69
100
|
* fold it into the shared predicate in one step. Convenience for the team-exit
|
|
70
101
|
* fact-gathering (computeCompletionFacts), which has already resolved the
|
|
71
|
-
* worktree path; a null path means no
|
|
72
|
-
* dep is passed in so the caller
|
|
102
|
+
* worktree path and fetched the focus's deliveries + issues; a null path means no
|
|
103
|
+
* worktree -> no hold. The isWorktreeUnderVerify dep is passed in so the caller
|
|
104
|
+
* keeps its own injection seam.
|
|
73
105
|
*/
|
|
74
106
|
export declare function resolveTeamActionableWork(args: {
|
|
75
107
|
focusWorktreePath: string | null;
|
|
76
108
|
hasUnheldActionableWork: boolean;
|
|
77
109
|
isWorktreeUnderVerify: (worktreePath: string) => boolean;
|
|
110
|
+
/** The focus's deliveries + issues, read under a hold to find work outside the verified set. */
|
|
111
|
+
outsideHold?: {
|
|
112
|
+
deliveries: readonly HoldWorkDelivery[];
|
|
113
|
+
issues: readonly HoldWorkIssue[];
|
|
114
|
+
verifyHeldDeliveryIds?: (worktreePath: string) => ReadonlySet<string>;
|
|
115
|
+
};
|
|
78
116
|
/** See TeamActionableWorkInput.mergeResolutionOutstanding. Optional; defaults
|
|
79
117
|
* to false so callers that do not track it are unaffected. */
|
|
80
118
|
mergeResolutionOutstanding?: boolean;
|
|
@@ -82,6 +120,25 @@ export declare function resolveTeamActionableWork(args: {
|
|
|
82
120
|
underVerifyHold: boolean;
|
|
83
121
|
teamHasActionableWork: boolean;
|
|
84
122
|
};
|
|
123
|
+
/** The hold facts a spawn-producing controller feeds the shared predicate. */
|
|
124
|
+
export interface VerifyHoldFacts {
|
|
125
|
+
underVerifyHold: boolean;
|
|
126
|
+
workOutsideVerifyHold: boolean;
|
|
127
|
+
}
|
|
128
|
+
/** Injectable seam for {@link resolveFocusVerifyHoldFacts}. */
|
|
129
|
+
export interface FocusHoldWorkDeps extends FocusHoldDeps {
|
|
130
|
+
verifyHeldDeliveryIds?: (worktreePath: string) => ReadonlySet<string>;
|
|
131
|
+
getFocusDeliveries?: (focusId: string) => Promise<readonly HoldWorkDelivery[]>;
|
|
132
|
+
getFocusIssues?: (focusId: string) => Promise<readonly HoldWorkIssue[]>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve the hold facts for a focus the caller knows only by id (the spawn gate,
|
|
136
|
+
* the pending-spawn pass, the directive executor). Reads deliveries + issues ONLY
|
|
137
|
+
* when the focus is held -- an unheld focus costs no fetch. A failed read fails
|
|
138
|
+
* CLOSED to "no work outside the hold": the storm-safe verdict (defer the spawn,
|
|
139
|
+
* re-read next poll), never a spawn into a focus whose work could not be seen.
|
|
140
|
+
*/
|
|
141
|
+
export declare function resolveFocusVerifyHoldFacts(focusId: string, deps?: FocusHoldWorkDeps): Promise<VerifyHoldFacts>;
|
|
85
142
|
/** Injectable seam for {@link anyFocusUnderVerifyHold}. */
|
|
86
143
|
export interface AnyFocusHoldDeps {
|
|
87
144
|
getAllFocusWorktrees?: () => ReadonlyMap<string, {
|
|
@@ -95,13 +152,12 @@ export interface AnyFocusHoldDeps {
|
|
|
95
152
|
* (focus-worktree-state + verify-interlock), so the drain/idle gate agrees with
|
|
96
153
|
* the spawn gate and the team-exit classifier about "is a verify in flight".
|
|
97
154
|
*
|
|
98
|
-
* The auto-updater consumes this: a verify runs as a spawned child
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* incidental fact that a held focus happens to stay in the ready set.
|
|
155
|
+
* The auto-updater consumes this: a verify runs as a spawned child (verification-
|
|
156
|
+
* deterministic.ts) that can last up to ~30 min, and during that hold there is
|
|
157
|
+
* often NO active team. Restarting the daemon then would kill the verify
|
|
158
|
+
* mid-run, so an in-flight hold must read as "not idle" REGARDLESS of team count,
|
|
159
|
+
* queue depth, or which delivery it judges -- robustly, not by the incidental
|
|
160
|
+
* fact that a held focus happens to stay in the ready set.
|
|
105
161
|
*/
|
|
106
162
|
export declare function anyFocusUnderVerifyHold(deps?: AnyFocusHoldDeps): boolean;
|
|
107
163
|
//# sourceMappingURL=team-actionable-work.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-actionable-work.d.ts","sourceRoot":"","sources":["../../src/focus/team-actionable-work.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"team-actionable-work.d.ts","sourceRoot":"","sources":["../../src/focus/team-actionable-work.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* The single definition of "is there team-actionable work for this focus right
|
|
8
8
|
* now?", read by every controller that can spawn, hold, or exit a team so they
|
|
9
9
|
* cannot disagree about the same focus state:
|
|
10
|
-
* - the spawn gate (focus/listener-spawn.ts, decideFocusSpawn
|
|
10
|
+
* - the spawn gate (focus/listener-spawn.ts, decideFocusSpawn +
|
|
11
|
+
* processPendingSpawnFocuses)
|
|
11
12
|
* - the team-exit decision (completion/event-phases.ts, computeCompletionFacts)
|
|
12
13
|
* - the directive executor's spawn-producing paths
|
|
13
14
|
* (directive/directive-verify-hold-gate.ts, consumed
|
|
@@ -35,19 +36,34 @@
|
|
|
35
36
|
* reported ready in the first place: no spawn, no no-op cycle to bound, nothing
|
|
36
37
|
* billed.
|
|
37
38
|
*
|
|
39
|
+
* Why the hold is DELIVERY-scoped: the hold is keyed on the focus worktree, which
|
|
40
|
+
* every delivery of the focus shares, but "held = nothing to do" is only true of
|
|
41
|
+
* the delivery the verify is JUDGING (and a delivery whose advance it defers,
|
|
42
|
+
* which has no open work by construction). Reading the worktree hold as "the
|
|
43
|
+
* whole focus has nothing to do" starved a sibling delivery holding an open Bug
|
|
44
|
+
* -- the very defect failing every verify -- so the team that would fix the red
|
|
45
|
+
* was torn down and never respawned (livelock, f1 2026-09-13). So under a hold a
|
|
46
|
+
* focus is actionable iff a delivery OUTSIDE the verified set still carries open
|
|
47
|
+
* work ({@link hasTeamWorkOutsideVerify}); the storm shape (the verified delivery
|
|
48
|
+
* is the only non-terminal work) still reads as no actionable work.
|
|
49
|
+
*
|
|
38
50
|
* @module focus/team-actionable-work
|
|
39
51
|
*/
|
|
40
52
|
import { getFocusWorktree, getAllFocusWorktrees } from './focus-worktree-state.js';
|
|
41
|
-
import { isWorktreeUnderVerify } from '../worktree/verify-interlock.js';
|
|
53
|
+
import { isWorktreeUnderVerify, verifyHeldDeliveryIds } from '../worktree/verify-interlock.js';
|
|
54
|
+
import { getFocusDeliveries, getFocusIssues } from '../queries/focuses.js';
|
|
55
|
+
import { isStatusAgentActionable } from '../workflow/stage-classifier.js';
|
|
56
|
+
import { OPEN_ISSUE_STATUSES } from '../shell/constants.js';
|
|
57
|
+
import { createLogger } from '../shell/log.js';
|
|
58
|
+
const log = createLogger({ module: 'focus' });
|
|
42
59
|
/**
|
|
43
60
|
* Whether the focus's worktree is currently held by an in-flight verify command.
|
|
44
61
|
*
|
|
45
|
-
* The daemon runs a product's configured verify command
|
|
46
|
-
*
|
|
62
|
+
* The daemon runs a product's configured verify command for a delivery of this
|
|
63
|
+
* focus and commits from the focus worktree; the verify interlock
|
|
47
64
|
* (worktree/verify-interlock.ts) serialises the two. While the hold is held the
|
|
48
65
|
* daemon defers the coding->verify advance (delivery/delivery-advance-block.ts)
|
|
49
|
-
* rather than snapshot a mid-verify tree
|
|
50
|
-
* nothing a freshly-spawned coding team could commit or advance.
|
|
66
|
+
* rather than snapshot a mid-verify tree.
|
|
51
67
|
*
|
|
52
68
|
* A focus with no registered worktree is not held: no verify can run without a
|
|
53
69
|
* worktree to run it in.
|
|
@@ -60,53 +76,102 @@ export function focusUnderVerifyHold(focusId, deps = {}) {
|
|
|
60
76
|
return false;
|
|
61
77
|
return underVerify(worktreePath);
|
|
62
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Whether a delivery OUTSIDE the verified set carries open work a coding team
|
|
81
|
+
* could act on: an agent-actionable delivery (queued / coding / verify_failed)
|
|
82
|
+
* that is not being judged by an in-flight verify, holding an open issue. The
|
|
83
|
+
* same "open issue on an agent-actionable delivery" fact the team-exit reads
|
|
84
|
+
* (computeCompletionFacts postHasActionableOpen), minus the held deliveries.
|
|
85
|
+
*
|
|
86
|
+
* A coding delivery whose advance the hold defers has every issue terminal (that
|
|
87
|
+
* is why it is advancing), so it contributes nothing -- the 2026-09-06 storm
|
|
88
|
+
* shape stays "no actionable work".
|
|
89
|
+
*/
|
|
90
|
+
export function hasTeamWorkOutsideVerify(input) {
|
|
91
|
+
const actionableIds = new Set(input.deliveries
|
|
92
|
+
.filter((d) => !input.heldDeliveryIds.has(d.id) && isStatusAgentActionable(d.executionStatus ?? ''))
|
|
93
|
+
.map((d) => d.id));
|
|
94
|
+
return input.issues.some((i) => actionableIds.has(i.deliveryId) && OPEN_ISSUE_STATUSES.has(i.status));
|
|
95
|
+
}
|
|
63
96
|
/**
|
|
64
97
|
* The one predicate. An outstanding merge-conflict resolution request the daemon
|
|
65
98
|
* sent this team IS actionable work regardless of delivery state -- it takes
|
|
66
99
|
* precedence so a team finishing its last delivery is never torn down mid-merge.
|
|
67
|
-
* Otherwise a
|
|
68
|
-
*
|
|
69
|
-
* actionable-work fact stands. Pure, so
|
|
70
|
-
*
|
|
100
|
+
* Otherwise, under a verify hold the focus is actionable only when work exists
|
|
101
|
+
* OUTSIDE the delivery being verified (never more than the caller's own fact);
|
|
102
|
+
* with no hold, the caller's own actionable-work fact stands. Pure, so every
|
|
103
|
+
* controller reads the identical answer for a given state.
|
|
71
104
|
*/
|
|
72
105
|
export function focusHasTeamActionableWork(input) {
|
|
73
106
|
if (input.mergeResolutionOutstanding)
|
|
74
107
|
return true;
|
|
75
108
|
if (input.underVerifyHold)
|
|
76
|
-
return
|
|
109
|
+
return input.hasUnheldActionableWork && input.workOutsideVerifyHold === true;
|
|
77
110
|
return input.hasUnheldActionableWork;
|
|
78
111
|
}
|
|
79
112
|
/**
|
|
80
113
|
* Resolve the verify hold for a focus whose worktree path is already known, and
|
|
81
114
|
* fold it into the shared predicate in one step. Convenience for the team-exit
|
|
82
115
|
* fact-gathering (computeCompletionFacts), which has already resolved the
|
|
83
|
-
* worktree path; a null path means no
|
|
84
|
-
* dep is passed in so the caller
|
|
116
|
+
* worktree path and fetched the focus's deliveries + issues; a null path means no
|
|
117
|
+
* worktree -> no hold. The isWorktreeUnderVerify dep is passed in so the caller
|
|
118
|
+
* keeps its own injection seam.
|
|
85
119
|
*/
|
|
86
120
|
export function resolveTeamActionableWork(args) {
|
|
87
121
|
const underVerifyHold = args.focusWorktreePath !== null && args.isWorktreeUnderVerify(args.focusWorktreePath);
|
|
122
|
+
const workOutsideVerifyHold = underVerifyHold && args.outsideHold !== undefined
|
|
123
|
+
&& hasTeamWorkOutsideVerify({
|
|
124
|
+
deliveries: args.outsideHold.deliveries,
|
|
125
|
+
issues: args.outsideHold.issues,
|
|
126
|
+
heldDeliveryIds: (args.outsideHold.verifyHeldDeliveryIds ?? verifyHeldDeliveryIds)(args.focusWorktreePath),
|
|
127
|
+
});
|
|
88
128
|
return {
|
|
89
129
|
underVerifyHold,
|
|
90
130
|
teamHasActionableWork: focusHasTeamActionableWork({
|
|
91
131
|
hasUnheldActionableWork: args.hasUnheldActionableWork,
|
|
92
132
|
underVerifyHold,
|
|
133
|
+
workOutsideVerifyHold,
|
|
93
134
|
mergeResolutionOutstanding: args.mergeResolutionOutstanding,
|
|
94
135
|
}),
|
|
95
136
|
};
|
|
96
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolve the hold facts for a focus the caller knows only by id (the spawn gate,
|
|
140
|
+
* the pending-spawn pass, the directive executor). Reads deliveries + issues ONLY
|
|
141
|
+
* when the focus is held -- an unheld focus costs no fetch. A failed read fails
|
|
142
|
+
* CLOSED to "no work outside the hold": the storm-safe verdict (defer the spawn,
|
|
143
|
+
* re-read next poll), never a spawn into a focus whose work could not be seen.
|
|
144
|
+
*/
|
|
145
|
+
export async function resolveFocusVerifyHoldFacts(focusId, deps = {}) {
|
|
146
|
+
const worktreePath = (deps.getFocusWorktree ?? getFocusWorktree)(focusId)?.worktreePath ?? null;
|
|
147
|
+
if (worktreePath === null || !(deps.isWorktreeUnderVerify ?? isWorktreeUnderVerify)(worktreePath)) {
|
|
148
|
+
return { underVerifyHold: false, workOutsideVerifyHold: false };
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const [deliveries, issues] = await Promise.all([
|
|
152
|
+
(deps.getFocusDeliveries ?? getFocusDeliveries)(focusId),
|
|
153
|
+
(deps.getFocusIssues ?? getFocusIssues)(focusId),
|
|
154
|
+
]);
|
|
155
|
+
const heldDeliveryIds = (deps.verifyHeldDeliveryIds ?? verifyHeldDeliveryIds)(worktreePath);
|
|
156
|
+
return { underVerifyHold: true, workOutsideVerifyHold: hasTeamWorkOutsideVerify({ deliveries, issues, heldDeliveryIds }) };
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
log.debug(`[team-actionable-work] hold-facts read failed for focus ${focusId.slice(0, 8)}; treating as held with no outside work: ${err.message}`);
|
|
160
|
+
return { underVerifyHold: true, workOutsideVerifyHold: false };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
97
163
|
/**
|
|
98
164
|
* Whether ANY registered focus worktree is currently held by an in-flight
|
|
99
165
|
* verify. Reads the same hold source the per-focus predicate does
|
|
100
166
|
* (focus-worktree-state + verify-interlock), so the drain/idle gate agrees with
|
|
101
167
|
* the spawn gate and the team-exit classifier about "is a verify in flight".
|
|
102
168
|
*
|
|
103
|
-
* The auto-updater consumes this: a verify runs as a spawned child
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* incidental fact that a held focus happens to stay in the ready set.
|
|
169
|
+
* The auto-updater consumes this: a verify runs as a spawned child (verification-
|
|
170
|
+
* deterministic.ts) that can last up to ~30 min, and during that hold there is
|
|
171
|
+
* often NO active team. Restarting the daemon then would kill the verify
|
|
172
|
+
* mid-run, so an in-flight hold must read as "not idle" REGARDLESS of team count,
|
|
173
|
+
* queue depth, or which delivery it judges -- robustly, not by the incidental
|
|
174
|
+
* fact that a held focus happens to stay in the ready set.
|
|
110
175
|
*/
|
|
111
176
|
export function anyFocusUnderVerifyHold(deps = {}) {
|
|
112
177
|
const resolveAll = deps.getAllFocusWorktrees ?? getAllFocusWorktrees;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-actionable-work.js","sourceRoot":"","sources":["../../src/focus/team-actionable-work.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,+FAA+F;AAC/F,iEAAiE;AACjE,2DAA2D;AAC3D,gBAAgB;AAEhB
|
|
1
|
+
{"version":3,"file":"team-actionable-work.js","sourceRoot":"","sources":["../../src/focus/team-actionable-work.ts"],"names":[],"mappings":"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"}
|
package/dist/nexus/incoming.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by:
|
|
2
|
+
// Pinned by: packages/daemon/src/nexus/nexus-return-path-e2e.test.ts
|
|
3
3
|
// PINNED-BY-END
|
|
4
4
|
import { callApi } from '../queries/shared.js';
|
|
5
5
|
import { createLogger } from '../shell/log.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incoming.js","sourceRoot":"","sources":["../../src/nexus/incoming.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"incoming.js","sourceRoot":"","sources":["../../src/nexus/incoming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nexus pending returns on the REQUESTING focus: what that focus is waiting on
|
|
3
|
+
* across products, and what came back.
|
|
4
|
+
*
|
|
5
|
+
* A pending return (product_request_pending_returns) is one return -- a
|
|
6
|
+
* discovery, question or findings entry the requested team sent, or the
|
|
7
|
+
* request's close / decline -- carried on the requesting focus until the
|
|
8
|
+
* requesting team acknowledges it. This module owns the READ + RENDER half:
|
|
9
|
+
*
|
|
10
|
+
* - resolveNexusReturnsSection: loads the focus's unacknowledged returns and
|
|
11
|
+
* the open outgoing requests the focus waits on (filed from the focus OR
|
|
12
|
+
* from one of its deliveries), and renders ONE prompt section with every
|
|
13
|
+
* return's FULL content (never truncated). The spawn path folds it into the
|
|
14
|
+
* carried section every pass receives -- fresh coding, scoping, resume and
|
|
15
|
+
* review -- so no pass on the focus misses a return.
|
|
16
|
+
* - buildNexusReturnHandOff: the message handed to a LIVE team when a new
|
|
17
|
+
* return arrives mid-session (nexus/return-routing.ts decides when).
|
|
18
|
+
*
|
|
19
|
+
* Leaf module: imports only query helpers, never the return / routing passes,
|
|
20
|
+
* so both the spawn path and the poll pass can import it without a cycle.
|
|
21
|
+
*/
|
|
22
|
+
import { type CallApiDeps } from '../queries/shared.js';
|
|
23
|
+
/** Rows per pending-return page (the product-api's max `limit`). */
|
|
24
|
+
export declare const PENDING_RETURNS_PAGE_SIZE = 500;
|
|
25
|
+
/**
|
|
26
|
+
* Read EVERY pending return matching the filter, oldest first. One list call
|
|
27
|
+
* serves at most a page, so a burst larger than a page would otherwise leave
|
|
28
|
+
* returns out of a prompt or out of an engagement pass. Walks the keyset cursor
|
|
29
|
+
* (the last row's createdAt + id) until a page comes back shorter than the limit
|
|
30
|
+
* the server applied (it echoes `limit`), so an earlier return acknowledged
|
|
31
|
+
* mid-walk never shifts a later one out of the read and a server cap below the
|
|
32
|
+
* requested page never ends the walk early. A full page that does not advance
|
|
33
|
+
* the cursor THROWS (no partial list read as complete). THROWS on a hard API
|
|
34
|
+
* error. `deps.callApi` is the test seam.
|
|
35
|
+
*/
|
|
36
|
+
export declare function listAllPendingReturns(filter: {
|
|
37
|
+
focusId?: string;
|
|
38
|
+
productId?: string;
|
|
39
|
+
unengagedOnly?: boolean;
|
|
40
|
+
}, deps?: CallApiDeps): Promise<PendingReturn[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Request statuses in which an outgoing request is still open: the requesting
|
|
43
|
+
* work waits on it. Single definition shared with the source-delivery gate
|
|
44
|
+
* (nexus/return.ts).
|
|
45
|
+
*/
|
|
46
|
+
export declare const WAITING_REQUEST_STATUSES: ReadonlySet<string>;
|
|
47
|
+
/** One pending return as product_request_list_pending_returns returns it (camelCase). */
|
|
48
|
+
export interface PendingReturn {
|
|
49
|
+
id: string;
|
|
50
|
+
requestId: string;
|
|
51
|
+
entryId?: string | null;
|
|
52
|
+
sourceFocusId?: string | null;
|
|
53
|
+
sourceDeliveryId?: string | null;
|
|
54
|
+
/** discovery | question | findings | closed | declined */
|
|
55
|
+
returnKind: string;
|
|
56
|
+
content: string;
|
|
57
|
+
createdAt: string;
|
|
58
|
+
engagedAt?: string | null;
|
|
59
|
+
requestTitle?: string | null;
|
|
60
|
+
requestStatus?: string | null;
|
|
61
|
+
targetProductId?: string | null;
|
|
62
|
+
}
|
|
63
|
+
/** The outgoing-request fields the waiting-on read needs. */
|
|
64
|
+
export interface WaitingRequest {
|
|
65
|
+
id: string;
|
|
66
|
+
status?: string;
|
|
67
|
+
title?: string | null;
|
|
68
|
+
sourceFocusId?: string | null;
|
|
69
|
+
sourceDeliveryId?: string | null;
|
|
70
|
+
targetProductId?: string | null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Pure: the open outgoing requests a focus waits on -- filed from the focus
|
|
74
|
+
* itself (with or without a source delivery) or from one of its deliveries.
|
|
75
|
+
*/
|
|
76
|
+
export declare function selectWaitingOnRequests(outgoing: readonly WaitingRequest[], focusId: string, deliveryIds: ReadonlySet<string>): WaitingRequest[];
|
|
77
|
+
/** Pure: one return rendered in full (its content is never truncated). */
|
|
78
|
+
export declare function renderPendingReturnBlock(ret: PendingReturn): string[];
|
|
79
|
+
/**
|
|
80
|
+
* Pure: the Nexus section for a focus's prompt. Empty (no lines) when the focus
|
|
81
|
+
* waits on nothing and has no pending return.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildNexusReturnsSection(args: {
|
|
84
|
+
waitingOn: readonly WaitingRequest[];
|
|
85
|
+
pendingReturns: readonly PendingReturn[];
|
|
86
|
+
}): string;
|
|
87
|
+
/** Pure: the message handed to a live team when new returns arrive mid-session. */
|
|
88
|
+
export declare function buildNexusReturnHandOff(returns: readonly PendingReturn[]): string;
|
|
89
|
+
/** Injectable reads (tests pass fakes; production uses callApi). */
|
|
90
|
+
export interface NexusReturnsSectionDeps {
|
|
91
|
+
listFocusPendingReturns: (focusId: string) => Promise<PendingReturn[]>;
|
|
92
|
+
listOutgoing: (productId: string) => Promise<WaitingRequest[]>;
|
|
93
|
+
}
|
|
94
|
+
/** The production reads over a product-api client (`apiDeps.callApi` is the test seam). */
|
|
95
|
+
export declare function nexusReturnsSectionDeps(apiDeps?: CallApiDeps): NexusReturnsSectionDeps;
|
|
96
|
+
export declare const defaultNexusReturnsSectionDeps: NexusReturnsSectionDeps;
|
|
97
|
+
/**
|
|
98
|
+
* Load + render the focus's Nexus section. Best-effort: each read degrades to
|
|
99
|
+
* empty on failure (logged) and never blocks a spawn.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resolveNexusReturnsSection(args: {
|
|
102
|
+
focusId: string;
|
|
103
|
+
productId: string | undefined;
|
|
104
|
+
deliveryIds: readonly string[];
|
|
105
|
+
}, deps?: NexusReturnsSectionDeps): Promise<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Fold the focus's Nexus section into the section every spawn shape carries
|
|
108
|
+
* (the answered-escalations carrier: appended to fresh directive + legacy
|
|
109
|
+
* prompts, the scoping message and the resume delta, for coding AND review
|
|
110
|
+
* passes). Ids are untouched: they name escalations to consume, not returns --
|
|
111
|
+
* a return is consumed only by the team's acknowledgement.
|
|
112
|
+
*/
|
|
113
|
+
export declare function foldNexusReturnsSection(carried: {
|
|
114
|
+
section: string;
|
|
115
|
+
ids: string[];
|
|
116
|
+
}, args: {
|
|
117
|
+
focusId: string;
|
|
118
|
+
productId: string | undefined;
|
|
119
|
+
deliveryIds: readonly string[];
|
|
120
|
+
}, deps?: NexusReturnsSectionDeps): Promise<{
|
|
121
|
+
section: string;
|
|
122
|
+
ids: string[];
|
|
123
|
+
}>;
|
|
124
|
+
//# sourceMappingURL=pending-returns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-returns.d.ts","sourceRoot":"","sources":["../../src/nexus/pending-returns.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMjE,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAQ7C;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,EACzE,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,aAAa,EAAE,CAAC,CAiB1B;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAA6D,CAAC;AAEvH,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,cAAc,EAAE,CAMlB;AAgBD,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,EAAE,CAUrE;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C,GAAG,MAAM,CAgCT;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAWjF;AAED,oEAAoE;AACpE,MAAM,WAAW,uBAAuB;IACtC,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACvE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;CAChE;AAED,2FAA2F;AAC3F,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,WAAgB,GAAG,uBAAuB,CAK1F;AAED,eAAO,MAAM,8BAA8B,EAAE,uBAAmD,CAAC;AAEjG;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EACxF,IAAI,GAAE,uBAAwD,GAC7D,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,EAC3C,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EACxF,IAAI,GAAE,uBAAwD,GAC7D,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAO7C"}
|