forked from pengchengneo/Claude-Code
-
Notifications
You must be signed in to change notification settings - Fork 185
Expand file tree
/
Copy pathremoteSession.ts
More file actions
98 lines (88 loc) · 2.98 KB
/
Copy pathremoteSession.ts
File metadata and controls
98 lines (88 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import type { SDKMessage } from 'src/entrypoints/agentSdkTypes.js'
import { checkGate_CACHED_OR_BLOCKING } from '../../../services/analytics/growthbook.js'
import { isPolicyAllowed } from '../../../services/policyLimits/index.js'
import { detectCurrentRepositoryWithHost } from '../../detectRepository.js'
import { isEnvTruthy } from '../../envUtils.js'
import type { TodoList } from '../../todo/types.js'
import {
checkGithubAppInstalled,
checkHasRemoteEnvironment,
checkIsInGitRepo,
checkNeedsClaudeAiLogin,
} from './preconditions.js'
/**
* Background remote session type for managing teleport sessions
*/
export type BackgroundRemoteSession = {
id: string
command: string
startTime: number
status: 'starting' | 'running' | 'completed' | 'failed' | 'killed'
todoList: TodoList
title: string
type: 'remote_session'
log: SDKMessage[]
}
/**
* Precondition failures for background remote sessions
*/
export type BackgroundRemoteSessionPrecondition =
| { type: 'not_logged_in' }
| { type: 'no_remote_environment' }
| { type: 'not_in_git_repo' }
| { type: 'no_git_remote' }
| { type: 'github_app_not_installed' }
| { type: 'policy_blocked' }
/**
* Checks eligibility for creating a background remote session
* Returns an array of failed preconditions (empty array means all checks passed)
*
* @returns Array of failed preconditions
*/
export async function checkBackgroundRemoteSessionEligibility({
skipBundle = false,
}: {
skipBundle?: boolean
} = {}): Promise<BackgroundRemoteSessionPrecondition[]> {
const errors: BackgroundRemoteSessionPrecondition[] = []
// Check policy first - if blocked, no need to check other preconditions
if (!isPolicyAllowed('allow_remote_sessions')) {
errors.push({ type: 'policy_blocked' })
return errors
}
const [needsLogin, hasRemoteEnv, repository] = await Promise.all([
checkNeedsClaudeAiLogin(),
checkHasRemoteEnvironment(),
detectCurrentRepositoryWithHost(),
])
if (needsLogin) {
errors.push({ type: 'not_logged_in' })
}
if (!hasRemoteEnv) {
errors.push({ type: 'no_remote_environment' })
}
// When bundle seeding is on, in-git-repo is enough — CCR can seed from
// a local bundle. No GitHub remote or app needed. Same gate as
// teleport.tsx bundleSeedGateOn.
const bundleSeedGateOn =
!skipBundle &&
(isEnvTruthy(process.env.CCR_FORCE_BUNDLE) ||
isEnvTruthy(process.env.CCR_ENABLE_BUNDLE) ||
(await checkGate_CACHED_OR_BLOCKING('tengu_ccr_bundle_seed_enabled')))
if (!checkIsInGitRepo()) {
errors.push({ type: 'not_in_git_repo' })
} else if (bundleSeedGateOn) {
// has .git/, bundle will work — skip remote+app checks
} else if (repository === null) {
errors.push({ type: 'no_git_remote' })
} else if (repository.host === 'github.com') {
const hasGithubApp = await checkGithubAppInstalled(
repository.owner,
repository.name,
)
if (!hasGithubApp) {
errors.push({ type: 'github_app_not_installed' })
}
}
return errors
}