forked from RapidAI/MaClaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremote_claude_onboarding.go
More file actions
85 lines (78 loc) · 2.7 KB
/
remote_claude_onboarding.go
File metadata and controls
85 lines (78 loc) · 2.7 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
package main
import (
"path/filepath"
"strings"
)
// ensureClaudeOnboardingComplete checks that Claude Code's user-level
// config file (~/.claude.json) contains the flags that mark onboarding
// as finished. If the file is missing or the flags are absent, they
// are added so that Claude Code skips the interactive first-run wizard
// when launched in a remote PTY session.
//
// It also ensures the given projectPath has a trust entry so Claude
// Code doesn't prompt "Do you trust this project folder?" on launch.
//
// This is necessary because:
// - Remote sessions may run under a user profile where Claude Code
// has never been launched interactively.
// - Remote sessions may use git worktree paths that Claude Code has
// never seen before.
// - The onboarding wizard and trust dialog are TUI flows that require
// manual input which is hard to automate through a PTY relay.
//
// The function is idempotent — it only adds missing keys and never
// removes existing user preferences.
func ensureClaudeOnboardingComplete(app *App, projectPath string) error {
return ensureClaudeCodeForkOnboarding(app, ".claude.json", "claude", projectPath)
}
// ensureProjectTrust adds a trust entry for the given project path in
// the "projects" map of ~/.claude.json. Returns true if the config
// was modified.
func ensureProjectTrust(config map[string]any, projectPath string) bool {
// Normalize the path to use forward slashes (Claude Code on Windows
// stores paths with forward slashes in its config).
normalizedPath := filepath.ToSlash(filepath.Clean(projectPath))
projects, ok := config["projects"].(map[string]any)
if !ok {
projects = map[string]any{}
config["projects"] = projects
}
// Check if this exact path or a variant already has trust.
for key, val := range projects {
// Normalize stored key for comparison.
normalizedKey := filepath.ToSlash(filepath.Clean(key))
if normalizedKey == normalizedPath {
entry, ok := val.(map[string]any)
if ok && isTruthy(entry["hasTrustDialogAccepted"]) {
return false // Already trusted
}
// Entry exists but trust not set — update it.
if entry == nil {
entry = map[string]any{}
}
entry["hasTrustDialogAccepted"] = true
projects[key] = entry
return true
}
}
// No entry for this path — create one with minimal trust flags.
projects[normalizedPath] = map[string]any{
"allowedTools": []any{},
"hasTrustDialogAccepted": true,
}
return true
}
// isTruthy checks if a JSON value is boolean true or the string "true".
func isTruthy(v any) bool {
if v == nil {
return false
}
switch val := v.(type) {
case bool:
return val
case string:
return strings.EqualFold(val, "true")
default:
return false
}
}