t3code-cli 0.14.1 → 0.15.0
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/README.md +37 -1
- package/dist/application.d.ts +2 -2
- package/dist/application.js +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +1 -1
- package/dist/bin.js +1305 -424
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/client-runtime/authorization.d.ts +1 -1
- package/dist/client-runtime/authorization.js +1 -1
- package/dist/client-runtime/connection.d.ts +1 -1
- package/dist/client-runtime/connection.js +1 -1
- package/dist/client-runtime/environment.d.ts +7 -1
- package/dist/client-runtime/environment.js +1 -1
- package/dist/client-runtime/errors.js +1 -1
- package/dist/client-runtime/operations/projects.d.ts +2 -2
- package/dist/client-runtime/operations/projects.js +2 -2
- package/dist/client-runtime/operations.d.ts +2 -2
- package/dist/client-runtime/operations.js +2 -2
- package/dist/client-runtime/platform.d.ts +1 -1
- package/dist/client-runtime/platform.js +1 -1
- package/dist/client-runtime/relay.d.ts +13 -2
- package/dist/client-runtime/relay.js +12 -2
- package/dist/client-runtime/rpc.d.ts +2 -2
- package/dist/client-runtime/rpc.js +2 -2
- package/dist/client-runtime/state/assets.d.ts +17 -11
- package/dist/client-runtime/state/assets.js +1 -1
- package/dist/client-runtime/state/auth.d.ts +1 -1
- package/dist/client-runtime/state/auth.js +1 -1
- package/dist/client-runtime/state/connections.js +1 -1
- package/dist/client-runtime/state/entities.d.ts +1 -1
- package/dist/client-runtime/state/entities.js +1 -1
- package/dist/client-runtime/state/filesystem.d.ts +1 -1
- package/dist/client-runtime/state/filesystem.js +1 -1
- package/dist/client-runtime/state/git.d.ts +6 -5
- package/dist/client-runtime/state/git.js +1 -1
- package/dist/client-runtime/state/models.d.ts +1 -1
- package/dist/client-runtime/state/models.js +1 -1
- package/dist/client-runtime/state/orchestration.d.ts +42 -2
- package/dist/client-runtime/state/orchestration.js +13 -1
- package/dist/client-runtime/state/presentation.d.ts +15 -3
- package/dist/client-runtime/state/presentation.js +1 -1
- package/dist/client-runtime/state/preview.d.ts +58 -48
- package/dist/client-runtime/state/preview.js +3 -2
- package/dist/client-runtime/state/project-grouping.d.ts +26 -2
- package/dist/client-runtime/state/project-grouping.js +83 -3
- package/dist/client-runtime/state/projects.d.ts +24 -18
- package/dist/client-runtime/state/projects.js +1 -1
- package/dist/client-runtime/state/pull-requests.d.ts +478 -0
- package/dist/client-runtime/state/pull-requests.js +172 -0
- package/dist/client-runtime/state/relay.d.ts +1 -1
- package/dist/client-runtime/state/relay.js +1 -1
- package/dist/client-runtime/state/review.d.ts +16 -1
- package/dist/client-runtime/state/review.js +27 -6
- package/dist/client-runtime/state/runtime.d.ts +2 -2
- package/dist/client-runtime/state/runtime.js +2 -2
- package/dist/client-runtime/state/server.d.ts +311 -172
- package/dist/client-runtime/state/server.js +192 -16
- package/dist/client-runtime/state/session.d.ts +77 -7
- package/dist/client-runtime/state/session.js +32 -3
- package/dist/client-runtime/state/shell.d.ts +47 -7
- package/dist/client-runtime/state/shell.js +1 -1
- package/dist/client-runtime/state/source-control.d.ts +2 -2
- package/dist/client-runtime/state/source-control.js +1 -1
- package/dist/client-runtime/state/subagentRuntime.d.ts +145 -0
- package/dist/client-runtime/state/subagentRuntime.js +521 -0
- package/dist/client-runtime/state/terminal.d.ts +17 -17
- package/dist/client-runtime/state/terminal.js +1 -1
- package/dist/client-runtime/state/thread-search.d.ts +23 -0
- package/dist/client-runtime/state/thread-search.js +38 -0
- package/dist/client-runtime/state/thread-settled.d.ts +32 -4
- package/dist/client-runtime/state/thread-settled.js +2 -157
- package/dist/client-runtime/state/thread-sort.d.ts +59 -2
- package/dist/client-runtime/state/thread-sort.js +128 -2
- package/dist/client-runtime/state/threads.d.ts +115 -3
- package/dist/client-runtime/state/threads.js +309 -28
- package/dist/client-runtime/state/vcs.d.ts +14 -14
- package/dist/client-runtime/state/vcs.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connection.d.ts +1 -1
- package/dist/connection.js +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/orchestration.d.ts +155 -6
- package/dist/orchestration.js +2 -2
- package/dist/preview.d.ts +1 -1
- package/dist/preview.js +1 -1
- package/dist/rpc.d.ts +887 -360
- package/dist/rpc.js +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/shared/DrainableWorker.js +1 -1
- package/dist/shared/KeyedCoalescingWorker.js +1 -1
- package/dist/shared/Net.d.ts +6 -0
- package/dist/shared/Net.js +2 -1
- package/dist/shared/advertisedEndpoint.d.ts +1 -1
- package/dist/shared/advertisedEndpoint.js +1 -1
- package/dist/shared/agentAwareness.d.ts +1 -1
- package/dist/shared/backgroundActivitySettings.d.ts +1 -1
- package/dist/shared/composerInlineTokens.js +1 -1
- package/dist/shared/connectAuth.d.ts +23 -4
- package/dist/shared/connectAuth.js +40 -7
- package/dist/shared/devHome.js +1 -1
- package/dist/shared/dpop.js +1 -1
- package/dist/shared/git.d.ts +1 -1
- package/dist/shared/httpObservability.js +1 -1
- package/dist/shared/httpReadiness.js +1 -1
- package/dist/shared/keybindings.d.ts +2 -2
- package/dist/shared/keybindings.js +15 -1
- package/dist/shared/model.d.ts +1 -1
- package/dist/shared/oauthScope.js +1 -1
- package/dist/shared/observability.d.ts +8 -1
- package/dist/shared/observability.js +49 -5
- package/dist/shared/path.js +1 -1
- package/dist/shared/preview.js +1 -1
- package/dist/shared/previewViewport.d.ts +1 -1
- package/dist/shared/previewViewport.js +1 -1
- package/dist/shared/projectFavicon.d.ts +2 -1
- package/dist/shared/projectFavicon.js +13 -1
- package/dist/shared/projectScripts.d.ts +1 -1
- package/dist/shared/relayAuth.js +1 -1
- package/dist/shared/relayClient.d.ts +1 -1
- package/dist/shared/relayClient.js +1 -1
- package/dist/shared/relayJwt.js +1 -1
- package/dist/shared/relayTracing.js +1 -1
- package/dist/shared/relayUrl.js +1 -1
- package/dist/shared/remote.js +1 -1
- package/dist/shared/schemaYaml.js +3 -3
- package/dist/shared/semver.js +1 -1
- package/dist/shared/serverSettings.d.ts +1 -1
- package/dist/shared/serverSettings.js +1 -1
- package/dist/shared/shell.d.ts +6 -1
- package/dist/shared/shell.js +42 -4
- package/dist/shared/sourceControl.d.ts +1 -1
- package/dist/shared/t3ProjectFile.d.ts +9 -1
- package/dist/shared/t3ProjectFile.js +12 -2
- package/dist/shared/terminalLabels.d.ts +1 -1
- package/dist/shared/threadEnvMode.d.ts +29 -0
- package/dist/shared/threadEnvMode.js +24 -0
- package/dist/shared/toolActivity.d.ts +1 -1
- package/dist/shared/usageFormat.d.ts +34 -0
- package/dist/shared/usageFormat.js +176 -0
- package/dist/shared/usageMerge.d.ts +78 -0
- package/dist/shared/usageMerge.js +241 -0
- package/dist/shared.d.ts +8268 -1372
- package/dist/shared.js +22185 -19774
- package/dist/t3tools.d.ts +2 -2
- package/dist/t3tools.js +2 -2
- package/package.json +5 -5
- package/src/application/error.ts +2 -2
- package/src/application/index.ts +2 -0
- package/src/application/service.ts +43 -5
- package/src/application/thread-commands.ts +78 -0
- package/src/application/threads.ts +156 -17
- package/src/cli/app.ts +4 -0
- package/src/cli/ask-lifecycle.ts +331 -0
- package/src/cli/ask.ts +390 -0
- package/src/cli/error.ts +70 -0
- package/src/cli/format/thread.ts +49 -7
- package/src/cli/search.ts +48 -0
- package/src/cli/thread.ts +12 -0
- package/src/cli/threads/messages.ts +33 -3
- package/src/cli/threads/pin.ts +46 -0
- package/src/cli/threads/send.ts +5 -1
- package/src/cli/threads/settle.ts +46 -0
- package/src/cli/threads/snooze.ts +117 -0
- package/src/cli/threads/start.ts +6 -1
- package/src/cli/threads/unpin.ts +48 -0
- package/src/cli/threads/unsettle.ts +48 -0
- package/src/cli/threads/unsnooze.ts +48 -0
- package/src/config/persist/schema.ts +1 -1
- package/src/connection/prepared.ts +12 -2
- package/src/orchestration/error.ts +10 -0
- package/src/orchestration/index.ts +1 -0
- package/src/orchestration/layer.ts +78 -0
- package/src/orchestration/service.ts +16 -3
- package/src/rpc/error.ts +2 -0
- package/src/rpc/operation.ts +2 -0
- package/src/rpc/ws-group.ts +3 -0
- package/src/runtime/layer.ts +9 -4
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { vb as OrchestrationThreadShell } from "../../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/client-runtime/src/state/threadSettled.d.ts
|
|
3
3
|
type ChangeRequestStateLike = "open" | "closed" | "merged";
|
|
4
|
+
/** Returns whether the change request state settles the thread immediately. */
|
|
5
|
+
declare function changeRequestAutoSettles(state: ChangeRequestStateLike | null | undefined, autoSettleOnMerge?: boolean): boolean;
|
|
4
6
|
declare function threadLastActivityAt(shell: OrchestrationThreadShell): string | null;
|
|
5
7
|
/**
|
|
6
8
|
* A queued turn start lives for at most this long: session adoption takes
|
|
@@ -90,15 +92,41 @@ declare function threadWokeAt(shell: ThreadSnoozeShell, options: {
|
|
|
90
92
|
* queued turn) are checked first and hold a thread active regardless of any
|
|
91
93
|
* override. Past the blockers, the explicit user override (thread.settle /
|
|
92
94
|
* thread.unsettle commands, projected into settledOverride + settledAt)
|
|
93
|
-
* wins in both directions; without one, a thread auto-
|
|
94
|
-
* merged
|
|
95
|
+
* wins in both directions; without one, a thread can auto-settle on a
|
|
96
|
+
* merged PR, always settles on a closed PR, or settles on inactivity past
|
|
97
|
+
* the window. An open PR blocks the inactivity path entirely. The server
|
|
95
98
|
* un-settles on real activity (user message, session start, approval/
|
|
96
99
|
* user-input request), so an override never goes stale silently.
|
|
97
100
|
*/
|
|
98
101
|
declare function effectiveSettled(shell: OrchestrationThreadShell, options: {
|
|
99
102
|
readonly now: string;
|
|
100
103
|
readonly autoSettleAfterDays: number | null;
|
|
104
|
+
readonly autoSettleOnMerge?: boolean;
|
|
101
105
|
readonly changeRequestState?: ChangeRequestStateLike | null;
|
|
102
106
|
}): boolean;
|
|
107
|
+
type SnoozePresetId = "hour" | "three-hours" | "evening" | "tomorrow" | "next-week";
|
|
108
|
+
interface SnoozePreset {
|
|
109
|
+
readonly id: SnoozePresetId;
|
|
110
|
+
readonly label: string;
|
|
111
|
+
/** Menu-row time column. Complements the label instead of repeating it:
|
|
112
|
+
"Tomorrow" pairs with "9:00 AM", not "tomorrow 9:00 AM". */
|
|
113
|
+
readonly whenLabel: string;
|
|
114
|
+
/** ISO wake time. */
|
|
115
|
+
readonly snoozedUntil: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Shared "snooze until" choices for every client. "This evening" only
|
|
119
|
+
* appears while it is meaningfully before evening; after that the calendar
|
|
120
|
+
* choices start at "Tomorrow".
|
|
121
|
+
*/
|
|
122
|
+
declare function resolveSnoozePresets(now: Date): ReadonlyArray<SnoozePreset>;
|
|
123
|
+
/**
|
|
124
|
+
* Compact "wakes in" label for snoozed rows: "2h", "18h", "3d". Minutes
|
|
125
|
+
* round up so a snooze never reads "0m" while still hidden. Shared by web
|
|
126
|
+
* and mobile so the same wake time never reads differently per client.
|
|
127
|
+
*/
|
|
128
|
+
declare function snoozeWakeLabel(snoozedUntil: string, options: {
|
|
129
|
+
readonly now: string;
|
|
130
|
+
}): string;
|
|
103
131
|
//#endregion
|
|
104
|
-
export { ChangeRequestStateLike, QUEUED_TURN_START_GRACE_MS, ThreadSnoozeShell, canSettle, canSnooze, effectiveSettled, effectiveSnoozed, hasQueuedTurnStart, threadLastActivityAt, threadRaisedHandWhileSnoozed, threadWokeAt };
|
|
132
|
+
export { ChangeRequestStateLike, QUEUED_TURN_START_GRACE_MS, SnoozePreset, SnoozePresetId, ThreadSnoozeShell, canSettle, canSnooze, changeRequestAutoSettles, effectiveSettled, effectiveSnoozed, hasQueuedTurnStart, resolveSnoozePresets, snoozeWakeLabel, threadLastActivityAt, threadRaisedHandWhileSnoozed, threadWokeAt };
|
|
@@ -1,157 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function threadLastActivityAt(shell) {
|
|
4
|
-
const candidates = [
|
|
5
|
-
shell.latestUserMessageAt,
|
|
6
|
-
shell.latestTurn?.requestedAt,
|
|
7
|
-
shell.latestTurn?.startedAt,
|
|
8
|
-
shell.latestTurn?.completedAt
|
|
9
|
-
];
|
|
10
|
-
let latest = null;
|
|
11
|
-
let latestTimestamp = Number.NEGATIVE_INFINITY;
|
|
12
|
-
for (const candidate of candidates) {
|
|
13
|
-
if (candidate === null || candidate === void 0) continue;
|
|
14
|
-
const timestamp = Date.parse(candidate);
|
|
15
|
-
if (timestamp > latestTimestamp) {
|
|
16
|
-
latest = candidate;
|
|
17
|
-
latestTimestamp = timestamp;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return latest;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* A queued turn start lives for at most this long: session adoption takes
|
|
24
|
-
* seconds, so a user message still unadopted after the grace window is a
|
|
25
|
-
* failed start (or stale data — shells from older servers can carry user
|
|
26
|
-
* messages with no latestTurn at all), not pending work. Without this bound
|
|
27
|
-
* such threads would be permanently unsettleable.
|
|
28
|
-
*/
|
|
29
|
-
const QUEUED_TURN_START_GRACE_MS = 120 * 1e3;
|
|
30
|
-
/**
|
|
31
|
-
* A user message no turn has picked up yet: the turn.start command was
|
|
32
|
-
* dispatched (message-sent + turn-start-requested) but no session has
|
|
33
|
-
* adopted it, so `session` is still null and the pending work is invisible
|
|
34
|
-
* to the session-status checks. Detectable as a user message strictly newer
|
|
35
|
-
* than every timestamp on the latest turn — on adoption the new turn's
|
|
36
|
-
* requestedAt equals the message time, clearing the condition — and only
|
|
37
|
-
* within the adoption grace window.
|
|
38
|
-
*/
|
|
39
|
-
function hasQueuedTurnStart(shell, options) {
|
|
40
|
-
if (shell.latestUserMessageAt == null) return false;
|
|
41
|
-
if (shell.session?.status === "error") return false;
|
|
42
|
-
const messageAt = Date.parse(shell.latestUserMessageAt);
|
|
43
|
-
if (Number.isNaN(messageAt)) return false;
|
|
44
|
-
const nowMs = Date.parse(options.now);
|
|
45
|
-
if (Number.isNaN(nowMs)) return false;
|
|
46
|
-
if (Math.abs(nowMs - messageAt) > 12e4) return false;
|
|
47
|
-
const turn = shell.latestTurn;
|
|
48
|
-
if (turn === null) return true;
|
|
49
|
-
return [
|
|
50
|
-
turn.requestedAt,
|
|
51
|
-
turn.startedAt,
|
|
52
|
-
turn.completedAt
|
|
53
|
-
].every((candidate) => candidate == null || Date.parse(candidate) < messageAt);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* A thread may be settled only when none of effectiveSettled's activity
|
|
57
|
-
* blockers hold. This is deliberately the same list: anything the partition
|
|
58
|
-
* refuses to CLASSIFY as settled must also be refused as a settle TARGET.
|
|
59
|
-
* The server enforces its own invariants; this client-side twin exists so
|
|
60
|
-
* the UI can disable/reject before a round trip.
|
|
61
|
-
*/
|
|
62
|
-
function canSettle(shell, options) {
|
|
63
|
-
if (shell.hasPendingApprovals || shell.hasPendingUserInput) return false;
|
|
64
|
-
if (shell.session?.status === "starting" || shell.session?.status === "running") return false;
|
|
65
|
-
if (hasQueuedTurnStart(shell, options)) return false;
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* A snoozed thread "raises its hand" when something happens that outranks
|
|
70
|
-
* the user's snooze: the agent is blocked on them (approval / user input),
|
|
71
|
-
* the session failed, or a run completed after the snooze was set — the
|
|
72
|
-
* v1 taste of event-based snooze ("something happened" wakes early).
|
|
73
|
-
* Raising a hand never clears the server-side snooze fields; it only stops
|
|
74
|
-
* the thread from CLASSIFYING as snoozed, exactly like blocked work and
|
|
75
|
-
* effectiveSettled.
|
|
76
|
-
*/
|
|
77
|
-
function threadRaisedHandWhileSnoozed(shell) {
|
|
78
|
-
if (shell.hasPendingApprovals || shell.hasPendingUserInput) return true;
|
|
79
|
-
if (shell.session?.status === "error" && (shell.snoozedAt == null || Date.parse(shell.session.updatedAt) > Date.parse(shell.snoozedAt))) return true;
|
|
80
|
-
if (shell.snoozedAt != null && shell.latestTurn?.state === "completed" && shell.latestTurn.completedAt != null && Date.parse(shell.latestTurn.completedAt) > Date.parse(shell.snoozedAt)) return true;
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* A thread may be snoozed unless the agent is blocked on the user: hiding a
|
|
85
|
-
* pending approval or user-input request defeats the request, and a queued
|
|
86
|
-
* turn start (a message no turn has adopted yet) is invisible pending work
|
|
87
|
-
* the same way it is for settle. A running session IS snoozable — snooze
|
|
88
|
-
* only affects visibility, never the agent. Client-side twin of the server
|
|
89
|
-
* invariants so the UI can reject before a round trip.
|
|
90
|
-
*/
|
|
91
|
-
function canSnooze(shell, options) {
|
|
92
|
-
if (shell.hasPendingApprovals || shell.hasPendingUserInput) return false;
|
|
93
|
-
if (hasQueuedTurnStart(shell, options)) return false;
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Snoozed resolution: hidden from the inbox while the wake time is in the
|
|
98
|
-
* future and the thread has not raised its hand. Timer wakes are derived —
|
|
99
|
-
* no server event fires when snoozedUntil passes; the stale fields simply
|
|
100
|
-
* stop classifying as snoozed (and feed the woke indicator until the user
|
|
101
|
-
* visits or re-engages).
|
|
102
|
-
*/
|
|
103
|
-
function effectiveSnoozed(shell, options) {
|
|
104
|
-
if (shell.snoozedUntil == null) return false;
|
|
105
|
-
const wakeAtMs = Date.parse(shell.snoozedUntil);
|
|
106
|
-
if (Number.isNaN(wakeAtMs)) return false;
|
|
107
|
-
if (wakeAtMs <= Date.parse(options.now)) return false;
|
|
108
|
-
return !threadRaisedHandWhileSnoozed(shell);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* When a previously-snoozed thread woke, or null if it never snoozed / is
|
|
112
|
-
* still snoozed. Used for the "Woke" indicator: the thread reappears in its
|
|
113
|
-
* original sort position (the inbox sort is deliberately static), so the
|
|
114
|
-
* wake signal has to carry the weight. Compare against the client's
|
|
115
|
-
* lastVisitedAt — visiting clears the indicator like it clears unread.
|
|
116
|
-
*
|
|
117
|
-
* Timer wakes report the wake time itself; raised-hand wakes report the
|
|
118
|
-
* triggering timestamp so a visit BEFORE the early wake doesn't suppress
|
|
119
|
-
* the indicator.
|
|
120
|
-
*/
|
|
121
|
-
function threadWokeAt(shell, options) {
|
|
122
|
-
if (shell.snoozedUntil == null) return null;
|
|
123
|
-
const wakeAtMs = Date.parse(shell.snoozedUntil);
|
|
124
|
-
if (Number.isNaN(wakeAtMs)) return null;
|
|
125
|
-
if (threadRaisedHandWhileSnoozed(shell)) {
|
|
126
|
-
if (shell.snoozedAt != null && shell.latestTurn?.state === "completed" && shell.latestTurn.completedAt != null && Date.parse(shell.latestTurn.completedAt) > Date.parse(shell.snoozedAt)) return shell.latestTurn.completedAt;
|
|
127
|
-
return shell.session?.updatedAt ?? shell.snoozedAt ?? null;
|
|
128
|
-
}
|
|
129
|
-
return wakeAtMs <= Date.parse(options.now) ? shell.snoozedUntil : null;
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Settled resolution over the server-backed settled lifecycle. Activity
|
|
133
|
-
* blockers (pending approval/user-input, a live session, an unadjudicated
|
|
134
|
-
* queued turn) are checked first and hold a thread active regardless of any
|
|
135
|
-
* override. Past the blockers, the explicit user override (thread.settle /
|
|
136
|
-
* thread.unsettle commands, projected into settledOverride + settledAt)
|
|
137
|
-
* wins in both directions; without one, a thread auto-settles on a
|
|
138
|
-
* merged/closed PR immediately or on inactivity past the window. The server
|
|
139
|
-
* un-settles on real activity (user message, session start, approval/
|
|
140
|
-
* user-input request), so an override never goes stale silently.
|
|
141
|
-
*/
|
|
142
|
-
function effectiveSettled(shell, options) {
|
|
143
|
-
if (shell.hasPendingApprovals || shell.hasPendingUserInput) return false;
|
|
144
|
-
if (shell.session?.status === "starting" || shell.session?.status === "running") return false;
|
|
145
|
-
if (hasQueuedTurnStart(shell, { now: options.now })) {
|
|
146
|
-
if (!(shell.settledOverride === "settled" && shell.settledAt !== null && shell.latestUserMessageAt !== null && Date.parse(shell.settledAt) >= Date.parse(shell.latestUserMessageAt))) return false;
|
|
147
|
-
}
|
|
148
|
-
if (shell.settledOverride === "settled") return true;
|
|
149
|
-
if (shell.settledOverride === "active") return false;
|
|
150
|
-
if (options.changeRequestState === "merged" || options.changeRequestState === "closed") return true;
|
|
151
|
-
if (options.autoSettleAfterDays === null) return false;
|
|
152
|
-
const lastActivityAt = threadLastActivityAt(shell);
|
|
153
|
-
if (lastActivityAt === null) return false;
|
|
154
|
-
return Date.parse(lastActivityAt) < Date.parse(options.now) - options.autoSettleAfterDays * DAY_MS;
|
|
155
|
-
}
|
|
156
|
-
//#endregion
|
|
157
|
-
export { QUEUED_TURN_START_GRACE_MS, canSettle, canSnooze, effectiveSettled, effectiveSnoozed, hasQueuedTurnStart, threadLastActivityAt, threadRaisedHandWhileSnoozed, threadWokeAt };
|
|
1
|
+
import { $s as threadRaisedHandWhileSnoozed, Gs as canSnooze, Js as effectiveSnoozed, Ks as changeRequestAutoSettles, Qs as threadLastActivityAt, Us as QUEUED_TURN_START_GRACE_MS, Ws as canSettle, Xs as resolveSnoozePresets, Ys as hasQueuedTurnStart, Zs as snoozeWakeLabel, ec as threadWokeAt, qs as effectiveSettled } from "../../shared.js";
|
|
2
|
+
export { QUEUED_TURN_START_GRACE_MS, canSettle, canSnooze, changeRequestAutoSettles, effectiveSettled, effectiveSnoozed, hasQueuedTurnStart, resolveSnoozePresets, snoozeWakeLabel, threadLastActivityAt, threadRaisedHandWhileSnoozed, threadWokeAt };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ek as ProjectId, ry as SidebarThreadSortOrder, ty as SidebarProjectSortOrder } from "../../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/client-runtime/src/state/threadSort.d.ts
|
|
3
3
|
interface ThreadSortInput {
|
|
4
4
|
readonly createdAt: string;
|
|
@@ -19,5 +19,62 @@ declare function getLatestThreadForProject<T extends {
|
|
|
19
19
|
readonly projectId: ProjectId;
|
|
20
20
|
readonly archivedAt: string | null;
|
|
21
21
|
} & ThreadSortInput>(threads: readonly T[], projectId: ProjectId, sortOrder: SidebarThreadSortOrder): T | null;
|
|
22
|
+
/** Key that sorts strictly between two neighbors; null bounds mean "top of
|
|
23
|
+
the pinned block" / "bottom of the keyed run". Returns null instead of
|
|
24
|
+
throwing when existing keys are corrupt or out of order — callers fall
|
|
25
|
+
back to rewriting the section. */
|
|
26
|
+
declare function pinOrderKeyBetween(before: string | null, after: string | null): string | null;
|
|
27
|
+
/** Evenly spaced keys for rewriting a whole pinned section (used when a
|
|
28
|
+
drop lands next to keyless threads, so single-key insertion has nothing
|
|
29
|
+
to anchor on). Two base-26 digits give 675 slots — far beyond any real
|
|
30
|
+
pinned section — with monotonicity enforced as a belt-and-braces. */
|
|
31
|
+
declare function generateSpreadPinOrderKeys(count: number): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Assignments needed to realize a new pinned order. When the moved thread
|
|
34
|
+
* sits between two keyed (or absent) neighbors, this is a single write to
|
|
35
|
+
* the moved thread. When a neighbor is keyless (threads pinned before
|
|
36
|
+
* reordering shipped), the whole section gets fresh spread keys — a
|
|
37
|
+
* one-time materialization; every move after that is single-write.
|
|
38
|
+
*/
|
|
39
|
+
declare function planPinnedReorder(input: {
|
|
40
|
+
/** Thread ids in the desired visual order (after the move). */
|
|
41
|
+
readonly orderedIds: readonly string[];
|
|
42
|
+
readonly keysById: ReadonlyMap<string, string | null | undefined>;
|
|
43
|
+
readonly movedId: string;
|
|
44
|
+
}): ReadonlyArray<{
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly orderKey: string;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Pinned block order: user-arranged keys first (string comparison, id
|
|
50
|
+
* tiebreak), then keyless threads newest-created first — so threads on
|
|
51
|
+
* servers that predate reordering keep the static creation order at the
|
|
52
|
+
* bottom of the block instead of breaking the section.
|
|
53
|
+
*/
|
|
54
|
+
declare function sortPinnedThreadsByOrderKey<T extends {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly createdAt: string;
|
|
57
|
+
readonly pinOrderKey?: string | null | undefined;
|
|
58
|
+
/** Thread ids are only unique within an environment, and the pinned
|
|
59
|
+
block merges environments — the tiebreak needs both parts or two
|
|
60
|
+
clients could render equal-key threads in stream-arrival order. */
|
|
61
|
+
readonly environmentId?: string | undefined;
|
|
62
|
+
}>(threads: readonly T[]): T[];
|
|
63
|
+
/**
|
|
64
|
+
* planPinnedReorder specialized for mobile's Move up / Move down menu
|
|
65
|
+
* actions: swap the moved thread with its displayed neighbor. Null when the
|
|
66
|
+
* move falls off either end of the list. Same single-write-per-move
|
|
67
|
+
* semantics as a web drag.
|
|
68
|
+
*/
|
|
69
|
+
declare function planPinnedMove(input: {
|
|
70
|
+
/** Reorder-capable pinned thread ids in displayed order. */
|
|
71
|
+
readonly orderedIds: readonly string[];
|
|
72
|
+
readonly keysById: ReadonlyMap<string, string | null | undefined>;
|
|
73
|
+
readonly movedId: string;
|
|
74
|
+
readonly direction: "up" | "down";
|
|
75
|
+
}): ReadonlyArray<{
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly orderKey: string;
|
|
78
|
+
}> | null;
|
|
22
79
|
//#endregion
|
|
23
|
-
export { ThreadSortInput, getLatestThreadForProject, getThreadSortTimestamp, sortThreads, toSortableTimestamp };
|
|
80
|
+
export { ThreadSortInput, generateSpreadPinOrderKeys, getLatestThreadForProject, getThreadSortTimestamp, pinOrderKeyBetween, planPinnedMove, planPinnedReorder, sortPinnedThreadsByOrderKey, sortThreads, toSortableTimestamp };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $N as flip, JN as Number$1, XN as Struct, YN as String, eP as mapInput, gN as sort } from "../../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/client-runtime/src/state/threadSort.ts
|
|
3
3
|
function toSortableTimestamp(iso) {
|
|
4
4
|
if (!iso) return null;
|
|
@@ -43,5 +43,131 @@ function sortThreads(threads, sortOrder) {
|
|
|
43
43
|
function getLatestThreadForProject(threads, projectId, sortOrder) {
|
|
44
44
|
return sortThreads(threads.filter((thread) => thread.projectId === projectId && thread.archivedAt === null), sortOrder)[0] ?? null;
|
|
45
45
|
}
|
|
46
|
+
const PIN_ORDER_DIGITS = "abcdefghijklmnopqrstuvwxyz";
|
|
47
|
+
function isValidPinOrderKey(key) {
|
|
48
|
+
if (key.length === 0) return false;
|
|
49
|
+
for (const char of key) if (!PIN_ORDER_DIGITS.includes(char)) return false;
|
|
50
|
+
return key.at(-1) !== PIN_ORDER_DIGITS[0];
|
|
51
|
+
}
|
|
52
|
+
/** Midpoint of two digit strings interpreted as fractions in (0, 1).
|
|
53
|
+
"" stands for the open bound on either side. Requires a < b. */
|
|
54
|
+
function pinOrderMidpoint(a, b) {
|
|
55
|
+
if (b !== "" && a >= b) throw new Error("pinOrderMidpoint: bounds out of order");
|
|
56
|
+
if (b !== "") {
|
|
57
|
+
let n = 0;
|
|
58
|
+
while ((a.charAt(n) || PIN_ORDER_DIGITS[0]) === b.charAt(n)) n += 1;
|
|
59
|
+
if (n > 0) return b.slice(0, n) + pinOrderMidpoint(a.slice(n), b.slice(n));
|
|
60
|
+
}
|
|
61
|
+
const digitA = a === "" ? 0 : PIN_ORDER_DIGITS.indexOf(a.charAt(0));
|
|
62
|
+
const digitB = b === "" ? 26 : PIN_ORDER_DIGITS.indexOf(b.charAt(0));
|
|
63
|
+
if (digitB - digitA > 1) return PIN_ORDER_DIGITS.charAt(Math.round((digitA + digitB) / 2));
|
|
64
|
+
if (b.length > 1) return b.charAt(0);
|
|
65
|
+
return PIN_ORDER_DIGITS.charAt(digitA) + pinOrderMidpoint(a.slice(1), "");
|
|
66
|
+
}
|
|
67
|
+
/** Key that sorts strictly between two neighbors; null bounds mean "top of
|
|
68
|
+
the pinned block" / "bottom of the keyed run". Returns null instead of
|
|
69
|
+
throwing when existing keys are corrupt or out of order — callers fall
|
|
70
|
+
back to rewriting the section. */
|
|
71
|
+
function pinOrderKeyBetween(before, after) {
|
|
72
|
+
const a = before ?? "";
|
|
73
|
+
const b = after ?? "";
|
|
74
|
+
if (a !== "" && !isValidPinOrderKey(a)) return null;
|
|
75
|
+
if (b !== "" && !isValidPinOrderKey(b)) return null;
|
|
76
|
+
if (b !== "" && a >= b) return null;
|
|
77
|
+
return pinOrderMidpoint(a, b);
|
|
78
|
+
}
|
|
79
|
+
/** Evenly spaced keys for rewriting a whole pinned section (used when a
|
|
80
|
+
drop lands next to keyless threads, so single-key insertion has nothing
|
|
81
|
+
to anchor on). Two base-26 digits give 675 slots — far beyond any real
|
|
82
|
+
pinned section — with monotonicity enforced as a belt-and-braces. */
|
|
83
|
+
function generateSpreadPinOrderKeys(count) {
|
|
84
|
+
const space = 676;
|
|
85
|
+
const step = space / (count + 1);
|
|
86
|
+
const keys = [];
|
|
87
|
+
let previous = 0;
|
|
88
|
+
for (let i = 0; i < count; i += 1) {
|
|
89
|
+
let value = Math.max(Math.round(step * (i + 1)), previous + 1);
|
|
90
|
+
if (value % 26 === 0) value += 1;
|
|
91
|
+
value = Math.min(value, space - 1);
|
|
92
|
+
previous = value;
|
|
93
|
+
keys.push(PIN_ORDER_DIGITS.charAt(Math.floor(value / 26)) + PIN_ORDER_DIGITS.charAt(value % 26));
|
|
94
|
+
}
|
|
95
|
+
return keys;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Assignments needed to realize a new pinned order. When the moved thread
|
|
99
|
+
* sits between two keyed (or absent) neighbors, this is a single write to
|
|
100
|
+
* the moved thread. When a neighbor is keyless (threads pinned before
|
|
101
|
+
* reordering shipped), the whole section gets fresh spread keys — a
|
|
102
|
+
* one-time materialization; every move after that is single-write.
|
|
103
|
+
*/
|
|
104
|
+
function planPinnedReorder(input) {
|
|
105
|
+
const { orderedIds, keysById, movedId } = input;
|
|
106
|
+
const movedIndex = orderedIds.indexOf(movedId);
|
|
107
|
+
if (movedIndex === -1) return [];
|
|
108
|
+
const beforeId = movedIndex > 0 ? orderedIds[movedIndex - 1] : null;
|
|
109
|
+
const afterId = movedIndex < orderedIds.length - 1 ? orderedIds[movedIndex + 1] : null;
|
|
110
|
+
const beforeKey = beforeId != null ? keysById.get(beforeId) ?? null : null;
|
|
111
|
+
const afterKey = afterId != null ? keysById.get(afterId) ?? null : null;
|
|
112
|
+
if ((beforeId === null || beforeKey != null) && (afterId === null || afterKey != null)) {
|
|
113
|
+
const key = pinOrderKeyBetween(beforeKey, afterKey);
|
|
114
|
+
if (key !== null) return [{
|
|
115
|
+
id: movedId,
|
|
116
|
+
orderKey: key
|
|
117
|
+
}];
|
|
118
|
+
}
|
|
119
|
+
const keys = generateSpreadPinOrderKeys(orderedIds.length);
|
|
120
|
+
return orderedIds.flatMap((id, index) => {
|
|
121
|
+
const key = keys[index];
|
|
122
|
+
return keysById.get(id) === key ? [] : [{
|
|
123
|
+
id,
|
|
124
|
+
orderKey: key
|
|
125
|
+
}];
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Pinned block order: user-arranged keys first (string comparison, id
|
|
130
|
+
* tiebreak), then keyless threads newest-created first — so threads on
|
|
131
|
+
* servers that predate reordering keep the static creation order at the
|
|
132
|
+
* bottom of the block instead of breaking the section.
|
|
133
|
+
*/
|
|
134
|
+
function sortPinnedThreadsByOrderKey(threads) {
|
|
135
|
+
const keyed = [];
|
|
136
|
+
const keyless = [];
|
|
137
|
+
for (const thread of threads) (thread.pinOrderKey != null ? keyed : keyless).push(thread);
|
|
138
|
+
const identityTiebreak = (left, right) => left.id.localeCompare(right.id) || (left.environmentId ?? "").localeCompare(right.environmentId ?? "");
|
|
139
|
+
keyed.sort((left, right) => {
|
|
140
|
+
const leftKey = left.pinOrderKey;
|
|
141
|
+
const rightKey = right.pinOrderKey;
|
|
142
|
+
return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : identityTiebreak(left, right);
|
|
143
|
+
});
|
|
144
|
+
keyless.sort((left, right) => {
|
|
145
|
+
const leftMs = Date.parse(left.createdAt);
|
|
146
|
+
const rightMs = Date.parse(right.createdAt);
|
|
147
|
+
return (Number.isNaN(rightMs) ? 0 : rightMs) - (Number.isNaN(leftMs) ? 0 : leftMs) || identityTiebreak(left, right);
|
|
148
|
+
});
|
|
149
|
+
return [...keyed, ...keyless];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* planPinnedReorder specialized for mobile's Move up / Move down menu
|
|
153
|
+
* actions: swap the moved thread with its displayed neighbor. Null when the
|
|
154
|
+
* move falls off either end of the list. Same single-write-per-move
|
|
155
|
+
* semantics as a web drag.
|
|
156
|
+
*/
|
|
157
|
+
function planPinnedMove(input) {
|
|
158
|
+
const { orderedIds, keysById, movedId, direction } = input;
|
|
159
|
+
const from = orderedIds.indexOf(movedId);
|
|
160
|
+
if (from === -1) return null;
|
|
161
|
+
const to = direction === "up" ? from - 1 : from + 1;
|
|
162
|
+
if (to < 0 || to >= orderedIds.length) return null;
|
|
163
|
+
const newOrder = [...orderedIds];
|
|
164
|
+
newOrder.splice(from, 1);
|
|
165
|
+
newOrder.splice(to, 0, movedId);
|
|
166
|
+
return planPinnedReorder({
|
|
167
|
+
orderedIds: newOrder,
|
|
168
|
+
keysById,
|
|
169
|
+
movedId
|
|
170
|
+
});
|
|
171
|
+
}
|
|
46
172
|
//#endregion
|
|
47
|
-
export { getLatestThreadForProject, getThreadSortTimestamp, sortThreads, toSortableTimestamp };
|
|
173
|
+
export { generateSpreadPinOrderKeys, getLatestThreadForProject, getThreadSortTimestamp, pinOrderKeyBetween, planPinnedMove, planPinnedReorder, sortPinnedThreadsByOrderKey, sortThreads, toSortableTimestamp };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $
|
|
1
|
+
import { $O as EnvironmentAuthorizationError, Aa as EnvironmentSupervisor, At as UnarchiveThreadInput, Ay as OrchestrationDispatchCommandError, By as OrchestrationGetTurnDiffResult, Ct as RevertThreadCheckpointInput, Da as EnvironmentNotRegisteredError, Dt as SnoozeThreadInput, Et as SettleThreadInput, Ft as UpdateThreadMetadataInput, Ia as EnvironmentCacheStore, Iy as OrchestrationGetFullThreadDiffResult, Mt as UnsettleThreadInput, Nk as ThreadId, Nt as UnsnoozeThreadInput, Oa as EnvironmentRegistry, Ot as StartThreadTurnInput, St as RespondToThreadUserInputInput, Tt as SetThreadRuntimeModeInput, _t as DeleteThreadInput, ab as OrchestrationShellSnapshot, bt as ReorderPinnedThreadInput, ct as EnvironmentThreadShell, f as AtomCommand, hn as EnvironmentRpcUnavailableError, ht as CreateThreadInput, jt as UnpinThreadInput, jy as OrchestrationEvent, kt as StopThreadSessionInput, lO as ScopedProjectRef, mb as OrchestrationThreadDetailSnapshot, ms as PreparedConnection, no as RemoteEnvironmentRequestError, pt as ArchiveThreadInput, st as EnvironmentThread, u as EnvironmentCatalogState, uO as ScopedThreadRef, ub as OrchestrationThread, vk as EnvironmentId, vt as InterruptThreadTurnInput, wo as ManagedRelayDpopSigner, wt as SetThreadInteractionModeInput, xt as RespondToThreadApprovalInput, yt as PinThreadInput } from "../../shared.js";
|
|
2
2
|
import * as Context from "effect/Context";
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
4
|
import * as Stream from "effect/Stream";
|
|
@@ -15,11 +15,21 @@ import { AsyncResult, Atom } from "effect/unstable/reactivity";
|
|
|
15
15
|
* WebSocket subscription's first frame. The response is gzip-compressible by
|
|
16
16
|
* the transport and keeps the (potentially multi-KB) snapshot off the socket.
|
|
17
17
|
*/
|
|
18
|
+
/**
|
|
19
|
+
* Optional turn window for a snapshot fetch. Only send a window to servers
|
|
20
|
+
* that advertise `threadSnapshotPagination`; older servers reject unknown
|
|
21
|
+
* query parameters.
|
|
22
|
+
*/
|
|
23
|
+
interface ThreadSnapshotWindow {
|
|
24
|
+
readonly turnLimit: number;
|
|
25
|
+
readonly beforeCursor?: string;
|
|
26
|
+
}
|
|
18
27
|
declare const fetchEnvironmentThreadSnapshot: (input: {
|
|
19
28
|
readonly prepared: PreparedConnection;
|
|
20
29
|
readonly threadId: ThreadId;
|
|
21
30
|
readonly signer: Option.Option<ManagedRelayDpopSigner["Service"]>;
|
|
22
31
|
readonly timeoutMs?: number;
|
|
32
|
+
readonly window?: ThreadSnapshotWindow;
|
|
23
33
|
}) => Effect.Effect<{
|
|
24
34
|
readonly snapshotSequence: number;
|
|
25
35
|
readonly thread: {
|
|
@@ -57,6 +67,12 @@ declare const fetchEnvironmentThreadSnapshot: (input: {
|
|
|
57
67
|
readonly settledAt: string | null;
|
|
58
68
|
readonly snoozedUntil?: string | null | undefined;
|
|
59
69
|
readonly snoozedAt?: string | null | undefined;
|
|
70
|
+
readonly pinnedAt?: string | null | undefined;
|
|
71
|
+
readonly pinOrderKey?: string | null | undefined;
|
|
72
|
+
readonly titleRegeneration?: {
|
|
73
|
+
readonly requestId: string & import("effect/Brand").Brand<"CommandId">;
|
|
74
|
+
readonly startedAt: string;
|
|
75
|
+
} | null | undefined;
|
|
60
76
|
readonly deletedAt: string | null;
|
|
61
77
|
readonly messages: readonly {
|
|
62
78
|
readonly id: string & import("effect/Brand").Brand<"MessageId">;
|
|
@@ -118,10 +134,16 @@ declare const fetchEnvironmentThreadSnapshot: (input: {
|
|
|
118
134
|
readonly updatedAt: string;
|
|
119
135
|
} | null;
|
|
120
136
|
};
|
|
137
|
+
readonly page?: {
|
|
138
|
+
readonly beforeCursor: string | null;
|
|
139
|
+
readonly hasMore: boolean;
|
|
140
|
+
readonly snapshotSequence: number;
|
|
141
|
+
readonly threadSequence?: number;
|
|
142
|
+
} | undefined;
|
|
121
143
|
}, RemoteEnvironmentRequestError, HttpClient.HttpClient>;
|
|
122
144
|
type FetchEnvironmentThreadSnapshotError = RemoteEnvironmentRequestError;
|
|
123
145
|
declare const ThreadSnapshotLoader_base: Context.ServiceClass<ThreadSnapshotLoader, "@t3tools/client-runtime/state/threadSnapshotHttp/ThreadSnapshotLoader", {
|
|
124
|
-
readonly load: (prepared: PreparedConnection, threadId: ThreadId) => Effect.Effect<Option.Option<OrchestrationThreadDetailSnapshot>>;
|
|
146
|
+
readonly load: (prepared: PreparedConnection, threadId: ThreadId, window?: ThreadSnapshotWindow) => Effect.Effect<Option.Option<OrchestrationThreadDetailSnapshot>>;
|
|
125
147
|
}>;
|
|
126
148
|
/**
|
|
127
149
|
* Loads a thread's detail snapshot over HTTP, returning `Option.none()` when it
|
|
@@ -134,12 +156,28 @@ declare const threadSnapshotLoaderLayer: Layer.Layer<ThreadSnapshotLoader, never
|
|
|
134
156
|
//#endregion
|
|
135
157
|
//#region upstream-t3code/packages/client-runtime/src/state/threadState.d.ts
|
|
136
158
|
type EnvironmentThreadStatus = "empty" | "cached" | "synchronizing" | "live" | "deleted";
|
|
159
|
+
/**
|
|
160
|
+
* Pagination state for a windowed thread. Present only when the loaded thread
|
|
161
|
+
* is a window (the server returned `page` metadata); absent means the thread is
|
|
162
|
+
* fully loaded — either the server predates pagination or the window reached
|
|
163
|
+
* the top.
|
|
164
|
+
*/
|
|
165
|
+
interface EnvironmentThreadPageState {
|
|
166
|
+
/** Opaque exclusive cursor for the next older slice; null when fully loaded. */
|
|
167
|
+
readonly beforeCursor: string | null;
|
|
168
|
+
readonly hasMore: boolean;
|
|
169
|
+
/** True while an older page fetch is in flight. */
|
|
170
|
+
readonly loadingOlder: boolean;
|
|
171
|
+
}
|
|
137
172
|
interface EnvironmentThreadState {
|
|
138
173
|
readonly data: Option.Option<OrchestrationThread>;
|
|
139
174
|
readonly status: EnvironmentThreadStatus;
|
|
140
175
|
readonly error: Option.Option<string>;
|
|
176
|
+
readonly page: Option.Option<EnvironmentThreadPageState>;
|
|
141
177
|
}
|
|
142
178
|
declare const EMPTY_ENVIRONMENT_THREAD_STATE: EnvironmentThreadState;
|
|
179
|
+
/** Whether the thread has older turns that can be loaded with more pages. */
|
|
180
|
+
declare function threadHasOlderTurns(state: EnvironmentThreadState): boolean;
|
|
143
181
|
//#endregion
|
|
144
182
|
//#region upstream-t3code/packages/client-runtime/src/state/archivedThreads.d.ts
|
|
145
183
|
interface ArchivedSnapshotEntry {
|
|
@@ -241,6 +279,24 @@ declare function createThreadEnvironmentAtoms<R, E>(runtime: Atom.AtomRuntime<En
|
|
|
241
279
|
}, {
|
|
242
280
|
readonly sequence: number;
|
|
243
281
|
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | OrchestrationDispatchCommandError | import("effect/unstable/rpc/RpcClientError").RpcClientError>;
|
|
282
|
+
pin: AtomCommand<{
|
|
283
|
+
readonly environmentId: EnvironmentId;
|
|
284
|
+
readonly input: PinThreadInput;
|
|
285
|
+
}, {
|
|
286
|
+
readonly sequence: number;
|
|
287
|
+
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | OrchestrationDispatchCommandError | import("effect/unstable/rpc/RpcClientError").RpcClientError>;
|
|
288
|
+
unpin: AtomCommand<{
|
|
289
|
+
readonly environmentId: EnvironmentId;
|
|
290
|
+
readonly input: UnpinThreadInput;
|
|
291
|
+
}, {
|
|
292
|
+
readonly sequence: number;
|
|
293
|
+
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | OrchestrationDispatchCommandError | import("effect/unstable/rpc/RpcClientError").RpcClientError>;
|
|
294
|
+
reorderPin: AtomCommand<{
|
|
295
|
+
readonly environmentId: EnvironmentId;
|
|
296
|
+
readonly input: ReorderPinnedThreadInput;
|
|
297
|
+
}, {
|
|
298
|
+
readonly sequence: number;
|
|
299
|
+
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | OrchestrationDispatchCommandError | import("effect/unstable/rpc/RpcClientError").RpcClientError>;
|
|
244
300
|
updateMetadata: AtomCommand<{
|
|
245
301
|
readonly environmentId: EnvironmentId;
|
|
246
302
|
readonly input: UpdateThreadMetadataInput;
|
|
@@ -446,6 +502,12 @@ declare function createEnvironmentThreadShellAtoms(input: {
|
|
|
446
502
|
readonly settledAt: string | null;
|
|
447
503
|
readonly snoozedUntil?: string | null | undefined;
|
|
448
504
|
readonly snoozedAt?: string | null | undefined;
|
|
505
|
+
readonly pinnedAt?: string | null | undefined;
|
|
506
|
+
readonly pinOrderKey?: string | null | undefined;
|
|
507
|
+
readonly titleRegeneration?: {
|
|
508
|
+
readonly requestId: string & import("effect/Brand").Brand<"CommandId">;
|
|
509
|
+
readonly startedAt: string;
|
|
510
|
+
} | null | undefined;
|
|
449
511
|
readonly session: {
|
|
450
512
|
readonly threadId: string & import("effect/Brand").Brand<"ThreadId">;
|
|
451
513
|
readonly status: "error" | "idle" | "interrupted" | "ready" | "running" | "starting" | "stopped";
|
|
@@ -460,6 +522,12 @@ declare function createEnvironmentThreadShellAtoms(input: {
|
|
|
460
522
|
readonly hasPendingApprovals: boolean;
|
|
461
523
|
readonly hasPendingUserInput: boolean;
|
|
462
524
|
readonly hasActionableProposedPlan: boolean;
|
|
525
|
+
readonly backgroundLiveness?: "monitoring" | "working" | null | undefined;
|
|
526
|
+
readonly planProgress?: {
|
|
527
|
+
readonly step: string;
|
|
528
|
+
readonly completedSteps: number;
|
|
529
|
+
readonly totalSteps: number;
|
|
530
|
+
} | null | undefined;
|
|
463
531
|
}[]>;
|
|
464
532
|
environmentThreadIndexAtom: (arg: string & import("effect/Brand").Brand<"EnvironmentId">) => Atom.Atom<ReadonlyMap<string & import("effect/Brand").Brand<"ThreadId">, {
|
|
465
533
|
readonly id: string & import("effect/Brand").Brand<"ThreadId">;
|
|
@@ -496,6 +564,12 @@ declare function createEnvironmentThreadShellAtoms(input: {
|
|
|
496
564
|
readonly settledAt: string | null;
|
|
497
565
|
readonly snoozedUntil?: string | null | undefined;
|
|
498
566
|
readonly snoozedAt?: string | null | undefined;
|
|
567
|
+
readonly pinnedAt?: string | null | undefined;
|
|
568
|
+
readonly pinOrderKey?: string | null | undefined;
|
|
569
|
+
readonly titleRegeneration?: {
|
|
570
|
+
readonly requestId: string & import("effect/Brand").Brand<"CommandId">;
|
|
571
|
+
readonly startedAt: string;
|
|
572
|
+
} | null | undefined;
|
|
499
573
|
readonly session: {
|
|
500
574
|
readonly threadId: string & import("effect/Brand").Brand<"ThreadId">;
|
|
501
575
|
readonly status: "error" | "idle" | "interrupted" | "ready" | "running" | "starting" | "stopped";
|
|
@@ -510,6 +584,12 @@ declare function createEnvironmentThreadShellAtoms(input: {
|
|
|
510
584
|
readonly hasPendingApprovals: boolean;
|
|
511
585
|
readonly hasPendingUserInput: boolean;
|
|
512
586
|
readonly hasActionableProposedPlan: boolean;
|
|
587
|
+
readonly backgroundLiveness?: "monitoring" | "working" | null | undefined;
|
|
588
|
+
readonly planProgress?: {
|
|
589
|
+
readonly step: string;
|
|
590
|
+
readonly completedSteps: number;
|
|
591
|
+
readonly totalSteps: number;
|
|
592
|
+
} | null | undefined;
|
|
513
593
|
}>>;
|
|
514
594
|
environmentThreadRefsAtom: (arg: string & import("effect/Brand").Brand<"EnvironmentId">) => Atom.Atom<readonly {
|
|
515
595
|
readonly environmentId: string & import("effect/Brand").Brand<"EnvironmentId">;
|
|
@@ -529,10 +609,42 @@ declare function createEnvironmentThreadShellAtoms(input: {
|
|
|
529
609
|
};
|
|
530
610
|
//#endregion
|
|
531
611
|
//#region upstream-t3code/packages/client-runtime/src/state/threads.d.ts
|
|
612
|
+
/**
|
|
613
|
+
* Turn window sizes for paginated thread loads: the initial page covers the
|
|
614
|
+
* last 10 user-anchored turns (subagent/fan-out turns ride along), each
|
|
615
|
+
* "load earlier" tap fetches 20 more. Sized so first paint on the heaviest
|
|
616
|
+
* observed threads stays around 100K gzipped while median threads load fully.
|
|
617
|
+
*/
|
|
618
|
+
declare const INITIAL_THREAD_USER_TURN_LIMIT = 10;
|
|
619
|
+
declare const OLDER_THREAD_PAGE_USER_TURN_LIMIT = 20;
|
|
620
|
+
interface ThreadOlderTurnRequestRegistry {
|
|
621
|
+
/**
|
|
622
|
+
* Registers the live state machine for a thread. Returns the deregistration
|
|
623
|
+
* cleanup; registration lives exactly as long as the machine's scope, and a
|
|
624
|
+
* successor machine for the same thread simply replaces the entry.
|
|
625
|
+
*/
|
|
626
|
+
readonly register: (key: string, handler: () => void) => () => void;
|
|
627
|
+
readonly request: (key: string) => boolean;
|
|
628
|
+
}
|
|
629
|
+
declare const ThreadOlderTurnRequests_base: Context.Reference<ThreadOlderTurnRequestRegistry>;
|
|
630
|
+
/**
|
|
631
|
+
* Channel from UI actions to the live per-thread state machines. The machines
|
|
632
|
+
* resolve it from the Effect environment (overridable in tests); the default
|
|
633
|
+
* instance is shared with the sync `requestOlderThreadTurns` entry point so
|
|
634
|
+
* the apps get working wiring without providing anything.
|
|
635
|
+
*/
|
|
636
|
+
declare class ThreadOlderTurnRequests extends ThreadOlderTurnRequests_base {}
|
|
637
|
+
/**
|
|
638
|
+
* Asks the live state machine for `threadId` to fetch the next older page.
|
|
639
|
+
* Returns false when no machine is live or no fetch was started (no cursor,
|
|
640
|
+
* already loading); callers render from `EnvironmentThreadState.page` and can
|
|
641
|
+
* treat false as "nothing to do".
|
|
642
|
+
*/
|
|
643
|
+
declare function requestOlderThreadTurns(environmentId: EnvironmentId, threadId: ThreadId): boolean;
|
|
532
644
|
declare const makeEnvironmentThreadState: (threadId: string & import("effect/Brand").Brand<"ThreadId">) => Effect.Effect<SubscriptionRef.SubscriptionRef<EnvironmentThreadState>, never, EnvironmentCacheStore | EnvironmentSupervisor | import("effect/Scope").Scope | ThreadSnapshotLoader>;
|
|
533
645
|
declare function threadStateChanges(environmentId: EnvironmentId, threadId: ThreadId): Stream.Stream<EnvironmentThreadState, never, EnvironmentCacheStore | EnvironmentRegistry | ThreadSnapshotLoader>;
|
|
534
646
|
declare function createEnvironmentThreadStateAtoms<R, E>(runtime: Atom.AtomRuntime<EnvironmentRegistry | EnvironmentCacheStore | ThreadSnapshotLoader | R, E>): {
|
|
535
647
|
stateAtom: (environmentId: EnvironmentId, threadId: ThreadId) => Atom.Atom<import("effect/unstable/reactivity/AsyncResult").AsyncResult<EnvironmentThreadState, E | Cause.NoSuchElementError>>;
|
|
536
648
|
};
|
|
537
649
|
//#endregion
|
|
538
|
-
export { type ArchiveThreadInput, ArchivedSnapshotEntry, ArchivedThreadSnapshotsState, CheckpointDiffResult, CheckpointDiffState, CheckpointDiffTarget, ComposerPathSearchEntry, ComposerPathSearchState, ComposerPathSearchTarget, type CreateThreadInput, type DeleteThreadInput, EMPTY_ENVIRONMENT_THREAD_STATE, EnvironmentThreadState, EnvironmentThreadStatus, FetchEnvironmentThreadSnapshotError, type InterruptThreadTurnInput, type RespondToThreadApprovalInput, type RespondToThreadUserInputInput, type RevertThreadCheckpointInput, type SetThreadInteractionModeInput, type SetThreadRuntimeModeInput, type SettleThreadInput, type SnoozeThreadInput, type StartThreadTurnInput, type StopThreadSessionInput, ThreadDetailReducerResult, ThreadSnapshotLoader, type UnarchiveThreadInput, type UnsettleThreadInput, type UnsnoozeThreadInput, type UpdateThreadMetadataInput, applyThreadDetailEvent, createArchivedThreadSnapshotsAtomFamily, createEnvironmentThreadDetailAtoms, createEnvironmentThreadShellAtoms, createEnvironmentThreadStateAtoms, createThreadEnvironmentAtoms, fetchEnvironmentThreadSnapshot, makeArchivedThreadsEnvironmentKey, makeEnvironmentThreadState, mergeEnvironmentThread, parseArchivedThreadsEnvironmentKey, threadSnapshotLoaderLayer, threadStateChanges };
|
|
650
|
+
export { type ArchiveThreadInput, ArchivedSnapshotEntry, ArchivedThreadSnapshotsState, CheckpointDiffResult, CheckpointDiffState, CheckpointDiffTarget, ComposerPathSearchEntry, ComposerPathSearchState, ComposerPathSearchTarget, type CreateThreadInput, type DeleteThreadInput, EMPTY_ENVIRONMENT_THREAD_STATE, EnvironmentThreadPageState, EnvironmentThreadState, EnvironmentThreadStatus, FetchEnvironmentThreadSnapshotError, INITIAL_THREAD_USER_TURN_LIMIT, type InterruptThreadTurnInput, OLDER_THREAD_PAGE_USER_TURN_LIMIT, type PinThreadInput, type ReorderPinnedThreadInput, type RespondToThreadApprovalInput, type RespondToThreadUserInputInput, type RevertThreadCheckpointInput, type SetThreadInteractionModeInput, type SetThreadRuntimeModeInput, type SettleThreadInput, type SnoozeThreadInput, type StartThreadTurnInput, type StopThreadSessionInput, ThreadDetailReducerResult, ThreadOlderTurnRequests, ThreadSnapshotLoader, ThreadSnapshotWindow, type UnarchiveThreadInput, type UnpinThreadInput, type UnsettleThreadInput, type UnsnoozeThreadInput, type UpdateThreadMetadataInput, applyThreadDetailEvent, createArchivedThreadSnapshotsAtomFamily, createEnvironmentThreadDetailAtoms, createEnvironmentThreadShellAtoms, createEnvironmentThreadStateAtoms, createThreadEnvironmentAtoms, fetchEnvironmentThreadSnapshot, makeArchivedThreadsEnvironmentKey, makeEnvironmentThreadState, mergeEnvironmentThread, parseArchivedThreadsEnvironmentKey, requestOlderThreadTurns, threadHasOlderTurns, threadSnapshotLoaderLayer, threadStateChanges };
|