t3code-cli 0.13.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 +348 -603
- 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/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 +25428 -12277
- package/dist/t3tools.d.ts +2 -0
- package/dist/t3tools.js +1 -1
- package/package.json +39 -21
- package/src/auth/index.ts +2 -0
- package/src/auth/pairing.ts +8 -5
- package/src/auth/service.ts +2 -1
- package/src/auth/transport.ts +4 -0
- package/src/auth/type.ts +6 -0
- package/src/cli/auth.ts +7 -1
- package/src/contracts/index.ts +8 -0
- package/src/orchestration/layer.ts +36 -0
- 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 +2 -0
- package/src/rpc/layer.ts +5 -4
- package/src/rpc/operation.ts +5 -4
- package/src/rpc/ws-group.ts +6 -0
- package/src/runtime/index.ts +1 -0
- package/src/runtime/layer.ts +5 -0
- 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 -96
- 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 -106
- package/dist/src/application/threads.d.ts +0 -660
- package/dist/src/auth/error.d.ts +0 -50
- 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/remote-error.d.ts +0 -3
- 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 -10
- package/dist/src/connection/index.d.ts +0 -4
- package/dist/src/connection/layer.d.ts +0 -3
- package/dist/src/connection/prepared.d.ts +0 -14
- 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 -179
- package/dist/src/domain/model-config.d.ts +0 -330
- package/dist/src/domain/thread-activities.d.ts +0 -14
- package/dist/src/domain/thread-lifecycle.d.ts +0 -120
- 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 -1419
- package/dist/src/orchestration/service.d.ts +0 -28
- package/dist/src/rpc/error.d.ts +0 -16
- package/dist/src/rpc/index.d.ts +0 -6
- package/dist/src/rpc/layer.d.ts +0 -5862
- package/dist/src/rpc/operation.d.ts +0 -24
- package/dist/src/rpc/service.d.ts +0 -15
- package/dist/src/rpc/session.d.ts +0 -22
- package/dist/src/rpc/ws-group.d.ts +0 -1984
- 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,756 @@
|
|
|
1
|
+
import { $D as flatMap, $r as failure, AO as tapError, Aa as EnvironmentSupervisor, Cv as get, DO as suspend, Dk as seconds, Dr as runStreamInEnvironment, EO as succeed, Ek as min, FE as concat, Fs as WS_METHODS, GT as Defect, Gr as family, HD as as, HE as fromEffect, HO as modifyDelay, Hk as match, Hr as runStream, Hu as GitActionProgressPhase, JS as EnvironmentId, JT as Literals, Jr as setIdleTTL, KE as map, Kr as keepAlive, La as EnvironmentCacheStore, MD as nowUnsafe, ND as toEpochMillis, Na as safeErrorLogAttributes, OO as sync, PE as changes$1, Q as applyGitStatusStreamEvent, QD as fail, QT as String, RO as void_, St as vcsCommandScheduler, Sv as changes, Uk as none, Ur as subscribe, VD as annotateLogs, VE as filterMap, VO as exponential, Vr as request, Wk as some, XT as NullOr, Xr as withLabel, YD as catch_, YO as hasInterruptsOnly, ZD as ensuring, ZE as retry, ZO as squash, ZT as Number, Zr as AtomRegistry, aO as gen, bO as provideService, bk as failVoid, bt as withVcsRefsPersistenceLock, dr as createEnvironmentRpcCommand, eE as TaggedErrorClass, eO as fn, ei as isSuccess, gr as createRuntimeCommand, hr as createEnvironmentSubscriptionAtomFamily, lD as unwrap, lO as logWarning, nE as Union, oD as switchMap, oE as decodeUnknownSync, qE as mapAccum, qO as fail$1, qr as make, rt as isTemporaryWorktreeBranch, tD as runForEach, tE as Tuple, td as GitStackedAction, vt as invalidateCachedVcsRefs, wk as succeed$1, xr as followStreamInEnvironment, xt as vcsCommandConcurrency, yt as vcsRefsCacheStateAtom, zE as empty } from "../../shared.js";
|
|
2
|
+
//#region upstream-t3code/packages/client-runtime/src/state/gitActions.ts
|
|
3
|
+
function buildGitActionProgressStages(input) {
|
|
4
|
+
const branchStages = input.featureBranch ? ["Preparing feature branch..."] : [];
|
|
5
|
+
const pushStage = input.pushTarget ? `Pushing to ${input.pushTarget}...` : "Pushing...";
|
|
6
|
+
const prStages = [
|
|
7
|
+
"Preparing PR...",
|
|
8
|
+
"Generating PR content...",
|
|
9
|
+
"Creating GitHub pull request..."
|
|
10
|
+
];
|
|
11
|
+
if (input.action === "push") return [pushStage];
|
|
12
|
+
if (input.action === "create_pr") return input.shouldPushBeforePr ? [pushStage, ...prStages] : prStages;
|
|
13
|
+
const commitStages = !(input.action === "commit" || input.hasWorkingTreeChanges) ? [] : input.hasCustomCommitMessage ? ["Committing..."] : ["Generating commit message...", "Committing..."];
|
|
14
|
+
if (input.action === "commit") return [...branchStages, ...commitStages];
|
|
15
|
+
if (input.action === "commit_push") return [
|
|
16
|
+
...branchStages,
|
|
17
|
+
...commitStages,
|
|
18
|
+
pushStage
|
|
19
|
+
];
|
|
20
|
+
return [
|
|
21
|
+
...branchStages,
|
|
22
|
+
...commitStages,
|
|
23
|
+
pushStage,
|
|
24
|
+
...prStages
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
function buildMenuItems(gitStatus, isBusy, hasOriginRemote = true) {
|
|
28
|
+
if (!gitStatus) return [];
|
|
29
|
+
const hasBranch = gitStatus.refName !== null;
|
|
30
|
+
const hasChanges = gitStatus.hasWorkingTreeChanges;
|
|
31
|
+
const hasOpenPr = gitStatus.pr?.state === "open";
|
|
32
|
+
const isBehind = gitStatus.behindCount > 0;
|
|
33
|
+
const canPushWithoutUpstream = hasOriginRemote && !gitStatus.hasUpstream;
|
|
34
|
+
const canCommit = !isBusy && hasChanges;
|
|
35
|
+
const canPush = !isBusy && hasBranch && !hasChanges && !isBehind && gitStatus.aheadCount > 0 && (gitStatus.hasUpstream || canPushWithoutUpstream);
|
|
36
|
+
const canCreatePr = !isBusy && hasBranch && !hasChanges && !hasOpenPr && gitStatus.aheadCount > 0 && !isBehind && (gitStatus.hasUpstream || canPushWithoutUpstream);
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
id: "commit",
|
|
40
|
+
label: "Commit",
|
|
41
|
+
disabled: !canCommit,
|
|
42
|
+
icon: "commit",
|
|
43
|
+
kind: "open_dialog",
|
|
44
|
+
dialogAction: "commit"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "push",
|
|
48
|
+
label: "Push",
|
|
49
|
+
disabled: !canPush,
|
|
50
|
+
icon: "push",
|
|
51
|
+
kind: "open_dialog",
|
|
52
|
+
dialogAction: "push"
|
|
53
|
+
},
|
|
54
|
+
hasOpenPr ? {
|
|
55
|
+
id: "pr",
|
|
56
|
+
label: "View PR",
|
|
57
|
+
disabled: !(!isBusy && hasOpenPr),
|
|
58
|
+
icon: "pr",
|
|
59
|
+
kind: "open_pr"
|
|
60
|
+
} : {
|
|
61
|
+
id: "pr",
|
|
62
|
+
label: "Create PR",
|
|
63
|
+
disabled: !canCreatePr,
|
|
64
|
+
icon: "pr",
|
|
65
|
+
kind: "open_dialog",
|
|
66
|
+
dialogAction: "create_pr"
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
function resolveQuickAction(gitStatus, isBusy, isDefaultBranch = false, hasOriginRemote = true) {
|
|
71
|
+
if (isBusy) return {
|
|
72
|
+
label: "Commit",
|
|
73
|
+
disabled: true,
|
|
74
|
+
kind: "show_hint",
|
|
75
|
+
hint: "Git action in progress."
|
|
76
|
+
};
|
|
77
|
+
if (!gitStatus) return {
|
|
78
|
+
label: "Commit",
|
|
79
|
+
disabled: true,
|
|
80
|
+
kind: "show_hint",
|
|
81
|
+
hint: "Git status is unavailable."
|
|
82
|
+
};
|
|
83
|
+
const hasBranch = gitStatus.refName !== null;
|
|
84
|
+
const hasChanges = gitStatus.hasWorkingTreeChanges;
|
|
85
|
+
const hasOpenPr = gitStatus.pr?.state === "open";
|
|
86
|
+
const isAhead = gitStatus.aheadCount > 0;
|
|
87
|
+
const isBehind = gitStatus.behindCount > 0;
|
|
88
|
+
const isDiverged = isAhead && isBehind;
|
|
89
|
+
if (!hasBranch) return {
|
|
90
|
+
label: "Commit",
|
|
91
|
+
disabled: true,
|
|
92
|
+
kind: "show_hint",
|
|
93
|
+
hint: "Create and checkout a branch before pushing or opening a PR."
|
|
94
|
+
};
|
|
95
|
+
if (hasChanges) {
|
|
96
|
+
if (!gitStatus.hasUpstream && !hasOriginRemote) return {
|
|
97
|
+
label: "Commit",
|
|
98
|
+
disabled: false,
|
|
99
|
+
kind: "run_action",
|
|
100
|
+
action: "commit"
|
|
101
|
+
};
|
|
102
|
+
if (hasOpenPr || isDefaultBranch) return {
|
|
103
|
+
label: "Commit & push",
|
|
104
|
+
disabled: false,
|
|
105
|
+
kind: "run_action",
|
|
106
|
+
action: "commit_push"
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
label: "Commit, push & PR",
|
|
110
|
+
disabled: false,
|
|
111
|
+
kind: "run_action",
|
|
112
|
+
action: "commit_push_pr"
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (!gitStatus.hasUpstream) {
|
|
116
|
+
if (!hasOriginRemote) {
|
|
117
|
+
if (hasOpenPr && !isAhead) return {
|
|
118
|
+
label: "View PR",
|
|
119
|
+
disabled: false,
|
|
120
|
+
kind: "open_pr"
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
label: "Push",
|
|
124
|
+
disabled: true,
|
|
125
|
+
kind: "show_hint",
|
|
126
|
+
hint: "Add an \"origin\" remote before pushing or creating a PR."
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (!isAhead) {
|
|
130
|
+
if (hasOpenPr) return {
|
|
131
|
+
label: "View PR",
|
|
132
|
+
disabled: false,
|
|
133
|
+
kind: "open_pr"
|
|
134
|
+
};
|
|
135
|
+
return {
|
|
136
|
+
label: "Push",
|
|
137
|
+
disabled: true,
|
|
138
|
+
kind: "show_hint",
|
|
139
|
+
hint: "No local commits to push."
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (hasOpenPr || isDefaultBranch) return {
|
|
143
|
+
label: "Push",
|
|
144
|
+
disabled: false,
|
|
145
|
+
kind: "run_action",
|
|
146
|
+
action: isDefaultBranch ? "commit_push" : "push"
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
label: "Push & create PR",
|
|
150
|
+
disabled: false,
|
|
151
|
+
kind: "run_action",
|
|
152
|
+
action: "create_pr"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (isDiverged) return {
|
|
156
|
+
label: "Sync branch",
|
|
157
|
+
disabled: true,
|
|
158
|
+
kind: "show_hint",
|
|
159
|
+
hint: "Branch has diverged from upstream. Rebase/merge first."
|
|
160
|
+
};
|
|
161
|
+
if (isBehind) return {
|
|
162
|
+
label: "Pull",
|
|
163
|
+
disabled: false,
|
|
164
|
+
kind: "run_pull"
|
|
165
|
+
};
|
|
166
|
+
if (isAhead) {
|
|
167
|
+
if (hasOpenPr || isDefaultBranch) return {
|
|
168
|
+
label: "Push",
|
|
169
|
+
disabled: false,
|
|
170
|
+
kind: "run_action",
|
|
171
|
+
action: isDefaultBranch ? "commit_push" : "push"
|
|
172
|
+
};
|
|
173
|
+
return {
|
|
174
|
+
label: "Push & create PR",
|
|
175
|
+
disabled: false,
|
|
176
|
+
kind: "run_action",
|
|
177
|
+
action: "create_pr"
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (hasOpenPr && gitStatus.hasUpstream) return {
|
|
181
|
+
label: "View PR",
|
|
182
|
+
disabled: false,
|
|
183
|
+
kind: "open_pr"
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
label: "Commit",
|
|
187
|
+
disabled: true,
|
|
188
|
+
kind: "show_hint",
|
|
189
|
+
hint: "Branch is up to date. No action needed."
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function getGitActionDisabledReason(input) {
|
|
193
|
+
const { item, gitStatus, isBusy, hasOriginRemote } = input;
|
|
194
|
+
if (!item.disabled) return null;
|
|
195
|
+
if (isBusy) return "Git action in progress.";
|
|
196
|
+
if (!gitStatus) return "Git status is unavailable.";
|
|
197
|
+
const hasBranch = gitStatus.refName !== null;
|
|
198
|
+
const hasChanges = gitStatus.hasWorkingTreeChanges;
|
|
199
|
+
const hasOpenPr = gitStatus.pr?.state === "open";
|
|
200
|
+
const isAhead = gitStatus.aheadCount > 0;
|
|
201
|
+
const isBehind = gitStatus.behindCount > 0;
|
|
202
|
+
if (item.id === "commit") {
|
|
203
|
+
if (!hasChanges) return "Worktree is clean. Make changes before committing.";
|
|
204
|
+
return "Commit is currently unavailable.";
|
|
205
|
+
}
|
|
206
|
+
if (item.id === "push") {
|
|
207
|
+
if (!hasBranch) return "Detached HEAD: checkout a branch before pushing.";
|
|
208
|
+
if (hasChanges) return "Commit or stash local changes before pushing.";
|
|
209
|
+
if (isBehind) return "Branch is behind upstream. Pull/rebase before pushing.";
|
|
210
|
+
if (!gitStatus.hasUpstream && !hasOriginRemote) return "Add an \"origin\" remote before pushing.";
|
|
211
|
+
if (!isAhead) return "No local commits to push.";
|
|
212
|
+
return "Push is currently unavailable.";
|
|
213
|
+
}
|
|
214
|
+
if (hasOpenPr) return "View PR is currently unavailable.";
|
|
215
|
+
if (!hasBranch) return "Detached HEAD: checkout a branch before creating a PR.";
|
|
216
|
+
if (hasChanges) return "Commit local changes before creating a PR.";
|
|
217
|
+
if (!gitStatus.hasUpstream && !hasOriginRemote) return "Add an \"origin\" remote before creating a PR.";
|
|
218
|
+
if (!isAhead) return "No local commits to include in a PR.";
|
|
219
|
+
if (isBehind) return "Branch is behind upstream. Pull/rebase before creating a PR.";
|
|
220
|
+
return "Create PR is currently unavailable.";
|
|
221
|
+
}
|
|
222
|
+
function requiresDefaultBranchConfirmation(action, isDefaultBranch) {
|
|
223
|
+
if (!isDefaultBranch) return false;
|
|
224
|
+
return action === "push" || action === "create_pr" || action === "commit_push" || action === "commit_push_pr";
|
|
225
|
+
}
|
|
226
|
+
function resolveDefaultBranchActionDialogCopy(input) {
|
|
227
|
+
const branchLabel = input.branchName;
|
|
228
|
+
const suffix = ` on "${branchLabel}". You can continue on this branch or create a feature branch and run the same action there.`;
|
|
229
|
+
if (input.action === "push" || input.action === "commit_push") {
|
|
230
|
+
if (input.includesCommit) return {
|
|
231
|
+
title: "Commit & push to default branch?",
|
|
232
|
+
description: `This action will commit and push changes${suffix}`,
|
|
233
|
+
continueLabel: `Commit & push to ${branchLabel}`
|
|
234
|
+
};
|
|
235
|
+
return {
|
|
236
|
+
title: "Push to default branch?",
|
|
237
|
+
description: `This action will push local commits${suffix}`,
|
|
238
|
+
continueLabel: `Push to ${branchLabel}`
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
if (input.includesCommit) return {
|
|
242
|
+
title: "Commit, push & create PR from default branch?",
|
|
243
|
+
description: `This action will commit, push, and create a PR${suffix}`,
|
|
244
|
+
continueLabel: "Commit, push & create PR"
|
|
245
|
+
};
|
|
246
|
+
return {
|
|
247
|
+
title: "Push & create PR from default branch?",
|
|
248
|
+
description: `This action will push local commits and create a PR${suffix}`,
|
|
249
|
+
continueLabel: "Push & create PR"
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function resolveThreadBranchUpdate(result) {
|
|
253
|
+
if (result.branch.status !== "created" || !result.branch.name) return null;
|
|
254
|
+
return { branch: result.branch.name };
|
|
255
|
+
}
|
|
256
|
+
function resolveLiveThreadBranchUpdate(input) {
|
|
257
|
+
if (!input.gitStatus) return null;
|
|
258
|
+
if (input.gitStatus.refName === null && input.threadBranch !== null) return null;
|
|
259
|
+
if (input.threadBranch === input.gitStatus.refName) return null;
|
|
260
|
+
if (input.threadBranch !== null && input.gitStatus.refName !== null && !isTemporaryWorktreeBranch(input.threadBranch) && isTemporaryWorktreeBranch(input.gitStatus.refName)) return null;
|
|
261
|
+
return { branch: input.gitStatus.refName };
|
|
262
|
+
}
|
|
263
|
+
//#endregion
|
|
264
|
+
//#region upstream-t3code/packages/client-runtime/src/state/vcsAction.ts
|
|
265
|
+
const VcsActionOperation = Literals([
|
|
266
|
+
"refresh_status",
|
|
267
|
+
"run_change_request",
|
|
268
|
+
"pull",
|
|
269
|
+
"switch_ref",
|
|
270
|
+
"create_ref",
|
|
271
|
+
"create_worktree",
|
|
272
|
+
"init",
|
|
273
|
+
"publish_repository",
|
|
274
|
+
"prepare_pull_request_thread"
|
|
275
|
+
]);
|
|
276
|
+
var VcsActionUnavailableError = class extends TaggedErrorClass()("VcsActionUnavailableError", {
|
|
277
|
+
operation: VcsActionOperation,
|
|
278
|
+
environmentId: NullOr(EnvironmentId),
|
|
279
|
+
cwd: NullOr(String)
|
|
280
|
+
}) {
|
|
281
|
+
get message() {
|
|
282
|
+
return `Source control operation '${this.operation.replaceAll("_", " ")}' is unavailable.`;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
var VcsActionRemoteFailureError = class extends TaggedErrorClass()("VcsActionRemoteFailureError", {
|
|
286
|
+
actionId: String,
|
|
287
|
+
transportActionId: String,
|
|
288
|
+
action: GitStackedAction,
|
|
289
|
+
environmentId: EnvironmentId,
|
|
290
|
+
cwd: String,
|
|
291
|
+
phase: NullOr(GitActionProgressPhase),
|
|
292
|
+
remoteMessageLength: Number
|
|
293
|
+
}) {
|
|
294
|
+
get message() {
|
|
295
|
+
const phase = this.phase === null ? "execution" : this.phase;
|
|
296
|
+
return `Source control action '${this.action}' failed during ${phase}.`;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
var VcsActionMissingTerminalEventError = class extends TaggedErrorClass()("VcsActionMissingTerminalEventError", {
|
|
300
|
+
actionId: String,
|
|
301
|
+
transportActionId: String,
|
|
302
|
+
action: GitStackedAction,
|
|
303
|
+
environmentId: EnvironmentId,
|
|
304
|
+
cwd: String
|
|
305
|
+
}) {
|
|
306
|
+
get message() {
|
|
307
|
+
return `Source control action '${this.action}' ended without a terminal result.`;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
var VcsActionTargetKeyParseError = class extends TaggedErrorClass()("VcsActionTargetKeyParseError", {
|
|
311
|
+
keyLength: Number,
|
|
312
|
+
cause: Defect()
|
|
313
|
+
}) {
|
|
314
|
+
get message() {
|
|
315
|
+
return `Invalid source control action target key (${this.keyLength} characters).`;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
const VcsActionExecutionError = Union([VcsActionRemoteFailureError, VcsActionMissingTerminalEventError]);
|
|
319
|
+
const EMPTY_VCS_ACTION_STATE = Object.freeze({
|
|
320
|
+
isRunning: false,
|
|
321
|
+
operation: null,
|
|
322
|
+
actionId: null,
|
|
323
|
+
action: null,
|
|
324
|
+
currentLabel: null,
|
|
325
|
+
currentPhaseLabel: null,
|
|
326
|
+
hookName: null,
|
|
327
|
+
lastOutputLine: null,
|
|
328
|
+
phaseStartedAtMs: null,
|
|
329
|
+
hookStartedAtMs: null,
|
|
330
|
+
error: null
|
|
331
|
+
});
|
|
332
|
+
const nowMs = () => toEpochMillis(nowUnsafe());
|
|
333
|
+
let nextLocalActionId = 0;
|
|
334
|
+
const decodeVcsActionTargetKey = decodeUnknownSync(Tuple([EnvironmentId, String]));
|
|
335
|
+
const vcsActionStateAtom = family((key) => {
|
|
336
|
+
return make(EMPTY_VCS_ACTION_STATE).pipe(keepAlive, withLabel(`vcs-action:${key}`));
|
|
337
|
+
});
|
|
338
|
+
const EMPTY_VCS_ACTION_ATOM = make(EMPTY_VCS_ACTION_STATE).pipe(keepAlive, withLabel("vcs-action:null"));
|
|
339
|
+
function getVcsActionTargetKey(target) {
|
|
340
|
+
if (target.environmentId === null || target.cwd === null) return null;
|
|
341
|
+
return JSON.stringify([target.environmentId, target.cwd]);
|
|
342
|
+
}
|
|
343
|
+
function parseVcsActionTargetKey(key) {
|
|
344
|
+
try {
|
|
345
|
+
const [environmentId, cwd] = decodeVcsActionTargetKey(JSON.parse(key));
|
|
346
|
+
return {
|
|
347
|
+
environmentId,
|
|
348
|
+
cwd
|
|
349
|
+
};
|
|
350
|
+
} catch (cause) {
|
|
351
|
+
throw new VcsActionTargetKeyParseError({
|
|
352
|
+
keyLength: key.length,
|
|
353
|
+
cause
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function getVcsActionStateAtom(target) {
|
|
358
|
+
const key = getVcsActionTargetKey(target);
|
|
359
|
+
return key === null ? EMPTY_VCS_ACTION_ATOM : vcsActionStateAtom(key);
|
|
360
|
+
}
|
|
361
|
+
function createLocalActionId() {
|
|
362
|
+
nextLocalActionId += 1;
|
|
363
|
+
return `local-vcs-action:${nextLocalActionId}`;
|
|
364
|
+
}
|
|
365
|
+
function beginVcsActionState(input) {
|
|
366
|
+
const actionId = input.actionId ?? createLocalActionId();
|
|
367
|
+
const startedAt = nowMs();
|
|
368
|
+
return {
|
|
369
|
+
...EMPTY_VCS_ACTION_STATE,
|
|
370
|
+
isRunning: true,
|
|
371
|
+
operation: input.operation,
|
|
372
|
+
actionId,
|
|
373
|
+
currentLabel: input.label,
|
|
374
|
+
currentPhaseLabel: input.label,
|
|
375
|
+
phaseStartedAtMs: startedAt
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function failVcsActionState(operation, actionId, error) {
|
|
379
|
+
return {
|
|
380
|
+
...EMPTY_VCS_ACTION_STATE,
|
|
381
|
+
operation,
|
|
382
|
+
actionId,
|
|
383
|
+
error: error instanceof Error ? error.message : "Source control action failed."
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function createVcsActionTransportId(target, actionId) {
|
|
387
|
+
const targetKey = JSON.stringify([target.environmentId, target.cwd]);
|
|
388
|
+
return `${targetKey.length}:${targetKey}${actionId}`;
|
|
389
|
+
}
|
|
390
|
+
function normalizeVcsActionProgressEvent(target, transportActionId, actionId, event) {
|
|
391
|
+
if (event.actionId !== transportActionId || event.cwd !== target.cwd) return null;
|
|
392
|
+
return {
|
|
393
|
+
...event,
|
|
394
|
+
actionId
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function consumeVcsActionProgress(stream, input) {
|
|
398
|
+
return suspend(() => {
|
|
399
|
+
let terminalEvent = null;
|
|
400
|
+
return stream.pipe(runForEach((event) => {
|
|
401
|
+
const normalized = normalizeVcsActionProgressEvent(input.target, input.transportActionId, input.actionId, event);
|
|
402
|
+
if (normalized === null) return void_;
|
|
403
|
+
if (normalized.kind === "action_finished" || normalized.kind === "action_failed") terminalEvent = normalized;
|
|
404
|
+
return input.onProgress(normalized);
|
|
405
|
+
}), flatMap(() => {
|
|
406
|
+
if (terminalEvent?.kind === "action_finished") return succeed(terminalEvent.result);
|
|
407
|
+
if (terminalEvent?.kind === "action_failed") return fail(new VcsActionRemoteFailureError({
|
|
408
|
+
actionId: input.actionId,
|
|
409
|
+
transportActionId: input.transportActionId,
|
|
410
|
+
action: terminalEvent.action,
|
|
411
|
+
environmentId: input.target.environmentId,
|
|
412
|
+
cwd: input.target.cwd,
|
|
413
|
+
phase: terminalEvent.phase,
|
|
414
|
+
remoteMessageLength: terminalEvent.message.length
|
|
415
|
+
}));
|
|
416
|
+
return fail(new VcsActionMissingTerminalEventError({
|
|
417
|
+
actionId: input.actionId,
|
|
418
|
+
transportActionId: input.transportActionId,
|
|
419
|
+
action: input.action,
|
|
420
|
+
environmentId: input.target.environmentId,
|
|
421
|
+
cwd: input.target.cwd
|
|
422
|
+
}));
|
|
423
|
+
}));
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
function applyVcsActionProgressEvent(current, event) {
|
|
427
|
+
if (current.actionId !== event.actionId) return current;
|
|
428
|
+
const now = nowMs();
|
|
429
|
+
switch (event.kind) {
|
|
430
|
+
case "action_started": return {
|
|
431
|
+
...current,
|
|
432
|
+
isRunning: true,
|
|
433
|
+
actionId: event.actionId,
|
|
434
|
+
action: event.action,
|
|
435
|
+
operation: "run_change_request",
|
|
436
|
+
phaseStartedAtMs: now,
|
|
437
|
+
hookStartedAtMs: null,
|
|
438
|
+
hookName: null,
|
|
439
|
+
lastOutputLine: null,
|
|
440
|
+
error: null
|
|
441
|
+
};
|
|
442
|
+
case "phase_started": return {
|
|
443
|
+
...current,
|
|
444
|
+
isRunning: true,
|
|
445
|
+
actionId: event.actionId,
|
|
446
|
+
action: event.action,
|
|
447
|
+
operation: "run_change_request",
|
|
448
|
+
currentLabel: event.label,
|
|
449
|
+
currentPhaseLabel: event.label,
|
|
450
|
+
phaseStartedAtMs: now,
|
|
451
|
+
hookStartedAtMs: null,
|
|
452
|
+
hookName: null,
|
|
453
|
+
lastOutputLine: null,
|
|
454
|
+
error: null
|
|
455
|
+
};
|
|
456
|
+
case "hook_started": return {
|
|
457
|
+
...current,
|
|
458
|
+
isRunning: true,
|
|
459
|
+
actionId: event.actionId,
|
|
460
|
+
action: event.action,
|
|
461
|
+
operation: "run_change_request",
|
|
462
|
+
currentLabel: `Running ${event.hookName}...`,
|
|
463
|
+
hookName: event.hookName,
|
|
464
|
+
hookStartedAtMs: now,
|
|
465
|
+
lastOutputLine: null,
|
|
466
|
+
error: null
|
|
467
|
+
};
|
|
468
|
+
case "hook_output": return {
|
|
469
|
+
...current,
|
|
470
|
+
isRunning: true,
|
|
471
|
+
actionId: event.actionId,
|
|
472
|
+
action: event.action,
|
|
473
|
+
operation: "run_change_request",
|
|
474
|
+
lastOutputLine: event.text,
|
|
475
|
+
error: null
|
|
476
|
+
};
|
|
477
|
+
case "hook_finished": return {
|
|
478
|
+
...current,
|
|
479
|
+
isRunning: true,
|
|
480
|
+
actionId: event.actionId,
|
|
481
|
+
action: event.action,
|
|
482
|
+
operation: "run_change_request",
|
|
483
|
+
currentLabel: current.currentPhaseLabel,
|
|
484
|
+
hookName: null,
|
|
485
|
+
hookStartedAtMs: null,
|
|
486
|
+
lastOutputLine: null,
|
|
487
|
+
error: null
|
|
488
|
+
};
|
|
489
|
+
case "action_finished": return {
|
|
490
|
+
...EMPTY_VCS_ACTION_STATE,
|
|
491
|
+
actionId: event.actionId,
|
|
492
|
+
action: event.action,
|
|
493
|
+
operation: "run_change_request"
|
|
494
|
+
};
|
|
495
|
+
case "action_failed": return {
|
|
496
|
+
...EMPTY_VCS_ACTION_STATE,
|
|
497
|
+
actionId: event.actionId,
|
|
498
|
+
action: event.action,
|
|
499
|
+
operation: "run_change_request",
|
|
500
|
+
error: event.message
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function createVcsActionManager(runtime) {
|
|
505
|
+
const runStackedActionCommands = /* @__PURE__ */ new Map();
|
|
506
|
+
const getRunStackedActionCommand = (requestedTarget) => {
|
|
507
|
+
const targetKey = getVcsActionTargetKey(requestedTarget);
|
|
508
|
+
const commandKey = targetKey ?? JSON.stringify([
|
|
509
|
+
"vcs-action-target:unavailable",
|
|
510
|
+
requestedTarget.environmentId,
|
|
511
|
+
requestedTarget.cwd
|
|
512
|
+
]);
|
|
513
|
+
const existing = runStackedActionCommands.get(commandKey);
|
|
514
|
+
if (existing !== void 0) return existing;
|
|
515
|
+
const target = targetKey === null ? null : parseVcsActionTargetKey(targetKey);
|
|
516
|
+
const stateAtom = targetKey === null ? EMPTY_VCS_ACTION_ATOM : vcsActionStateAtom(targetKey);
|
|
517
|
+
const command = createRuntimeCommand(runtime, {
|
|
518
|
+
label: `vcs-action:run-stacked:${commandKey}`,
|
|
519
|
+
scheduler: vcsCommandScheduler,
|
|
520
|
+
concurrency: {
|
|
521
|
+
mode: "serial",
|
|
522
|
+
key: () => commandKey
|
|
523
|
+
},
|
|
524
|
+
execute: (input, registry) => {
|
|
525
|
+
if (target === null) return fail(new VcsActionUnavailableError({
|
|
526
|
+
operation: "run_change_request",
|
|
527
|
+
environmentId: requestedTarget.environmentId,
|
|
528
|
+
cwd: requestedTarget.cwd
|
|
529
|
+
}));
|
|
530
|
+
const transportActionId = createVcsActionTransportId(target, input.actionId);
|
|
531
|
+
registry.set(stateAtom, beginVcsActionState({
|
|
532
|
+
operation: "run_change_request",
|
|
533
|
+
label: "Running source control action",
|
|
534
|
+
actionId: input.actionId
|
|
535
|
+
}));
|
|
536
|
+
const rpcInput = {
|
|
537
|
+
actionId: transportActionId,
|
|
538
|
+
cwd: target.cwd,
|
|
539
|
+
action: input.action,
|
|
540
|
+
...input.commitMessage ? { commitMessage: input.commitMessage } : {},
|
|
541
|
+
...input.featureBranch ? { featureBranch: true } : {},
|
|
542
|
+
...input.filePaths?.length ? { filePaths: [...input.filePaths] } : {}
|
|
543
|
+
};
|
|
544
|
+
return consumeVcsActionProgress(runStreamInEnvironment(target.environmentId, runStream(WS_METHODS.gitRunStackedAction, rpcInput)), {
|
|
545
|
+
target,
|
|
546
|
+
transportActionId,
|
|
547
|
+
actionId: input.actionId,
|
|
548
|
+
action: input.action,
|
|
549
|
+
onProgress: (event) => sync(() => {
|
|
550
|
+
const current = registry.get(stateAtom);
|
|
551
|
+
if (current.actionId !== input.actionId) return;
|
|
552
|
+
registry.set(stateAtom, applyVcsActionProgressEvent(current, event));
|
|
553
|
+
if (input.onProgress !== void 0) try {
|
|
554
|
+
input.onProgress(event);
|
|
555
|
+
} catch {}
|
|
556
|
+
})
|
|
557
|
+
}).pipe(ensuring(invalidateCachedVcsRefs(registry, target)), tapError((error) => sync(() => {
|
|
558
|
+
const current = registry.get(stateAtom);
|
|
559
|
+
if (current.actionId === input.actionId && current.isRunning) registry.set(stateAtom, failVcsActionState("run_change_request", input.actionId, error));
|
|
560
|
+
})));
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
runStackedActionCommands.set(commandKey, command);
|
|
564
|
+
return command;
|
|
565
|
+
};
|
|
566
|
+
const setState = (registry, target, update) => {
|
|
567
|
+
const key = getVcsActionTargetKey(target);
|
|
568
|
+
if (key === null) return;
|
|
569
|
+
const stateAtom = vcsActionStateAtom(key);
|
|
570
|
+
registry.set(stateAtom, update(registry.get(stateAtom)));
|
|
571
|
+
};
|
|
572
|
+
return {
|
|
573
|
+
stateAtom: getVcsActionStateAtom,
|
|
574
|
+
runStackedAction: (target) => getRunStackedActionCommand(target),
|
|
575
|
+
track: async (registry, target, input, action) => {
|
|
576
|
+
const key = getVcsActionTargetKey(target);
|
|
577
|
+
if (key === null) return failure(fail$1(new VcsActionUnavailableError({
|
|
578
|
+
operation: input.operation,
|
|
579
|
+
environmentId: target.environmentId,
|
|
580
|
+
cwd: target.cwd
|
|
581
|
+
})));
|
|
582
|
+
const stateAtom = vcsActionStateAtom(key);
|
|
583
|
+
const next = beginVcsActionState(input);
|
|
584
|
+
registry.set(stateAtom, next);
|
|
585
|
+
const result = await action();
|
|
586
|
+
if (registry.get(stateAtom).actionId !== next.actionId) return result;
|
|
587
|
+
if (isSuccess(result) || hasInterruptsOnly(result.cause)) registry.set(stateAtom, EMPTY_VCS_ACTION_STATE);
|
|
588
|
+
else if (registry.get(stateAtom).actionId === next.actionId) registry.set(stateAtom, failVcsActionState(input.operation, next.actionId, squash(result.cause)));
|
|
589
|
+
return result;
|
|
590
|
+
},
|
|
591
|
+
resetError: (registry, target, operation) => {
|
|
592
|
+
setState(registry, target, (current) => !current.isRunning && current.operation === operation ? EMPTY_VCS_ACTION_STATE : current);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
//#endregion
|
|
597
|
+
//#region upstream-t3code/packages/client-runtime/src/state/vcs.ts
|
|
598
|
+
const OFFLINE_BRANCH_LIST_LIMIT = 100;
|
|
599
|
+
const VCS_REFS_IDLE_TTL_MS = 3e4;
|
|
600
|
+
const VCS_REFS_RETRY_SCHEDULE = exponential("1 second").pipe(modifyDelay(({ duration }) => succeed(min(duration, seconds(30)))));
|
|
601
|
+
function canUseVcsRefsCache(input) {
|
|
602
|
+
return input.query === void 0 && input.cursor === void 0 && input.includeMatchingRemoteRefs === void 0 && input.refKind === void 0 && input.limit === OFFLINE_BRANCH_LIST_LIMIT;
|
|
603
|
+
}
|
|
604
|
+
const commitVcsRefsRefresh = fn("CachedVcsRefsState.commitRefresh")(function* (registry, cache, input) {
|
|
605
|
+
return yield* withVcsRefsPersistenceLock(input.environmentId, gen(function* () {
|
|
606
|
+
const stateAtom = vcsRefsCacheStateAtom({ environmentId: input.environmentId });
|
|
607
|
+
const state = registry.get(stateAtom);
|
|
608
|
+
if (state.revision !== input.expectedRevision) return false;
|
|
609
|
+
let persistedCacheReadable = state.persistedCacheReadable;
|
|
610
|
+
if (input.persist) {
|
|
611
|
+
if (!persistedCacheReadable) persistedCacheReadable = yield* cache.clearVcsRefs(input.environmentId).pipe(as(true), catch_((error) => logWarning("Could not recover invalidated cached Git refs.").pipe(annotateLogs({
|
|
612
|
+
environmentId: input.environmentId,
|
|
613
|
+
cwd: input.cwd,
|
|
614
|
+
...safeErrorLogAttributes(error)
|
|
615
|
+
}), as(false))));
|
|
616
|
+
yield* cache.saveVcsRefs(input.environmentId, input.cwd, input.refs).pipe(catch_((error) => logWarning("Could not persist cached Git refs.").pipe(annotateLogs({
|
|
617
|
+
environmentId: input.environmentId,
|
|
618
|
+
cwd: input.cwd,
|
|
619
|
+
...safeErrorLogAttributes(error)
|
|
620
|
+
}))));
|
|
621
|
+
if (persistedCacheReadable !== state.persistedCacheReadable) registry.update(stateAtom, (current) => current.revision === input.expectedRevision ? {
|
|
622
|
+
...current,
|
|
623
|
+
persistedCacheReadable
|
|
624
|
+
} : current);
|
|
625
|
+
}
|
|
626
|
+
return true;
|
|
627
|
+
}));
|
|
628
|
+
});
|
|
629
|
+
/**
|
|
630
|
+
* Retains the last unfiltered branch-list response for the new-task picker.
|
|
631
|
+
* Filtered or paginated lists intentionally stay live-only: treating a
|
|
632
|
+
* partial result as a complete offline list would make branch selection
|
|
633
|
+
* misleading.
|
|
634
|
+
*/
|
|
635
|
+
const makeCachedVcsRefsChanges = fn("CachedVcsRefsState.makeChanges")(function* (input, expectedRevision, registry, persistedCacheReadable = true) {
|
|
636
|
+
const supervisor = yield* EnvironmentSupervisor;
|
|
637
|
+
const cache = yield* EnvironmentCacheStore;
|
|
638
|
+
const environmentId = supervisor.target.environmentId;
|
|
639
|
+
const useCache = canUseVcsRefsCache(input);
|
|
640
|
+
const cached = useCache && persistedCacheReadable ? yield* cache.loadVcsRefs(environmentId, input.cwd).pipe(catch_((error) => logWarning("Could not load cached Git refs.").pipe(annotateLogs({
|
|
641
|
+
environmentId,
|
|
642
|
+
cwd: input.cwd,
|
|
643
|
+
...safeErrorLogAttributes(error)
|
|
644
|
+
}), as(none())))) : none();
|
|
645
|
+
const refresh = fn("CachedVcsRefsState.refresh")(function* () {
|
|
646
|
+
const refs = yield* request(WS_METHODS.vcsListRefs, input).pipe(provideService(EnvironmentSupervisor, supervisor));
|
|
647
|
+
const persist = cache.saveVcsRefs(environmentId, input.cwd, refs).pipe(catch_((error) => logWarning("Could not persist cached Git refs.").pipe(annotateLogs({
|
|
648
|
+
environmentId,
|
|
649
|
+
cwd: input.cwd,
|
|
650
|
+
...safeErrorLogAttributes(error)
|
|
651
|
+
}))));
|
|
652
|
+
if (expectedRevision === void 0 || registry === void 0) {
|
|
653
|
+
if (useCache) yield* persist;
|
|
654
|
+
return some(refs);
|
|
655
|
+
}
|
|
656
|
+
return (yield* commitVcsRefsRefresh(registry, cache, {
|
|
657
|
+
environmentId,
|
|
658
|
+
cwd: input.cwd,
|
|
659
|
+
refs,
|
|
660
|
+
expectedRevision,
|
|
661
|
+
persist: useCache
|
|
662
|
+
})) ? some(refs) : none();
|
|
663
|
+
});
|
|
664
|
+
return concat(fromEffect(succeed(cached)).pipe(filterMap((refs) => match(refs, {
|
|
665
|
+
onNone: () => failVoid,
|
|
666
|
+
onSome: succeed$1
|
|
667
|
+
}))), concat(fromEffect(get(supervisor.state)), changes(supervisor.state)).pipe(map((connection) => connection.phase === "connected" ? connection.generation : null), changes$1, switchMap((generation) => generation === null ? empty : fromEffect(refresh().pipe(tapError((error) => logWarning("Could not refresh Git refs.").pipe(annotateLogs({
|
|
668
|
+
environmentId,
|
|
669
|
+
cwd: input.cwd,
|
|
670
|
+
...safeErrorLogAttributes(error)
|
|
671
|
+
}))))).pipe(retry(VCS_REFS_RETRY_SCHEDULE), filterMap((refs) => match(refs, {
|
|
672
|
+
onNone: () => failVoid,
|
|
673
|
+
onSome: succeed$1
|
|
674
|
+
}))))));
|
|
675
|
+
});
|
|
676
|
+
function cachedVcsRefsChanges(environmentId, input, expectedRevision, persistedCacheReadable) {
|
|
677
|
+
return followStreamInEnvironment(environmentId, unwrap(gen(function* () {
|
|
678
|
+
const registry = yield* AtomRegistry;
|
|
679
|
+
return yield* makeCachedVcsRefsChanges(input, expectedRevision, registry, persistedCacheReadable);
|
|
680
|
+
})));
|
|
681
|
+
}
|
|
682
|
+
function createVcsEnvironmentAtoms(runtime) {
|
|
683
|
+
const listRefsByEnvironment = family((environmentId) => family((inputKey) => {
|
|
684
|
+
const input = JSON.parse(inputKey);
|
|
685
|
+
return runtime.atom((get) => {
|
|
686
|
+
const state = get(vcsRefsCacheStateAtom({ environmentId }));
|
|
687
|
+
return cachedVcsRefsChanges(environmentId, input, state.revision, state.persistedCacheReadable);
|
|
688
|
+
}).pipe(setIdleTTL(VCS_REFS_IDLE_TTL_MS), withLabel(`environment-data:vcs:list-refs:${environmentId}:${inputKey}`));
|
|
689
|
+
}));
|
|
690
|
+
const listRefs = (target) => listRefsByEnvironment(target.environmentId)(JSON.stringify(target.input));
|
|
691
|
+
const invalidateRefs = (target, registry) => invalidateCachedVcsRefs(registry, {
|
|
692
|
+
environmentId: target.environmentId,
|
|
693
|
+
cwd: target.input.cwd
|
|
694
|
+
});
|
|
695
|
+
return {
|
|
696
|
+
listRefs,
|
|
697
|
+
status: createEnvironmentSubscriptionAtomFamily(runtime, {
|
|
698
|
+
label: "environment-data:vcs:status",
|
|
699
|
+
subscribe: (input) => subscribe(WS_METHODS.subscribeVcsStatus, input).pipe(mapAccum(() => null, (current, event) => {
|
|
700
|
+
const next = applyGitStatusStreamEvent(current, event);
|
|
701
|
+
return [next, [next]];
|
|
702
|
+
}))
|
|
703
|
+
}),
|
|
704
|
+
pull: createEnvironmentRpcCommand(runtime, {
|
|
705
|
+
label: "environment-data:vcs:pull",
|
|
706
|
+
tag: WS_METHODS.vcsPull,
|
|
707
|
+
scheduler: vcsCommandScheduler,
|
|
708
|
+
concurrency: vcsCommandConcurrency,
|
|
709
|
+
onSettled: invalidateRefs
|
|
710
|
+
}),
|
|
711
|
+
refreshStatus: createEnvironmentRpcCommand(runtime, {
|
|
712
|
+
label: "environment-data:vcs:refresh-status",
|
|
713
|
+
tag: WS_METHODS.vcsRefreshStatus,
|
|
714
|
+
scheduler: vcsCommandScheduler,
|
|
715
|
+
concurrency: vcsCommandConcurrency,
|
|
716
|
+
onSettled: invalidateRefs
|
|
717
|
+
}),
|
|
718
|
+
createWorktree: createEnvironmentRpcCommand(runtime, {
|
|
719
|
+
label: "environment-data:vcs:create-worktree",
|
|
720
|
+
tag: WS_METHODS.vcsCreateWorktree,
|
|
721
|
+
scheduler: vcsCommandScheduler,
|
|
722
|
+
concurrency: vcsCommandConcurrency,
|
|
723
|
+
onSettled: invalidateRefs
|
|
724
|
+
}),
|
|
725
|
+
removeWorktree: createEnvironmentRpcCommand(runtime, {
|
|
726
|
+
label: "environment-data:vcs:remove-worktree",
|
|
727
|
+
tag: WS_METHODS.vcsRemoveWorktree,
|
|
728
|
+
scheduler: vcsCommandScheduler,
|
|
729
|
+
concurrency: vcsCommandConcurrency,
|
|
730
|
+
onSettled: invalidateRefs
|
|
731
|
+
}),
|
|
732
|
+
createRef: createEnvironmentRpcCommand(runtime, {
|
|
733
|
+
label: "environment-data:vcs:create-ref",
|
|
734
|
+
tag: WS_METHODS.vcsCreateRef,
|
|
735
|
+
scheduler: vcsCommandScheduler,
|
|
736
|
+
concurrency: vcsCommandConcurrency,
|
|
737
|
+
onSettled: invalidateRefs
|
|
738
|
+
}),
|
|
739
|
+
switchRef: createEnvironmentRpcCommand(runtime, {
|
|
740
|
+
label: "environment-data:vcs:switch-ref",
|
|
741
|
+
tag: WS_METHODS.vcsSwitchRef,
|
|
742
|
+
scheduler: vcsCommandScheduler,
|
|
743
|
+
concurrency: vcsCommandConcurrency,
|
|
744
|
+
onSettled: invalidateRefs
|
|
745
|
+
}),
|
|
746
|
+
init: createEnvironmentRpcCommand(runtime, {
|
|
747
|
+
label: "environment-data:vcs:init",
|
|
748
|
+
tag: WS_METHODS.vcsInit,
|
|
749
|
+
scheduler: vcsCommandScheduler,
|
|
750
|
+
concurrency: vcsCommandConcurrency,
|
|
751
|
+
onSettled: invalidateRefs
|
|
752
|
+
})
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
//#endregion
|
|
756
|
+
export { EMPTY_VCS_ACTION_ATOM, EMPTY_VCS_ACTION_STATE, VcsActionExecutionError, VcsActionMissingTerminalEventError, VcsActionOperation, VcsActionRemoteFailureError, VcsActionTargetKeyParseError, VcsActionUnavailableError, applyVcsActionProgressEvent, beginVcsActionState, buildGitActionProgressStages, buildMenuItems, cachedVcsRefsChanges, commitVcsRefsRefresh, consumeVcsActionProgress, createVcsActionManager, createVcsActionTransportId, createVcsEnvironmentAtoms, failVcsActionState, getGitActionDisabledReason, getVcsActionStateAtom, getVcsActionTargetKey, makeCachedVcsRefsChanges, normalizeVcsActionProgressEvent, parseVcsActionTargetKey, requiresDefaultBranchConfirmation, resolveDefaultBranchActionDialogCopy, resolveLiveThreadBranchUpdate, resolveQuickAction, resolveThreadBranchUpdate, vcsActionStateAtom };
|