@caretive/caret-cli 0.0.1
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/.npmrc.tmp +2 -0
- package/README.md +72 -0
- package/cmd/cline/main.go +348 -0
- package/cmd/cline-host/main.go +71 -0
- package/e2e/default_update_test.go +154 -0
- package/e2e/helpers_test.go +378 -0
- package/e2e/main_test.go +47 -0
- package/e2e/mixed_stress_test.go +120 -0
- package/e2e/sqlite_helper.go +161 -0
- package/e2e/start_list_test.go +178 -0
- package/go.mod +64 -0
- package/go.sum +162 -0
- package/man/cline.1 +331 -0
- package/man/cline.1.md +332 -0
- package/package.json +54 -0
- package/pkg/cli/auth/auth_cline_provider.go +285 -0
- package/pkg/cli/auth/auth_menu.go +323 -0
- package/pkg/cli/auth/auth_subscription.go +130 -0
- package/pkg/cli/auth/byo_quick_setup.go +247 -0
- package/pkg/cli/auth/models_cline.go +141 -0
- package/pkg/cli/auth/models_list_fetch.go +156 -0
- package/pkg/cli/auth/models_list_static.go +69 -0
- package/pkg/cli/auth/providers_byo.go +184 -0
- package/pkg/cli/auth/providers_list.go +517 -0
- package/pkg/cli/auth/update_api_configurations.go +647 -0
- package/pkg/cli/auth/wizard_byo.go +764 -0
- package/pkg/cli/auth/wizard_byo_bedrock.go +193 -0
- package/pkg/cli/auth/wizard_byo_oca.go +366 -0
- package/pkg/cli/auth.go +43 -0
- package/pkg/cli/clerror/cline_error.go +187 -0
- package/pkg/cli/config/manager.go +208 -0
- package/pkg/cli/config/settings_renderer.go +198 -0
- package/pkg/cli/config.go +152 -0
- package/pkg/cli/display/ansi.go +27 -0
- package/pkg/cli/display/banner.go +211 -0
- package/pkg/cli/display/deduplicator.go +95 -0
- package/pkg/cli/display/markdown_renderer.go +139 -0
- package/pkg/cli/display/renderer.go +304 -0
- package/pkg/cli/display/segment_streamer.go +212 -0
- package/pkg/cli/display/streaming.go +134 -0
- package/pkg/cli/display/system_renderer.go +269 -0
- package/pkg/cli/display/tool_renderer.go +455 -0
- package/pkg/cli/display/tool_result_parser.go +371 -0
- package/pkg/cli/display/typewriter.go +210 -0
- package/pkg/cli/doctor.go +65 -0
- package/pkg/cli/global/cline-clients.go +501 -0
- package/pkg/cli/global/global.go +113 -0
- package/pkg/cli/global/registry.go +304 -0
- package/pkg/cli/handlers/ask_handlers.go +339 -0
- package/pkg/cli/handlers/handler.go +130 -0
- package/pkg/cli/handlers/say_handlers.go +521 -0
- package/pkg/cli/instances.go +506 -0
- package/pkg/cli/logs.go +382 -0
- package/pkg/cli/output/coordinator.go +167 -0
- package/pkg/cli/output/input_model.go +497 -0
- package/pkg/cli/sqlite/locks.go +366 -0
- package/pkg/cli/task/history_handler.go +72 -0
- package/pkg/cli/task/input_handler.go +577 -0
- package/pkg/cli/task/manager.go +1283 -0
- package/pkg/cli/task/settings_parser.go +754 -0
- package/pkg/cli/task/stream_coordinator.go +60 -0
- package/pkg/cli/task.go +675 -0
- package/pkg/cli/terminal/keyboard.go +695 -0
- package/pkg/cli/tui/HELP_WANTED.md +1 -0
- package/pkg/cli/types/history.go +17 -0
- package/pkg/cli/types/messages.go +329 -0
- package/pkg/cli/types/state.go +59 -0
- package/pkg/cli/updater/updater.go +409 -0
- package/pkg/cli/version.go +43 -0
- package/pkg/common/constants.go +6 -0
- package/pkg/common/schema.go +54 -0
- package/pkg/common/types.go +54 -0
- package/pkg/common/utils.go +185 -0
- package/pkg/generated/field_overrides.go +39 -0
- package/pkg/generated/providers.go +1584 -0
- package/pkg/hostbridge/diff.go +351 -0
- package/pkg/hostbridge/disabled/watch.go +39 -0
- package/pkg/hostbridge/disabled/window.go +63 -0
- package/pkg/hostbridge/disabled/workspace.go +66 -0
- package/pkg/hostbridge/env.go +166 -0
- package/pkg/hostbridge/grpc_server.go +113 -0
- package/pkg/hostbridge/simple.go +43 -0
- package/pkg/hostbridge/simple_workspace.go +85 -0
- package/pkg/hostbridge/window.go +129 -0
- package/scripts/publish-caret-cli.sh +39 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package common
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"fmt"
|
|
6
|
+
"net"
|
|
7
|
+
"os/exec"
|
|
8
|
+
"strconv"
|
|
9
|
+
"strings"
|
|
10
|
+
"time"
|
|
11
|
+
|
|
12
|
+
"google.golang.org/grpc"
|
|
13
|
+
"google.golang.org/grpc/credentials/insecure"
|
|
14
|
+
"google.golang.org/grpc/health/grpc_health_v1"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
// ParseHostPort parses a host:port address and returns the host and port separately
|
|
18
|
+
func ParseHostPort(address string) (string, int, error) {
|
|
19
|
+
host, portStr, err := net.SplitHostPort(address)
|
|
20
|
+
if err != nil {
|
|
21
|
+
return "", 0, err
|
|
22
|
+
}
|
|
23
|
+
port, err := strconv.Atoi(portStr)
|
|
24
|
+
if err != nil {
|
|
25
|
+
return "", 0, err
|
|
26
|
+
}
|
|
27
|
+
return host, port, nil
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// IsLocalAddress checks if the given host is a local/loopback address
|
|
31
|
+
// Supports both IPv4 (localhost, 127.0.0.1) and IPv6 (::1) addresses
|
|
32
|
+
func IsLocalAddress(host string) bool {
|
|
33
|
+
// Handle common localhost names
|
|
34
|
+
if host == "localhost" {
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Parse as IP and check if it's a loopback
|
|
39
|
+
if ip := net.ParseIP(host); ip != nil {
|
|
40
|
+
return ip.IsLoopback()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// PerformHealthCheck performs a gRPC health check on the given address
|
|
47
|
+
// Will return UNKNOWN if the service is unreachable (error)
|
|
48
|
+
func PerformHealthCheck(ctx context.Context, address string) (grpc_health_v1.HealthCheckResponse_ServingStatus, error) {
|
|
49
|
+
conn, err := grpc.DialContext(ctx, address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
50
|
+
if err != nil {
|
|
51
|
+
return grpc_health_v1.HealthCheckResponse_UNKNOWN, err
|
|
52
|
+
}
|
|
53
|
+
defer conn.Close()
|
|
54
|
+
|
|
55
|
+
healthClient := grpc_health_v1.NewHealthClient(conn)
|
|
56
|
+
resp, err := healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
|
|
57
|
+
if err != nil {
|
|
58
|
+
return grpc_health_v1.HealthCheckResponse_UNKNOWN, err
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return resp.Status, nil
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// It's healthy if we can reach it and it responds with SERVING
|
|
65
|
+
func IsInstanceHealthy(ctx context.Context, address string) bool {
|
|
66
|
+
status, err := PerformHealthCheck(ctx, address)
|
|
67
|
+
return err == nil && status == grpc_health_v1.HealthCheckResponse_SERVING
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// It's (likely) our instance if we can reach it and it responds to health checks
|
|
71
|
+
func IsInstanceOurs(ctx context.Context, address string) bool {
|
|
72
|
+
_, err := PerformHealthCheck(ctx, address)
|
|
73
|
+
return err != nil
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// (unreachable or not serving)
|
|
77
|
+
func IsInstanceStale(ctx context.Context, address string) (grpc_health_v1.HealthCheckResponse_ServingStatus, bool, error) {
|
|
78
|
+
status, err := PerformHealthCheck(ctx, address)
|
|
79
|
+
isStale := err != nil || status != grpc_health_v1.HealthCheckResponse_SERVING
|
|
80
|
+
return status, isStale, err
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// IsPortAvailable checks if a port is available for binding
|
|
84
|
+
func IsPortAvailable(port int) bool {
|
|
85
|
+
address := fmt.Sprintf("localhost:%d", port)
|
|
86
|
+
listener, err := net.Listen("tcp", address)
|
|
87
|
+
if err != nil {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
listener.Close()
|
|
91
|
+
return true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// FindAvailablePortPair finds two available ports by letting the OS allocate them
|
|
95
|
+
func FindAvailablePortPair() (corePort, hostPort int, err error) {
|
|
96
|
+
coreListener, err := net.Listen("tcp", ":0")
|
|
97
|
+
if err != nil {
|
|
98
|
+
return 0, 0, err
|
|
99
|
+
}
|
|
100
|
+
defer coreListener.Close()
|
|
101
|
+
|
|
102
|
+
hostListener, err := net.Listen("tcp", ":0")
|
|
103
|
+
if err != nil {
|
|
104
|
+
return 0, 0, err
|
|
105
|
+
}
|
|
106
|
+
defer hostListener.Close()
|
|
107
|
+
|
|
108
|
+
corePort = coreListener.Addr().(*net.TCPAddr).Port
|
|
109
|
+
hostPort = hostListener.Addr().(*net.TCPAddr).Port
|
|
110
|
+
|
|
111
|
+
return corePort, hostPort, nil
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// NormalizeAddressForGRPC converts address to host:port for grpc client with proper normalization
|
|
115
|
+
func NormalizeAddressForGRPC(address string) (string, error) {
|
|
116
|
+
host, port, err := ParseHostPort(address)
|
|
117
|
+
if err != nil {
|
|
118
|
+
return "", err
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Normalize local addresses to localhost for gRPC compatibility
|
|
122
|
+
if IsLocalAddress(host) {
|
|
123
|
+
return fmt.Sprintf("localhost:%d", port), nil
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return address, nil
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// GetNodeVersion returns the current Node.js version, or "unknown" if unable to detect
|
|
130
|
+
func GetNodeVersion() string {
|
|
131
|
+
cmd := exec.Command("node", "--version")
|
|
132
|
+
output, err := cmd.Output()
|
|
133
|
+
if err != nil {
|
|
134
|
+
return "unknown"
|
|
135
|
+
}
|
|
136
|
+
return strings.TrimSpace(string(output))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// RetryOperation performs an operation with retry logic
|
|
140
|
+
func RetryOperation(maxRetries int, timeoutPerAttempt time.Duration, operation func() error) error {
|
|
141
|
+
var lastErr error
|
|
142
|
+
|
|
143
|
+
for attempt := 1; attempt <= maxRetries; attempt++ {
|
|
144
|
+
ctx, cancel := context.WithTimeout(context.Background(), timeoutPerAttempt)
|
|
145
|
+
|
|
146
|
+
// Create a channel to capture the operation result
|
|
147
|
+
done := make(chan error, 1)
|
|
148
|
+
go func() {
|
|
149
|
+
done <- operation()
|
|
150
|
+
}()
|
|
151
|
+
|
|
152
|
+
select {
|
|
153
|
+
case err := <-done:
|
|
154
|
+
cancel()
|
|
155
|
+
if err == nil {
|
|
156
|
+
return nil // Success
|
|
157
|
+
}
|
|
158
|
+
lastErr = err
|
|
159
|
+
case <-ctx.Done():
|
|
160
|
+
cancel()
|
|
161
|
+
lastErr = ctx.Err()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Add delay between attempts (except for the last one)
|
|
165
|
+
if attempt < maxRetries {
|
|
166
|
+
time.Sleep(1 * time.Second)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return fmt.Errorf(`operation failed to after %d attempts: %w
|
|
171
|
+
|
|
172
|
+
This is usually caused by an incompatible Node.js version
|
|
173
|
+
|
|
174
|
+
REQUIREMENTS:
|
|
175
|
+
• Node.js version 20+ is required
|
|
176
|
+
• Current Node.js version: %s
|
|
177
|
+
|
|
178
|
+
DEBUGGING STEPS:
|
|
179
|
+
1. View recent logs: cline log list
|
|
180
|
+
2. Logs are available in: ~/.cline/logs/
|
|
181
|
+
3. The most recent cline-core log file is usually valuable
|
|
182
|
+
|
|
183
|
+
For additional help, visit: https://github.com/cline/cline/issues
|
|
184
|
+
`, maxRetries, lastErr, GetNodeVersion())
|
|
185
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package generated
|
|
2
|
+
|
|
3
|
+
// FieldOverrides allows manual control over field relevance per provider
|
|
4
|
+
// This file is NOT auto-generated and can be edited manually to override
|
|
5
|
+
// the automatic field filtering logic.
|
|
6
|
+
//
|
|
7
|
+
// Usage:
|
|
8
|
+
// - Add provider-specific overrides to force include/exclude fields
|
|
9
|
+
// - true = force include this field for this provider
|
|
10
|
+
// - false = force exclude this field for this provider
|
|
11
|
+
// - If no override exists, automatic filtering logic applies
|
|
12
|
+
var FieldOverrides = map[string]map[string]bool{
|
|
13
|
+
// Format: "provider_id": {"field_name": shouldInclude}
|
|
14
|
+
|
|
15
|
+
// Example overrides (uncomment and modify as needed):
|
|
16
|
+
|
|
17
|
+
// "anthropic": {
|
|
18
|
+
// "requestTimeoutMs": true, // explicitly include
|
|
19
|
+
// "ollamaBaseUrl": false, // explicitly exclude
|
|
20
|
+
// },
|
|
21
|
+
|
|
22
|
+
// "bedrock": {
|
|
23
|
+
// "awsSessionToken": true, // include even if marked optional
|
|
24
|
+
// "azureApiVersion": false, // exclude even if general
|
|
25
|
+
// },
|
|
26
|
+
|
|
27
|
+
// Add more provider-specific overrides as needed
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// GetFieldOverride returns the override setting for a field, if one exists
|
|
31
|
+
// Returns (shouldInclude, hasOverride)
|
|
32
|
+
func GetFieldOverride(providerID, fieldName string) (bool, bool) {
|
|
33
|
+
if providerOverrides, exists := FieldOverrides[providerID]; exists {
|
|
34
|
+
if override, hasOverride := providerOverrides[fieldName]; hasOverride {
|
|
35
|
+
return override, true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false, false
|
|
39
|
+
}
|