t3code-cli 0.12.0 → 0.14.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 +87 -1
- package/dist/application.d.ts +2 -0
- package/dist/application.js +1 -1
- package/dist/auth.d.ts +50 -0
- package/dist/auth.js +1 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +392 -630
- package/dist/cli.d.ts +66 -0
- package/dist/cli.js +1 -1
- package/dist/client-runtime/authorization.d.ts +2 -0
- package/dist/client-runtime/authorization.js +2 -0
- package/dist/client-runtime/connection.d.ts +2 -0
- package/dist/client-runtime/connection.js +2 -0
- package/dist/client-runtime/environment.d.ts +57 -0
- package/dist/client-runtime/environment.js +2 -0
- package/dist/client-runtime/errors.d.ts +28 -0
- package/dist/client-runtime/errors.js +35 -0
- package/dist/client-runtime/operations/projects.d.ts +2 -0
- package/dist/client-runtime/operations/projects.js +2 -0
- package/dist/client-runtime/operations.d.ts +2 -0
- package/dist/client-runtime/operations.js +2 -0
- package/dist/client-runtime/platform.d.ts +26 -0
- package/dist/client-runtime/platform.js +74 -0
- package/dist/client-runtime/relay.d.ts +121 -0
- package/dist/client-runtime/relay.js +245 -0
- package/dist/client-runtime/rpc.d.ts +2 -0
- package/dist/client-runtime/rpc.js +2 -0
- package/dist/client-runtime/state/assets.d.ts +40 -0
- package/dist/client-runtime/state/assets.js +53 -0
- package/dist/client-runtime/state/auth.d.ts +98 -0
- package/dist/client-runtime/state/auth.js +48 -0
- package/dist/client-runtime/state/connections.d.ts +2 -0
- package/dist/client-runtime/state/connections.js +52 -0
- package/dist/client-runtime/state/entities.d.ts +33 -0
- package/dist/client-runtime/state/entities.js +2 -0
- package/dist/client-runtime/state/filesystem.d.ts +42 -0
- package/dist/client-runtime/state/filesystem.js +48 -0
- package/dist/client-runtime/state/git.d.ts +43 -0
- package/dist/client-runtime/state/git.js +18 -0
- package/dist/client-runtime/state/models.d.ts +2 -0
- package/dist/client-runtime/state/models.js +2 -0
- package/dist/client-runtime/state/orchestration.d.ts +128 -0
- package/dist/client-runtime/state/orchestration.js +20 -0
- package/dist/client-runtime/state/presentation.d.ts +277 -0
- package/dist/client-runtime/state/presentation.js +34 -0
- package/dist/client-runtime/state/preview.d.ts +447 -0
- package/dist/client-runtime/state/preview.js +103 -0
- package/dist/client-runtime/state/project-grouping.d.ts +26 -0
- package/dist/client-runtime/state/project-grouping.js +73 -0
- package/dist/client-runtime/state/projects.d.ts +192 -0
- package/dist/client-runtime/state/projects.js +2 -0
- package/dist/client-runtime/state/relay.d.ts +10 -0
- package/dist/client-runtime/state/relay.js +19 -0
- package/dist/client-runtime/state/review.d.ts +28 -0
- package/dist/client-runtime/state/review.js +11 -0
- package/dist/client-runtime/state/runtime.d.ts +2 -0
- package/dist/client-runtime/state/runtime.js +2 -0
- package/dist/client-runtime/state/server.d.ts +1495 -0
- package/dist/client-runtime/state/server.js +207 -0
- package/dist/client-runtime/state/session.d.ts +532 -0
- package/dist/client-runtime/state/session.js +21 -0
- package/dist/client-runtime/state/shell.d.ts +529 -0
- package/dist/client-runtime/state/shell.js +2 -0
- package/dist/client-runtime/state/source-control.d.ts +92 -0
- package/dist/client-runtime/state/source-control.js +36 -0
- package/dist/client-runtime/state/terminal.d.ts +237 -0
- package/dist/client-runtime/state/terminal.js +173 -0
- package/dist/client-runtime/state/thread-settled.d.ts +104 -0
- package/dist/client-runtime/state/thread-settled.js +157 -0
- package/dist/client-runtime/state/thread-sort.d.ts +23 -0
- package/dist/client-runtime/state/thread-sort.js +47 -0
- package/dist/client-runtime/state/threads.d.ts +538 -0
- package/dist/client-runtime/state/threads.js +934 -0
- package/dist/client-runtime/state/vcs.d.ts +442 -0
- package/dist/client-runtime/state/vcs.js +756 -0
- package/dist/config.d.ts +84 -0
- package/dist/config.js +1 -1
- package/dist/connection.d.ts +7 -0
- package/dist/connection.js +1 -1
- package/dist/contracts.d.ts +2 -0
- package/dist/contracts.js +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/node.d.ts +6 -0
- package/dist/node.js +1 -1
- package/dist/orchestration.d.ts +1420 -0
- package/dist/orchestration.js +1 -1
- package/dist/preview.d.ts +2 -0
- package/dist/preview.js +2 -0
- package/dist/rolldown-runtime.js +1 -1
- package/dist/rpc.d.ts +6043 -0
- package/dist/rpc.js +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +2 -2
- package/dist/shared/DrainableWorker.d.ts +28 -0
- package/dist/shared/DrainableWorker.js +24 -0
- package/dist/shared/KeyedCoalescingWorker.d.ts +13 -0
- package/dist/shared/KeyedCoalescingWorker.js +89 -0
- package/dist/shared/Net.d.ts +43 -0
- package/dist/shared/Net.js +126 -0
- package/dist/shared/String.d.ts +4 -0
- package/dist/shared/String.js +8 -0
- package/dist/shared/Struct.d.ts +5 -0
- package/dist/shared/Struct.js +2 -0
- package/dist/shared/advertisedEndpoint.d.ts +2 -0
- package/dist/shared/advertisedEndpoint.js +2 -0
- package/dist/shared/agentAwareness.d.ts +27 -0
- package/dist/shared/agentAwareness.js +54 -0
- package/dist/shared/backgroundActivitySettings.d.ts +23 -0
- package/dist/shared/backgroundActivitySettings.js +2 -0
- package/dist/shared/chatList.d.ts +12 -0
- package/dist/shared/chatList.js +14 -0
- package/dist/shared/cliArgs.d.ts +33 -0
- package/dist/shared/cliArgs.js +103 -0
- package/dist/shared/composerInlineTokens.d.ts +20 -0
- package/dist/shared/composerInlineTokens.js +72 -0
- package/dist/shared/composerTrigger.d.ts +26 -0
- package/dist/shared/composerTrigger.js +97 -0
- package/dist/shared/connectAuth.d.ts +58 -0
- package/dist/shared/connectAuth.js +89 -0
- package/dist/shared/devHome.d.ts +21 -0
- package/dist/shared/devHome.js +65 -0
- package/dist/shared/devProxy.d.ts +15 -0
- package/dist/shared/devProxy.js +22 -0
- package/dist/shared/dpop.d.ts +32 -0
- package/dist/shared/dpop.js +2724 -0
- package/dist/shared/dpopCommon.d.ts +2 -0
- package/dist/shared/dpopCommon.js +2 -0
- package/dist/shared/filePreview.d.ts +8 -0
- package/dist/shared/filePreview.js +31 -0
- package/dist/shared/git.d.ts +41 -0
- package/dist/shared/git.js +2 -0
- package/dist/shared/hostProcess.d.ts +13 -0
- package/dist/shared/hostProcess.js +2 -0
- package/dist/shared/httpObservability.d.ts +5 -0
- package/dist/shared/httpObservability.js +2 -0
- package/dist/shared/httpReadiness.d.ts +38 -0
- package/dist/shared/httpReadiness.js +110 -0
- package/dist/shared/keybindings.d.ts +35 -0
- package/dist/shared/keybindings.js +330 -0
- package/dist/shared/logging.d.ts +39 -0
- package/dist/shared/logging.js +2 -0
- package/dist/shared/model.d.ts +44 -0
- package/dist/shared/model.js +2 -0
- package/dist/shared/oauthScope.d.ts +23 -0
- package/dist/shared/oauthScope.js +2 -0
- package/dist/shared/observability.d.ts +105 -0
- package/dist/shared/observability.js +346 -0
- package/dist/shared/orchestrationTiming.d.ts +16 -0
- package/dist/shared/orchestrationTiming.js +32 -0
- package/dist/shared/path.d.ts +2 -0
- package/dist/shared/path.js +2 -0
- package/dist/shared/preview.d.ts +35 -0
- package/dist/shared/preview.js +103 -0
- package/dist/shared/previewViewport.d.ts +16 -0
- package/dist/shared/previewViewport.js +159 -0
- package/dist/shared/projectFavicon.d.ts +5 -0
- package/dist/shared/projectFavicon.js +13 -0
- package/dist/shared/projectScripts.d.ts +19 -0
- package/dist/shared/projectScripts.js +18 -0
- package/dist/shared/qrCode.d.ts +87 -0
- package/dist/shared/qrCode.js +870 -0
- package/dist/shared/relayAuth.d.ts +27 -0
- package/dist/shared/relayAuth.js +83 -0
- package/dist/shared/relayClient.d.ts +58 -0
- package/dist/shared/relayClient.js +245 -0
- package/dist/shared/relayJwt.d.ts +39 -0
- package/dist/shared/relayJwt.js +2 -0
- package/dist/shared/relaySigning.d.ts +4 -0
- package/dist/shared/relaySigning.js +2 -0
- package/dist/shared/relayTracing.d.ts +25 -0
- package/dist/shared/relayTracing.js +2 -0
- package/dist/shared/relayUrl.d.ts +5 -0
- package/dist/shared/relayUrl.js +2 -0
- package/dist/shared/remote.d.ts +57 -0
- package/dist/shared/remote.js +2 -0
- package/dist/shared/schemaJson.d.ts +35 -0
- package/dist/shared/schemaJson.js +2 -0
- package/dist/shared/schemaYaml.d.ts +86 -0
- package/dist/shared/schemaYaml.js +99 -0
- package/dist/shared/searchRanking.d.ts +30 -0
- package/dist/shared/searchRanking.js +99 -0
- package/dist/shared/semver.d.ts +23 -0
- package/dist/shared/semver.js +124 -0
- package/dist/shared/serverSettings.d.ts +19 -0
- package/dist/shared/serverSettings.js +103 -0
- package/dist/shared/shell.d.ts +51 -0
- package/dist/shared/shell.js +408 -0
- package/dist/shared/sourceControl.d.ts +26 -0
- package/dist/shared/sourceControl.js +2 -0
- package/dist/shared/t3ProjectFile.d.ts +27 -0
- package/dist/shared/t3ProjectFile.js +25 -0
- package/dist/shared/terminalLabels.d.ts +16 -0
- package/dist/shared/terminalLabels.js +28 -0
- package/dist/shared/toolActivity.d.ts +16 -0
- package/dist/shared/toolActivity.js +159 -0
- package/dist/shared.d.ts +43036 -0
- package/dist/shared.js +36722 -13117
- package/dist/t3tools.d.ts +2 -0
- package/dist/t3tools.js +2 -2
- package/package.json +46 -27
- package/src/application/thread-wait.ts +4 -0
- package/src/auth/error.ts +2 -8
- package/src/auth/index.ts +2 -0
- package/src/auth/pairing.ts +8 -5
- package/src/auth/remote-error.ts +17 -0
- package/src/auth/service.ts +2 -1
- package/src/auth/transport.ts +49 -114
- package/src/auth/type.ts +6 -0
- package/src/cli/auth.ts +7 -1
- package/src/connection/error.ts +4 -1
- package/src/connection/layer.ts +5 -2
- package/src/connection/prepared.ts +83 -0
- package/src/contracts/index.ts +8 -0
- package/src/orchestration/layer.ts +38 -1
- package/src/orchestration/service.ts +5 -0
- package/src/preview/index.ts +11 -0
- package/src/preview/service.ts +52 -0
- package/src/rpc/error.ts +11 -16
- package/src/rpc/index.ts +3 -2
- package/src/rpc/layer.ts +18 -51
- package/src/rpc/operation.ts +21 -6
- package/src/rpc/service.ts +2 -1
- package/src/rpc/session.ts +168 -0
- package/src/rpc/ws-group.ts +18 -26
- package/src/runtime/index.ts +1 -0
- package/src/runtime/layer.ts +11 -3
- package/src/sql/node-sqlite-client.ts +3 -0
- package/dist/src/application/actions.d.ts +0 -25
- package/dist/src/application/error.d.ts +0 -3
- package/dist/src/application/index.d.ts +0 -4
- package/dist/src/application/layer.d.ts +0 -117
- package/dist/src/application/model-selection.d.ts +0 -34
- package/dist/src/application/models.d.ts +0 -8
- package/dist/src/application/project-commands.d.ts +0 -44
- package/dist/src/application/projects.d.ts +0 -23
- package/dist/src/application/service.d.ts +0 -243
- package/dist/src/application/shell-sequence.d.ts +0 -101
- package/dist/src/application/terminals.d.ts +0 -66
- package/dist/src/application/thread-commands.d.ts +0 -157
- package/dist/src/application/thread-update.d.ts +0 -8
- package/dist/src/application/thread-wait.d.ts +0 -111
- package/dist/src/application/threads.d.ts +0 -685
- package/dist/src/auth/error.d.ts +0 -51
- package/dist/src/auth/index.d.ts +0 -10
- package/dist/src/auth/layer.d.ts +0 -53
- package/dist/src/auth/local-base-dir.d.ts +0 -8
- package/dist/src/auth/local-origin.d.ts +0 -18
- package/dist/src/auth/local-token.d.ts +0 -26
- package/dist/src/auth/local.d.ts +0 -24
- package/dist/src/auth/pairing.d.ts +0 -22
- package/dist/src/auth/schema.d.ts +0 -58
- package/dist/src/auth/service.d.ts +0 -27
- package/dist/src/auth/transport.d.ts +0 -22
- package/dist/src/auth/type.d.ts +0 -83
- package/dist/src/cli/env/flag.d.ts +0 -2
- package/dist/src/cli/env/index.d.ts +0 -2
- package/dist/src/cli/env/selection-layer.d.ts +0 -3
- package/dist/src/cli/flags.d.ts +0 -20
- package/dist/src/cli/format/index.d.ts +0 -1
- package/dist/src/cli/format/output.d.ts +0 -12
- package/dist/src/cli/index.d.ts +0 -5
- package/dist/src/cli/runtime/index.d.ts +0 -1
- package/dist/src/cli/runtime/service.d.ts +0 -16
- package/dist/src/cli/scope/index.d.ts +0 -1
- package/dist/src/cli/scope/resolve.d.ts +0 -20
- package/dist/src/cli-path/layer.d.ts +0 -3
- package/dist/src/cli-path/service.d.ts +0 -8
- package/dist/src/config/config.d.ts +0 -49
- package/dist/src/config/credential/cipher-node.d.ts +0 -3
- package/dist/src/config/credential/cipher-web.d.ts +0 -3
- package/dist/src/config/credential/cipher.d.ts +0 -29
- package/dist/src/config/credential/env.d.ts +0 -3
- package/dist/src/config/credential/error.d.ts +0 -8
- package/dist/src/config/credential/index.d.ts +0 -6
- package/dist/src/config/credential/service.d.ts +0 -34
- package/dist/src/config/env/env.d.ts +0 -55
- package/dist/src/config/env/index.d.ts +0 -2
- package/dist/src/config/env/layout.d.ts +0 -11
- package/dist/src/config/environment-name/index.d.ts +0 -1
- package/dist/src/config/environment-name/name.d.ts +0 -10
- package/dist/src/config/error.d.ts +0 -11
- package/dist/src/config/index.d.ts +0 -10
- package/dist/src/config/keystore/error.d.ts +0 -8
- package/dist/src/config/keystore/file.d.ts +0 -9
- package/dist/src/config/keystore/index.d.ts +0 -4
- package/dist/src/config/keystore/keyring-node.d.ts +0 -4
- package/dist/src/config/keystore/service.d.ts +0 -33
- package/dist/src/config/paths/index.d.ts +0 -1
- package/dist/src/config/paths/paths.d.ts +0 -6
- package/dist/src/config/persist/file-mode.d.ts +0 -4
- package/dist/src/config/persist/migration.d.ts +0 -68
- package/dist/src/config/persist/persist.d.ts +0 -40
- package/dist/src/config/persist/schema.d.ts +0 -68
- package/dist/src/config/resolve/resolve.d.ts +0 -40
- package/dist/src/config/selection/index.d.ts +0 -1
- package/dist/src/config/selection/resolve.d.ts +0 -4
- package/dist/src/config/selection/service.d.ts +0 -10
- package/dist/src/config/types.d.ts +0 -36
- package/dist/src/config/url/error.d.ts +0 -10
- package/dist/src/config/url/index.d.ts +0 -2
- package/dist/src/config/url/url.d.ts +0 -6
- package/dist/src/connection/error.d.ts +0 -8
- package/dist/src/connection/index.d.ts +0 -4
- package/dist/src/connection/layer.d.ts +0 -3
- package/dist/src/connection/service.d.ts +0 -13
- package/dist/src/connection/type.d.ts +0 -10
- package/dist/src/contracts/index.d.ts +0 -1
- package/dist/src/domain/error.d.ts +0 -57
- package/dist/src/domain/helpers.d.ts +0 -184
- package/dist/src/domain/model-config.d.ts +0 -325
- package/dist/src/domain/thread-activities.d.ts +0 -14
- package/dist/src/domain/thread-lifecycle.d.ts +0 -125
- package/dist/src/index.d.ts +0 -3
- package/dist/src/node/connection.d.ts +0 -2
- package/dist/src/node/index.d.ts +0 -1
- package/dist/src/orchestration/index.d.ts +0 -2
- package/dist/src/orchestration/layer.d.ts +0 -1634
- package/dist/src/orchestration/service.d.ts +0 -28
- package/dist/src/rpc/error.d.ts +0 -18
- package/dist/src/rpc/index.d.ts +0 -5
- package/dist/src/rpc/layer.d.ts +0 -6271
- package/dist/src/rpc/operation.d.ts +0 -6280
- package/dist/src/rpc/service.d.ts +0 -15
- package/dist/src/rpc/ws-group.d.ts +0 -2725
- package/dist/src/runtime/index.d.ts +0 -1
- package/dist/src/runtime/layer.d.ts +0 -15
- package/dist/src/sql/node-sqlite-client.d.ts +0 -10
- package/dist/src/sql/service.d.ts +0 -17
- package/dist/src/t3tools/index.d.ts +0 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { $T as ThreadId, Hb as TerminalCwdNotDirectoryError, Jb as TerminalMetadataStreamEvent, Rb as TerminalAttachStreamEvent, Ub as TerminalCwdNotFoundError, Wb as TerminalCwdStatError, Yb as TerminalNotRunningError, Zb as TerminalResizeError, bT as EnvironmentAuthorizationError, f as AtomCommand, ha as EnvironmentRegistry, ix as TerminalSummary, ma as EnvironmentNotRegisteredError, nx as TerminalSessionSnapshot, on as EnvironmentRpcUnavailableError, ox as TerminalWriteError, qb as TerminalHistoryError, tx as TerminalSessionLookupError, zT as EnvironmentId } from "../../shared.js";
|
|
2
|
+
import { Atom } from "effect/unstable/reactivity";
|
|
3
|
+
//#region upstream-t3code/packages/client-runtime/src/state/terminalSession.d.ts
|
|
4
|
+
interface TerminalSessionState {
|
|
5
|
+
readonly summary: TerminalSummary | null;
|
|
6
|
+
readonly buffer: string;
|
|
7
|
+
readonly status: TerminalSessionSnapshot["status"] | "closed";
|
|
8
|
+
readonly error: string | null;
|
|
9
|
+
readonly hasRunningSubprocess: boolean;
|
|
10
|
+
readonly updatedAt: string | null;
|
|
11
|
+
readonly version: number;
|
|
12
|
+
}
|
|
13
|
+
interface TerminalBufferState {
|
|
14
|
+
readonly buffer: string;
|
|
15
|
+
readonly status: TerminalSessionSnapshot["status"] | "closed";
|
|
16
|
+
readonly error: string | null;
|
|
17
|
+
readonly updatedAt: string | null;
|
|
18
|
+
readonly version: number;
|
|
19
|
+
}
|
|
20
|
+
interface KnownTerminalSessionTarget {
|
|
21
|
+
readonly environmentId: EnvironmentId;
|
|
22
|
+
readonly threadId: ThreadId;
|
|
23
|
+
readonly terminalId: string;
|
|
24
|
+
}
|
|
25
|
+
interface KnownTerminalSession {
|
|
26
|
+
readonly target: KnownTerminalSessionTarget;
|
|
27
|
+
readonly state: TerminalSessionState;
|
|
28
|
+
}
|
|
29
|
+
declare function selectRunningSubprocessTerminalIds(sessions: ReadonlyArray<KnownTerminalSession>): ReadonlyArray<string>;
|
|
30
|
+
declare const EMPTY_TERMINAL_BUFFER_STATE: Readonly<TerminalBufferState>;
|
|
31
|
+
declare const EMPTY_TERMINAL_SESSION_STATE: Readonly<TerminalSessionState>;
|
|
32
|
+
declare const DEFAULT_MAX_TERMINAL_BUFFER_BYTES: number;
|
|
33
|
+
declare function terminalBufferStateFromSnapshot(snapshot: TerminalSessionSnapshot, maxBufferBytes: number): TerminalBufferState;
|
|
34
|
+
declare function combineTerminalSessionState(summary: TerminalSummary | null, buffer: TerminalBufferState): TerminalSessionState;
|
|
35
|
+
declare function applyTerminalAttachStreamEvent(current: TerminalBufferState, event: TerminalAttachStreamEvent, maxBufferBytes?: number): TerminalBufferState;
|
|
36
|
+
declare function applyTerminalMetadataStreamEvent(current: ReadonlyArray<TerminalSummary>, event: TerminalMetadataStreamEvent): ReadonlyArray<TerminalSummary>;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region upstream-t3code/packages/client-runtime/src/state/terminal.d.ts
|
|
39
|
+
declare function createTerminalEnvironmentAtoms<R, E>(runtime: Atom.AtomRuntime<EnvironmentRegistry | R, E>): {
|
|
40
|
+
attach: (target: {
|
|
41
|
+
readonly environmentId: EnvironmentId;
|
|
42
|
+
readonly input: {
|
|
43
|
+
readonly threadId: string;
|
|
44
|
+
readonly terminalId: string;
|
|
45
|
+
readonly cwd?: string | undefined;
|
|
46
|
+
readonly worktreePath?: string | null | undefined;
|
|
47
|
+
readonly cols?: number | undefined;
|
|
48
|
+
readonly rows?: number | undefined;
|
|
49
|
+
readonly env?: {
|
|
50
|
+
readonly [x: string]: string;
|
|
51
|
+
} | undefined;
|
|
52
|
+
readonly restartIfNotRunning?: boolean | undefined;
|
|
53
|
+
};
|
|
54
|
+
}) => Atom.Atom<import("effect/unstable/reactivity/AsyncResult").AsyncResult<TerminalBufferState, E | EnvironmentAuthorizationError | import("effect/Cause").NoSuchElementError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>>;
|
|
55
|
+
events: (target: {
|
|
56
|
+
readonly environmentId: EnvironmentId;
|
|
57
|
+
readonly input: import("effect/Schema").Struct.ReadonlyMakeIn<{}>;
|
|
58
|
+
}) => Atom.Atom<import("effect/unstable/reactivity/AsyncResult").AsyncResult<{
|
|
59
|
+
readonly threadId: string;
|
|
60
|
+
readonly terminalId: string;
|
|
61
|
+
readonly sequence?: number | undefined;
|
|
62
|
+
readonly type: "output";
|
|
63
|
+
readonly data: string;
|
|
64
|
+
} | {
|
|
65
|
+
readonly threadId: string;
|
|
66
|
+
readonly terminalId: string;
|
|
67
|
+
readonly sequence?: number | undefined;
|
|
68
|
+
readonly type: "exited";
|
|
69
|
+
readonly exitCode: number | null;
|
|
70
|
+
readonly exitSignal: number | null;
|
|
71
|
+
} | {
|
|
72
|
+
readonly threadId: string;
|
|
73
|
+
readonly terminalId: string;
|
|
74
|
+
readonly sequence?: number | undefined;
|
|
75
|
+
readonly type: "closed";
|
|
76
|
+
} | {
|
|
77
|
+
readonly threadId: string;
|
|
78
|
+
readonly terminalId: string;
|
|
79
|
+
readonly sequence?: number | undefined;
|
|
80
|
+
readonly type: "error";
|
|
81
|
+
readonly message: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly threadId: string;
|
|
84
|
+
readonly terminalId: string;
|
|
85
|
+
readonly sequence?: number | undefined;
|
|
86
|
+
readonly type: "cleared";
|
|
87
|
+
} | {
|
|
88
|
+
readonly threadId: string;
|
|
89
|
+
readonly terminalId: string;
|
|
90
|
+
readonly sequence?: number | undefined;
|
|
91
|
+
readonly type: "restarted";
|
|
92
|
+
readonly snapshot: {
|
|
93
|
+
readonly threadId: string;
|
|
94
|
+
readonly terminalId: string;
|
|
95
|
+
readonly cwd: string;
|
|
96
|
+
readonly worktreePath: string | null;
|
|
97
|
+
readonly status: "error" | "exited" | "running" | "starting";
|
|
98
|
+
readonly pid: number | null;
|
|
99
|
+
readonly history: string;
|
|
100
|
+
readonly exitCode: number | null;
|
|
101
|
+
readonly exitSignal: number | null;
|
|
102
|
+
readonly label: string;
|
|
103
|
+
readonly updatedAt: string;
|
|
104
|
+
readonly sequence?: number | undefined;
|
|
105
|
+
};
|
|
106
|
+
} | {
|
|
107
|
+
readonly threadId: string;
|
|
108
|
+
readonly terminalId: string;
|
|
109
|
+
readonly sequence?: number | undefined;
|
|
110
|
+
readonly type: "activity";
|
|
111
|
+
readonly hasRunningSubprocess: boolean;
|
|
112
|
+
readonly label: string;
|
|
113
|
+
} | {
|
|
114
|
+
readonly threadId: string;
|
|
115
|
+
readonly terminalId: string;
|
|
116
|
+
readonly sequence?: number | undefined;
|
|
117
|
+
readonly type: "started";
|
|
118
|
+
readonly snapshot: {
|
|
119
|
+
readonly threadId: string;
|
|
120
|
+
readonly terminalId: string;
|
|
121
|
+
readonly cwd: string;
|
|
122
|
+
readonly worktreePath: string | null;
|
|
123
|
+
readonly status: "error" | "exited" | "running" | "starting";
|
|
124
|
+
readonly pid: number | null;
|
|
125
|
+
readonly history: string;
|
|
126
|
+
readonly exitCode: number | null;
|
|
127
|
+
readonly exitSignal: number | null;
|
|
128
|
+
readonly label: string;
|
|
129
|
+
readonly updatedAt: string;
|
|
130
|
+
readonly sequence?: number | undefined;
|
|
131
|
+
};
|
|
132
|
+
}, E | EnvironmentAuthorizationError | import("effect/Cause").NoSuchElementError | import("effect/unstable/rpc/RpcClientError").RpcClientError>>;
|
|
133
|
+
metadata: (target: {
|
|
134
|
+
readonly environmentId: EnvironmentId;
|
|
135
|
+
readonly input: null;
|
|
136
|
+
}) => Atom.Atom<import("effect/unstable/reactivity/AsyncResult").AsyncResult<readonly {
|
|
137
|
+
readonly threadId: string;
|
|
138
|
+
readonly terminalId: string;
|
|
139
|
+
readonly cwd: string;
|
|
140
|
+
readonly worktreePath: string | null;
|
|
141
|
+
readonly status: "error" | "exited" | "running" | "starting";
|
|
142
|
+
readonly pid: number | null;
|
|
143
|
+
readonly exitCode: number | null;
|
|
144
|
+
readonly exitSignal: number | null;
|
|
145
|
+
readonly hasRunningSubprocess: boolean;
|
|
146
|
+
readonly label: string;
|
|
147
|
+
readonly updatedAt: string;
|
|
148
|
+
}[], E | EnvironmentAuthorizationError | import("effect/Cause").NoSuchElementError | import("effect/unstable/rpc/RpcClientError").RpcClientError>>;
|
|
149
|
+
open: AtomCommand<{
|
|
150
|
+
readonly environmentId: EnvironmentId;
|
|
151
|
+
readonly input: {
|
|
152
|
+
readonly threadId: string;
|
|
153
|
+
readonly terminalId: string;
|
|
154
|
+
readonly cwd: string;
|
|
155
|
+
readonly worktreePath?: string | null | undefined;
|
|
156
|
+
readonly cols?: number | undefined;
|
|
157
|
+
readonly rows?: number | undefined;
|
|
158
|
+
readonly env?: {
|
|
159
|
+
readonly [x: string]: string;
|
|
160
|
+
} | undefined;
|
|
161
|
+
};
|
|
162
|
+
}, {
|
|
163
|
+
readonly threadId: string;
|
|
164
|
+
readonly terminalId: string;
|
|
165
|
+
readonly cwd: string;
|
|
166
|
+
readonly worktreePath: string | null;
|
|
167
|
+
readonly status: "error" | "exited" | "running" | "starting";
|
|
168
|
+
readonly pid: number | null;
|
|
169
|
+
readonly history: string;
|
|
170
|
+
readonly exitCode: number | null;
|
|
171
|
+
readonly exitSignal: number | null;
|
|
172
|
+
readonly label: string;
|
|
173
|
+
readonly updatedAt: string;
|
|
174
|
+
readonly sequence?: number | undefined;
|
|
175
|
+
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
176
|
+
write: AtomCommand<{
|
|
177
|
+
readonly environmentId: EnvironmentId;
|
|
178
|
+
readonly input: import("effect/Schema").Struct.ReadonlyMakeIn<{
|
|
179
|
+
readonly threadId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
180
|
+
readonly terminalId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
181
|
+
readonly data: import("effect/Schema").String;
|
|
182
|
+
}>;
|
|
183
|
+
}, void, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
184
|
+
resize: AtomCommand<{
|
|
185
|
+
readonly environmentId: EnvironmentId;
|
|
186
|
+
readonly input: import("effect/Schema").Struct.ReadonlyMakeIn<{
|
|
187
|
+
readonly threadId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
188
|
+
readonly terminalId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
189
|
+
readonly cols: import("effect/Schema").Int;
|
|
190
|
+
readonly rows: import("effect/Schema").Int;
|
|
191
|
+
}>;
|
|
192
|
+
}, void, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
193
|
+
clear: AtomCommand<{
|
|
194
|
+
readonly environmentId: EnvironmentId;
|
|
195
|
+
readonly input: import("effect/Schema").Struct.ReadonlyMakeIn<{
|
|
196
|
+
readonly threadId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
197
|
+
readonly terminalId: import("effect/Schema").decodeTo<import("effect/Schema").String, import("effect/Schema").String, never, never>;
|
|
198
|
+
}>;
|
|
199
|
+
}, void, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
200
|
+
restart: AtomCommand<{
|
|
201
|
+
readonly environmentId: EnvironmentId;
|
|
202
|
+
readonly input: {
|
|
203
|
+
readonly threadId: string;
|
|
204
|
+
readonly terminalId: string;
|
|
205
|
+
readonly cwd: string;
|
|
206
|
+
readonly worktreePath?: string | null | undefined;
|
|
207
|
+
readonly cols: number;
|
|
208
|
+
readonly rows: number;
|
|
209
|
+
readonly env?: {
|
|
210
|
+
readonly [x: string]: string;
|
|
211
|
+
} | undefined;
|
|
212
|
+
};
|
|
213
|
+
}, {
|
|
214
|
+
readonly threadId: string;
|
|
215
|
+
readonly terminalId: string;
|
|
216
|
+
readonly cwd: string;
|
|
217
|
+
readonly worktreePath: string | null;
|
|
218
|
+
readonly status: "error" | "exited" | "running" | "starting";
|
|
219
|
+
readonly pid: number | null;
|
|
220
|
+
readonly history: string;
|
|
221
|
+
readonly exitCode: number | null;
|
|
222
|
+
readonly exitSignal: number | null;
|
|
223
|
+
readonly label: string;
|
|
224
|
+
readonly updatedAt: string;
|
|
225
|
+
readonly sequence?: number | undefined;
|
|
226
|
+
}, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
227
|
+
close: AtomCommand<{
|
|
228
|
+
readonly environmentId: EnvironmentId;
|
|
229
|
+
readonly input: {
|
|
230
|
+
readonly threadId: string;
|
|
231
|
+
readonly terminalId?: string | undefined;
|
|
232
|
+
readonly deleteHistory?: boolean | undefined;
|
|
233
|
+
};
|
|
234
|
+
}, void, E | EnvironmentAuthorizationError | EnvironmentNotRegisteredError | EnvironmentRpcUnavailableError | import("effect/unstable/rpc/RpcClientError").RpcClientError | TerminalCwdNotDirectoryError | TerminalCwdNotFoundError | TerminalCwdStatError | TerminalHistoryError | TerminalNotRunningError | TerminalResizeError | TerminalSessionLookupError | TerminalWriteError>;
|
|
235
|
+
};
|
|
236
|
+
//#endregion
|
|
237
|
+
export { DEFAULT_MAX_TERMINAL_BUFFER_BYTES, EMPTY_TERMINAL_BUFFER_STATE, EMPTY_TERMINAL_SESSION_STATE, KnownTerminalSession, KnownTerminalSessionTarget, TerminalBufferState, TerminalSessionState, applyTerminalAttachStreamEvent, applyTerminalMetadataStreamEvent, combineTerminalSessionState, createTerminalEnvironmentAtoms, selectRunningSubprocessTerminalIds, terminalBufferStateFromSnapshot };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Fs as WS_METHODS, Ur as subscribe, dr as createEnvironmentRpcCommand, hr as createEnvironmentSubscriptionAtomFamily, iD as scan, lr as createAtomCommandScheduler, mr as createEnvironmentRpcSubscriptionAtomFamily } from "../../shared.js";
|
|
2
|
+
//#region upstream-t3code/packages/client-runtime/src/state/terminalSession.ts
|
|
3
|
+
function selectRunningSubprocessTerminalIds(sessions) {
|
|
4
|
+
return sessions.filter((session) => session.state.hasRunningSubprocess).map((session) => session.target.terminalId);
|
|
5
|
+
}
|
|
6
|
+
const EMPTY_TERMINAL_BUFFER_STATE = Object.freeze({
|
|
7
|
+
buffer: "",
|
|
8
|
+
status: "closed",
|
|
9
|
+
error: null,
|
|
10
|
+
updatedAt: null,
|
|
11
|
+
version: 0
|
|
12
|
+
});
|
|
13
|
+
const EMPTY_TERMINAL_SESSION_STATE = Object.freeze({
|
|
14
|
+
summary: null,
|
|
15
|
+
buffer: "",
|
|
16
|
+
status: "closed",
|
|
17
|
+
error: null,
|
|
18
|
+
hasRunningSubprocess: false,
|
|
19
|
+
updatedAt: null,
|
|
20
|
+
version: 0
|
|
21
|
+
});
|
|
22
|
+
const DEFAULT_MAX_TERMINAL_BUFFER_BYTES = 512 * 1024;
|
|
23
|
+
const textEncoder = new TextEncoder();
|
|
24
|
+
const textDecoder = new TextDecoder();
|
|
25
|
+
function trimBufferToBytes(buffer, maxBufferBytes) {
|
|
26
|
+
if (maxBufferBytes <= 0) return "";
|
|
27
|
+
const encoded = textEncoder.encode(buffer);
|
|
28
|
+
if (encoded.byteLength <= maxBufferBytes) return buffer;
|
|
29
|
+
let start = encoded.byteLength - maxBufferBytes;
|
|
30
|
+
while (start < encoded.length) {
|
|
31
|
+
const byte = encoded[start];
|
|
32
|
+
if (byte === void 0 || (byte & 192) !== 128) break;
|
|
33
|
+
start += 1;
|
|
34
|
+
}
|
|
35
|
+
return textDecoder.decode(encoded.subarray(start));
|
|
36
|
+
}
|
|
37
|
+
function terminalBufferStateFromSnapshot(snapshot, maxBufferBytes) {
|
|
38
|
+
return {
|
|
39
|
+
buffer: trimBufferToBytes(snapshot.history, maxBufferBytes),
|
|
40
|
+
status: snapshot.status,
|
|
41
|
+
error: null,
|
|
42
|
+
updatedAt: snapshot.updatedAt,
|
|
43
|
+
version: 1
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function latestTimestamp(left, right) {
|
|
47
|
+
if (left === null) return right;
|
|
48
|
+
if (right === null) return left;
|
|
49
|
+
return Date.parse(left) >= Date.parse(right) ? left : right;
|
|
50
|
+
}
|
|
51
|
+
function combineTerminalSessionState(summary, buffer) {
|
|
52
|
+
return {
|
|
53
|
+
summary,
|
|
54
|
+
buffer: buffer.buffer,
|
|
55
|
+
status: buffer.version > 0 ? buffer.status : summary?.status ?? buffer.status,
|
|
56
|
+
error: buffer.error,
|
|
57
|
+
hasRunningSubprocess: summary?.hasRunningSubprocess ?? false,
|
|
58
|
+
updatedAt: latestTimestamp(summary?.updatedAt ?? null, buffer.updatedAt),
|
|
59
|
+
version: buffer.version
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function applyTerminalAttachStreamEvent(current, event, maxBufferBytes = DEFAULT_MAX_TERMINAL_BUFFER_BYTES) {
|
|
63
|
+
switch (event.type) {
|
|
64
|
+
case "snapshot":
|
|
65
|
+
case "restarted": return terminalBufferStateFromSnapshot(event.snapshot, maxBufferBytes);
|
|
66
|
+
case "output": return {
|
|
67
|
+
...current,
|
|
68
|
+
buffer: trimBufferToBytes(`${current.buffer}${event.data}`, maxBufferBytes),
|
|
69
|
+
status: current.status === "closed" ? "running" : current.status,
|
|
70
|
+
error: null,
|
|
71
|
+
version: current.version + 1
|
|
72
|
+
};
|
|
73
|
+
case "cleared": return {
|
|
74
|
+
...current,
|
|
75
|
+
buffer: "",
|
|
76
|
+
error: null,
|
|
77
|
+
version: current.version + 1
|
|
78
|
+
};
|
|
79
|
+
case "exited": return {
|
|
80
|
+
...current,
|
|
81
|
+
status: "exited",
|
|
82
|
+
error: null,
|
|
83
|
+
version: current.version + 1
|
|
84
|
+
};
|
|
85
|
+
case "closed": return {
|
|
86
|
+
...current,
|
|
87
|
+
status: "closed",
|
|
88
|
+
error: null,
|
|
89
|
+
version: current.version + 1
|
|
90
|
+
};
|
|
91
|
+
case "error": return {
|
|
92
|
+
...current,
|
|
93
|
+
status: "error",
|
|
94
|
+
error: event.message,
|
|
95
|
+
version: current.version + 1
|
|
96
|
+
};
|
|
97
|
+
case "activity": return current;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function applyTerminalMetadataStreamEvent(current, event) {
|
|
101
|
+
if (event.type === "snapshot") return event.terminals;
|
|
102
|
+
if (event.type === "remove") return current.filter((terminal) => terminal.threadId !== event.threadId || terminal.terminalId !== event.terminalId);
|
|
103
|
+
return [...current.filter((terminal) => terminal.threadId !== event.terminal.threadId || terminal.terminalId !== event.terminal.terminalId), event.terminal];
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region upstream-t3code/packages/client-runtime/src/state/terminal.ts
|
|
107
|
+
function createTerminalEnvironmentAtoms(runtime) {
|
|
108
|
+
const lifecycleScheduler = createAtomCommandScheduler();
|
|
109
|
+
const resizeScheduler = createAtomCommandScheduler();
|
|
110
|
+
const terminalThreadKey = ({ environmentId, input }) => JSON.stringify([environmentId, input.threadId]);
|
|
111
|
+
const terminalSessionKey = ({ environmentId, input }) => JSON.stringify([
|
|
112
|
+
environmentId,
|
|
113
|
+
input.threadId,
|
|
114
|
+
input.terminalId ?? null
|
|
115
|
+
]);
|
|
116
|
+
const lifecycleConcurrency = {
|
|
117
|
+
mode: "serial",
|
|
118
|
+
key: terminalThreadKey
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
attach: createEnvironmentSubscriptionAtomFamily(runtime, {
|
|
122
|
+
label: "environment-data:terminal:attach",
|
|
123
|
+
subscribe: (input) => subscribe(WS_METHODS.terminalAttach, input).pipe(scan(EMPTY_TERMINAL_BUFFER_STATE, applyTerminalAttachStreamEvent))
|
|
124
|
+
}),
|
|
125
|
+
events: createEnvironmentRpcSubscriptionAtomFamily(runtime, {
|
|
126
|
+
label: "environment-data:terminal:events",
|
|
127
|
+
tag: WS_METHODS.subscribeTerminalEvents
|
|
128
|
+
}),
|
|
129
|
+
metadata: createEnvironmentSubscriptionAtomFamily(runtime, {
|
|
130
|
+
label: "environment-data:terminal:metadata",
|
|
131
|
+
subscribe: (_input) => subscribe(WS_METHODS.subscribeTerminalMetadata, {}).pipe(scan([], applyTerminalMetadataStreamEvent))
|
|
132
|
+
}),
|
|
133
|
+
open: createEnvironmentRpcCommand(runtime, {
|
|
134
|
+
label: "environment-data:terminal:open",
|
|
135
|
+
tag: WS_METHODS.terminalOpen,
|
|
136
|
+
scheduler: lifecycleScheduler,
|
|
137
|
+
concurrency: lifecycleConcurrency
|
|
138
|
+
}),
|
|
139
|
+
write: createEnvironmentRpcCommand(runtime, {
|
|
140
|
+
label: "environment-data:terminal:write",
|
|
141
|
+
tag: WS_METHODS.terminalWrite
|
|
142
|
+
}),
|
|
143
|
+
resize: createEnvironmentRpcCommand(runtime, {
|
|
144
|
+
label: "environment-data:terminal:resize",
|
|
145
|
+
tag: WS_METHODS.terminalResize,
|
|
146
|
+
scheduler: resizeScheduler,
|
|
147
|
+
concurrency: {
|
|
148
|
+
mode: "latest",
|
|
149
|
+
key: terminalSessionKey
|
|
150
|
+
}
|
|
151
|
+
}),
|
|
152
|
+
clear: createEnvironmentRpcCommand(runtime, {
|
|
153
|
+
label: "environment-data:terminal:clear",
|
|
154
|
+
tag: WS_METHODS.terminalClear,
|
|
155
|
+
scheduler: lifecycleScheduler,
|
|
156
|
+
concurrency: lifecycleConcurrency
|
|
157
|
+
}),
|
|
158
|
+
restart: createEnvironmentRpcCommand(runtime, {
|
|
159
|
+
label: "environment-data:terminal:restart",
|
|
160
|
+
tag: WS_METHODS.terminalRestart,
|
|
161
|
+
scheduler: lifecycleScheduler,
|
|
162
|
+
concurrency: lifecycleConcurrency
|
|
163
|
+
}),
|
|
164
|
+
close: createEnvironmentRpcCommand(runtime, {
|
|
165
|
+
label: "environment-data:terminal:close",
|
|
166
|
+
tag: WS_METHODS.terminalClose,
|
|
167
|
+
scheduler: lifecycleScheduler,
|
|
168
|
+
concurrency: lifecycleConcurrency
|
|
169
|
+
})
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
export { DEFAULT_MAX_TERMINAL_BUFFER_BYTES, EMPTY_TERMINAL_BUFFER_STATE, EMPTY_TERMINAL_SESSION_STATE, applyTerminalAttachStreamEvent, applyTerminalMetadataStreamEvent, combineTerminalSessionState, createTerminalEnvironmentAtoms, selectRunningSubprocessTerminalIds, terminalBufferStateFromSnapshot };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { _v as OrchestrationThreadShell } from "../../shared.js";
|
|
2
|
+
//#region upstream-t3code/packages/client-runtime/src/state/threadSettled.d.ts
|
|
3
|
+
type ChangeRequestStateLike = "open" | "closed" | "merged";
|
|
4
|
+
declare function threadLastActivityAt(shell: OrchestrationThreadShell): string | null;
|
|
5
|
+
/**
|
|
6
|
+
* A queued turn start lives for at most this long: session adoption takes
|
|
7
|
+
* seconds, so a user message still unadopted after the grace window is a
|
|
8
|
+
* failed start (or stale data — shells from older servers can carry user
|
|
9
|
+
* messages with no latestTurn at all), not pending work. Without this bound
|
|
10
|
+
* such threads would be permanently unsettleable.
|
|
11
|
+
*/
|
|
12
|
+
declare const QUEUED_TURN_START_GRACE_MS: number;
|
|
13
|
+
/**
|
|
14
|
+
* A user message no turn has picked up yet: the turn.start command was
|
|
15
|
+
* dispatched (message-sent + turn-start-requested) but no session has
|
|
16
|
+
* adopted it, so `session` is still null and the pending work is invisible
|
|
17
|
+
* to the session-status checks. Detectable as a user message strictly newer
|
|
18
|
+
* than every timestamp on the latest turn — on adoption the new turn's
|
|
19
|
+
* requestedAt equals the message time, clearing the condition — and only
|
|
20
|
+
* within the adoption grace window.
|
|
21
|
+
*/
|
|
22
|
+
declare function hasQueuedTurnStart(shell: Pick<OrchestrationThreadShell, "latestUserMessageAt" | "latestTurn" | "session">, options: {
|
|
23
|
+
readonly now: string;
|
|
24
|
+
}): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* A thread may be settled only when none of effectiveSettled's activity
|
|
27
|
+
* blockers hold. This is deliberately the same list: anything the partition
|
|
28
|
+
* refuses to CLASSIFY as settled must also be refused as a settle TARGET.
|
|
29
|
+
* The server enforces its own invariants; this client-side twin exists so
|
|
30
|
+
* the UI can disable/reject before a round trip.
|
|
31
|
+
*/
|
|
32
|
+
declare function canSettle(shell: Pick<OrchestrationThreadShell, "hasPendingApprovals" | "hasPendingUserInput" | "session" | "latestUserMessageAt" | "latestTurn">, options: {
|
|
33
|
+
readonly now: string;
|
|
34
|
+
}): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The snooze lifecycle fields plus everything needed to detect a raised
|
|
37
|
+
* hand. Snooze is an overlay on the active state: a snoozed thread stays
|
|
38
|
+
* "active" in the data model and is only suppressed from the inbox until
|
|
39
|
+
* its wake time passes or the thread demands attention.
|
|
40
|
+
*/
|
|
41
|
+
type ThreadSnoozeShell = Pick<OrchestrationThreadShell, "snoozedUntil" | "snoozedAt" | "hasPendingApprovals" | "hasPendingUserInput" | "session" | "latestTurn">;
|
|
42
|
+
/**
|
|
43
|
+
* A snoozed thread "raises its hand" when something happens that outranks
|
|
44
|
+
* the user's snooze: the agent is blocked on them (approval / user input),
|
|
45
|
+
* the session failed, or a run completed after the snooze was set — the
|
|
46
|
+
* v1 taste of event-based snooze ("something happened" wakes early).
|
|
47
|
+
* Raising a hand never clears the server-side snooze fields; it only stops
|
|
48
|
+
* the thread from CLASSIFYING as snoozed, exactly like blocked work and
|
|
49
|
+
* effectiveSettled.
|
|
50
|
+
*/
|
|
51
|
+
declare function threadRaisedHandWhileSnoozed(shell: ThreadSnoozeShell): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* A thread may be snoozed unless the agent is blocked on the user: hiding a
|
|
54
|
+
* pending approval or user-input request defeats the request, and a queued
|
|
55
|
+
* turn start (a message no turn has adopted yet) is invisible pending work
|
|
56
|
+
* the same way it is for settle. A running session IS snoozable — snooze
|
|
57
|
+
* only affects visibility, never the agent. Client-side twin of the server
|
|
58
|
+
* invariants so the UI can reject before a round trip.
|
|
59
|
+
*/
|
|
60
|
+
declare function canSnooze(shell: Pick<OrchestrationThreadShell, "hasPendingApprovals" | "hasPendingUserInput" | "latestUserMessageAt" | "latestTurn" | "session">, options: {
|
|
61
|
+
readonly now: string;
|
|
62
|
+
}): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Snoozed resolution: hidden from the inbox while the wake time is in the
|
|
65
|
+
* future and the thread has not raised its hand. Timer wakes are derived —
|
|
66
|
+
* no server event fires when snoozedUntil passes; the stale fields simply
|
|
67
|
+
* stop classifying as snoozed (and feed the woke indicator until the user
|
|
68
|
+
* visits or re-engages).
|
|
69
|
+
*/
|
|
70
|
+
declare function effectiveSnoozed(shell: ThreadSnoozeShell, options: {
|
|
71
|
+
readonly now: string;
|
|
72
|
+
}): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* When a previously-snoozed thread woke, or null if it never snoozed / is
|
|
75
|
+
* still snoozed. Used for the "Woke" indicator: the thread reappears in its
|
|
76
|
+
* original sort position (the inbox sort is deliberately static), so the
|
|
77
|
+
* wake signal has to carry the weight. Compare against the client's
|
|
78
|
+
* lastVisitedAt — visiting clears the indicator like it clears unread.
|
|
79
|
+
*
|
|
80
|
+
* Timer wakes report the wake time itself; raised-hand wakes report the
|
|
81
|
+
* triggering timestamp so a visit BEFORE the early wake doesn't suppress
|
|
82
|
+
* the indicator.
|
|
83
|
+
*/
|
|
84
|
+
declare function threadWokeAt(shell: ThreadSnoozeShell, options: {
|
|
85
|
+
readonly now: string;
|
|
86
|
+
}): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Settled resolution over the server-backed settled lifecycle. Activity
|
|
89
|
+
* blockers (pending approval/user-input, a live session, an unadjudicated
|
|
90
|
+
* queued turn) are checked first and hold a thread active regardless of any
|
|
91
|
+
* override. Past the blockers, the explicit user override (thread.settle /
|
|
92
|
+
* thread.unsettle commands, projected into settledOverride + settledAt)
|
|
93
|
+
* wins in both directions; without one, a thread auto-settles on a
|
|
94
|
+
* merged/closed PR immediately or on inactivity past the window. The server
|
|
95
|
+
* un-settles on real activity (user message, session start, approval/
|
|
96
|
+
* user-input request), so an override never goes stale silently.
|
|
97
|
+
*/
|
|
98
|
+
declare function effectiveSettled(shell: OrchestrationThreadShell, options: {
|
|
99
|
+
readonly now: string;
|
|
100
|
+
readonly autoSettleAfterDays: number | null;
|
|
101
|
+
readonly changeRequestState?: ChangeRequestStateLike | null;
|
|
102
|
+
}): boolean;
|
|
103
|
+
//#endregion
|
|
104
|
+
export { ChangeRequestStateLike, QUEUED_TURN_START_GRACE_MS, ThreadSnoozeShell, canSettle, canSnooze, effectiveSettled, effectiveSnoozed, hasQueuedTurnStart, threadLastActivityAt, threadRaisedHandWhileSnoozed, threadWokeAt };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
//#region upstream-t3code/packages/client-runtime/src/state/threadSettled.ts
|
|
2
|
+
const DAY_MS = 1440 * 60 * 1e3;
|
|
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 };
|