@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.
Files changed (85) hide show
  1. package/.npmrc.tmp +2 -0
  2. package/README.md +72 -0
  3. package/cmd/cline/main.go +348 -0
  4. package/cmd/cline-host/main.go +71 -0
  5. package/e2e/default_update_test.go +154 -0
  6. package/e2e/helpers_test.go +378 -0
  7. package/e2e/main_test.go +47 -0
  8. package/e2e/mixed_stress_test.go +120 -0
  9. package/e2e/sqlite_helper.go +161 -0
  10. package/e2e/start_list_test.go +178 -0
  11. package/go.mod +64 -0
  12. package/go.sum +162 -0
  13. package/man/cline.1 +331 -0
  14. package/man/cline.1.md +332 -0
  15. package/package.json +54 -0
  16. package/pkg/cli/auth/auth_cline_provider.go +285 -0
  17. package/pkg/cli/auth/auth_menu.go +323 -0
  18. package/pkg/cli/auth/auth_subscription.go +130 -0
  19. package/pkg/cli/auth/byo_quick_setup.go +247 -0
  20. package/pkg/cli/auth/models_cline.go +141 -0
  21. package/pkg/cli/auth/models_list_fetch.go +156 -0
  22. package/pkg/cli/auth/models_list_static.go +69 -0
  23. package/pkg/cli/auth/providers_byo.go +184 -0
  24. package/pkg/cli/auth/providers_list.go +517 -0
  25. package/pkg/cli/auth/update_api_configurations.go +647 -0
  26. package/pkg/cli/auth/wizard_byo.go +764 -0
  27. package/pkg/cli/auth/wizard_byo_bedrock.go +193 -0
  28. package/pkg/cli/auth/wizard_byo_oca.go +366 -0
  29. package/pkg/cli/auth.go +43 -0
  30. package/pkg/cli/clerror/cline_error.go +187 -0
  31. package/pkg/cli/config/manager.go +208 -0
  32. package/pkg/cli/config/settings_renderer.go +198 -0
  33. package/pkg/cli/config.go +152 -0
  34. package/pkg/cli/display/ansi.go +27 -0
  35. package/pkg/cli/display/banner.go +211 -0
  36. package/pkg/cli/display/deduplicator.go +95 -0
  37. package/pkg/cli/display/markdown_renderer.go +139 -0
  38. package/pkg/cli/display/renderer.go +304 -0
  39. package/pkg/cli/display/segment_streamer.go +212 -0
  40. package/pkg/cli/display/streaming.go +134 -0
  41. package/pkg/cli/display/system_renderer.go +269 -0
  42. package/pkg/cli/display/tool_renderer.go +455 -0
  43. package/pkg/cli/display/tool_result_parser.go +371 -0
  44. package/pkg/cli/display/typewriter.go +210 -0
  45. package/pkg/cli/doctor.go +65 -0
  46. package/pkg/cli/global/cline-clients.go +501 -0
  47. package/pkg/cli/global/global.go +113 -0
  48. package/pkg/cli/global/registry.go +304 -0
  49. package/pkg/cli/handlers/ask_handlers.go +339 -0
  50. package/pkg/cli/handlers/handler.go +130 -0
  51. package/pkg/cli/handlers/say_handlers.go +521 -0
  52. package/pkg/cli/instances.go +506 -0
  53. package/pkg/cli/logs.go +382 -0
  54. package/pkg/cli/output/coordinator.go +167 -0
  55. package/pkg/cli/output/input_model.go +497 -0
  56. package/pkg/cli/sqlite/locks.go +366 -0
  57. package/pkg/cli/task/history_handler.go +72 -0
  58. package/pkg/cli/task/input_handler.go +577 -0
  59. package/pkg/cli/task/manager.go +1283 -0
  60. package/pkg/cli/task/settings_parser.go +754 -0
  61. package/pkg/cli/task/stream_coordinator.go +60 -0
  62. package/pkg/cli/task.go +675 -0
  63. package/pkg/cli/terminal/keyboard.go +695 -0
  64. package/pkg/cli/tui/HELP_WANTED.md +1 -0
  65. package/pkg/cli/types/history.go +17 -0
  66. package/pkg/cli/types/messages.go +329 -0
  67. package/pkg/cli/types/state.go +59 -0
  68. package/pkg/cli/updater/updater.go +409 -0
  69. package/pkg/cli/version.go +43 -0
  70. package/pkg/common/constants.go +6 -0
  71. package/pkg/common/schema.go +54 -0
  72. package/pkg/common/types.go +54 -0
  73. package/pkg/common/utils.go +185 -0
  74. package/pkg/generated/field_overrides.go +39 -0
  75. package/pkg/generated/providers.go +1584 -0
  76. package/pkg/hostbridge/diff.go +351 -0
  77. package/pkg/hostbridge/disabled/watch.go +39 -0
  78. package/pkg/hostbridge/disabled/window.go +63 -0
  79. package/pkg/hostbridge/disabled/workspace.go +66 -0
  80. package/pkg/hostbridge/env.go +166 -0
  81. package/pkg/hostbridge/grpc_server.go +113 -0
  82. package/pkg/hostbridge/simple.go +43 -0
  83. package/pkg/hostbridge/simple_workspace.go +85 -0
  84. package/pkg/hostbridge/window.go +129 -0
  85. package/scripts/publish-caret-cli.sh +39 -0
@@ -0,0 +1,113 @@
1
+ package hostbridge
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "log"
7
+ "net"
8
+
9
+ "github.com/cline/grpc-go/host"
10
+ "google.golang.org/grpc"
11
+ "google.golang.org/grpc/health"
12
+ "google.golang.org/grpc/health/grpc_health_v1"
13
+ )
14
+
15
+ // GrpcServer provides gRPC hostbridge functionality
16
+ type GrpcServer struct {
17
+ port int
18
+ verbose bool
19
+ server *grpc.Server
20
+ shutdownCh chan struct{}
21
+ }
22
+
23
+ // NewGrpcServer creates a new GrpcServer
24
+ func NewGrpcServer(port int, verbose bool) *GrpcServer {
25
+ return &GrpcServer{
26
+ port: port,
27
+ verbose: verbose,
28
+ shutdownCh: make(chan struct{}),
29
+ }
30
+ }
31
+
32
+ // Start starts the gRPC hostbridge server
33
+ func (s *GrpcServer) Start(ctx context.Context) error {
34
+ if s.verbose {
35
+ log.Printf("Starting gRPC hostbridge server on port %d", s.port)
36
+ }
37
+
38
+ // Create listener
39
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", s.port))
40
+ if err != nil {
41
+ return fmt.Errorf("failed to listen on port %d: %w", s.port, err)
42
+ }
43
+
44
+ // Create gRPC server
45
+ s.server = grpc.NewServer()
46
+
47
+ // Register health service
48
+ healthServer := health.NewServer()
49
+ healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_SERVING)
50
+ grpc_health_v1.RegisterHealthServer(s.server, healthServer)
51
+
52
+ // Register services
53
+ workspaceService := NewSimpleWorkspaceService(s.verbose)
54
+ host.RegisterWorkspaceServiceServer(s.server, workspaceService)
55
+
56
+ windowService := NewWindowService(s.verbose)
57
+ host.RegisterWindowServiceServer(s.server, windowService)
58
+
59
+ diffService := NewDiffService(s.verbose)
60
+ host.RegisterDiffServiceServer(s.server, diffService)
61
+
62
+ envService := NewEnvService(s.verbose)
63
+ host.RegisterEnvServiceServer(s.server, envService)
64
+
65
+ if s.verbose {
66
+ log.Printf("Registered HealthService")
67
+ log.Printf("Registered WorkspaceService")
68
+ log.Printf("Registered WindowService")
69
+ log.Printf("Registered DiffService")
70
+ log.Printf("Registered EnvService")
71
+ }
72
+
73
+ // Start server in goroutine
74
+ go func() {
75
+ if s.verbose {
76
+ log.Printf("gRPC server listening on :%d", s.port)
77
+ }
78
+ if err := s.server.Serve(lis); err != nil {
79
+ log.Printf("gRPC server error: %v", err)
80
+ }
81
+ }()
82
+
83
+ // Wait for context cancellation or global shutdown signal
84
+ select {
85
+ case <-ctx.Done():
86
+ if s.verbose {
87
+ log.Println("Context cancelled, shutting down gRPC hostbridge server...")
88
+ }
89
+ case <-globalShutdownCh:
90
+ if s.verbose {
91
+ log.Println("Shutdown requested via RPC, shutting down gRPC hostbridge server...")
92
+ }
93
+ }
94
+
95
+ // Graceful shutdown
96
+ s.server.GracefulStop()
97
+
98
+ if s.verbose {
99
+ log.Println("gRPC hostbridge server stopped")
100
+ }
101
+
102
+ return nil
103
+ }
104
+
105
+ // TriggerShutdown triggers a graceful shutdown of the server
106
+ func (s *GrpcServer) TriggerShutdown() {
107
+ select {
108
+ case s.shutdownCh <- struct{}{}:
109
+ // Shutdown signal sent
110
+ default:
111
+ // Channel already has a signal or is closed
112
+ }
113
+ }
@@ -0,0 +1,43 @@
1
+ package hostbridge
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "log"
7
+ )
8
+
9
+ // Simple implementations that don't rely on proto files for now
10
+ // This allows us to test the basic hostbridge structure
11
+
12
+ // SimpleService provides basic hostbridge functionality
13
+ type SimpleService struct {
14
+ coreAddress string
15
+ verbose bool
16
+ }
17
+
18
+ // NewSimpleService creates a new SimpleService
19
+ func NewSimpleService(coreAddress string, verbose bool) *SimpleService {
20
+ return &SimpleService{
21
+ coreAddress: coreAddress,
22
+ verbose: verbose,
23
+ }
24
+ }
25
+
26
+ // Start starts the simple hostbridge service
27
+ func (s *SimpleService) Start(ctx context.Context) error {
28
+ if s.verbose {
29
+ log.Printf("Starting simple hostbridge service (connecting to core at %s)", s.coreAddress)
30
+ }
31
+
32
+ // For now, just log that we're running
33
+ fmt.Printf("[Cline Host Bridge] Service started on core address: %s\n", s.coreAddress)
34
+
35
+ // Keep running until context is cancelled
36
+ <-ctx.Done()
37
+
38
+ if s.verbose {
39
+ log.Println("Simple hostbridge service stopped")
40
+ }
41
+
42
+ return nil
43
+ }
@@ -0,0 +1,85 @@
1
+ package hostbridge
2
+
3
+ import (
4
+ "context"
5
+ "log"
6
+ "os"
7
+
8
+ "github.com/cline/grpc-go/cline"
9
+ "github.com/cline/grpc-go/host"
10
+ )
11
+
12
+ // SimpleWorkspaceService implements a basic workspace service without complex dependencies
13
+ type SimpleWorkspaceService struct {
14
+ host.UnimplementedWorkspaceServiceServer
15
+ verbose bool
16
+ }
17
+
18
+ // NewSimpleWorkspaceService creates a new SimpleWorkspaceService
19
+ func NewSimpleWorkspaceService(verbose bool) *SimpleWorkspaceService {
20
+ return &SimpleWorkspaceService{
21
+ verbose: verbose,
22
+ }
23
+ }
24
+
25
+ // GetWorkspacePaths returns the workspace directory paths
26
+ func (s *SimpleWorkspaceService) GetWorkspacePaths(ctx context.Context, req *host.GetWorkspacePathsRequest) (*host.GetWorkspacePathsResponse, error) {
27
+ if s.verbose {
28
+ log.Printf("GetWorkspacePaths called")
29
+ }
30
+
31
+ // Get current working directory as the workspace
32
+ cwd, err := os.Getwd()
33
+ if err != nil {
34
+ return nil, err
35
+ }
36
+
37
+ return &host.GetWorkspacePathsResponse{
38
+ Paths: []string{cwd},
39
+ }, nil
40
+ }
41
+
42
+ // SaveOpenDocumentIfDirty saves an open document if it has unsaved changes
43
+ func (s *SimpleWorkspaceService) SaveOpenDocumentIfDirty(ctx context.Context, req *host.SaveOpenDocumentIfDirtyRequest) (*host.SaveOpenDocumentIfDirtyResponse, error) {
44
+ if s.verbose {
45
+ log.Printf("SaveOpenDocumentIfDirty called for path: %s", req.GetFilePath())
46
+ }
47
+
48
+ // For console implementation, we'll assume the document is already saved
49
+ wasSaved := false
50
+ return &host.SaveOpenDocumentIfDirtyResponse{
51
+ WasSaved: &wasSaved,
52
+ }, nil
53
+ }
54
+
55
+ // GetDiagnostics returns diagnostic information for a file - simplified version
56
+ func (s *SimpleWorkspaceService) GetDiagnostics(ctx context.Context, req *host.GetDiagnosticsRequest) (*host.GetDiagnosticsResponse, error) {
57
+ if s.verbose {
58
+ log.Printf("GetDiagnostics called")
59
+ }
60
+
61
+ // For console implementation, return empty diagnostics
62
+ return &host.GetDiagnosticsResponse{
63
+ FileDiagnostics: []*cline.FileDiagnostics{},
64
+ }, nil
65
+ }
66
+
67
+ // OpenProblemsPanel opens the problems panel - no-op for console implementation
68
+ func (s *SimpleWorkspaceService) OpenProblemsPanel(ctx context.Context, req *host.OpenProblemsPanelRequest) (*host.OpenProblemsPanelResponse, error) {
69
+ return &host.OpenProblemsPanelResponse{}, nil
70
+ }
71
+
72
+ // OpenInFileExplorerPanel opens a file/folder in the file explorer - no-op for console implementation
73
+ func (s *SimpleWorkspaceService) OpenInFileExplorerPanel(ctx context.Context, req *host.OpenInFileExplorerPanelRequest) (*host.OpenInFileExplorerPanelResponse, error) {
74
+ return &host.OpenInFileExplorerPanelResponse{}, nil
75
+ }
76
+
77
+ // OpenClineSidebarPanel opens the Cline sidebar panel - no-op for console implementation
78
+ func (s *SimpleWorkspaceService) OpenClineSidebarPanel(ctx context.Context, req *host.OpenClineSidebarPanelRequest) (*host.OpenClineSidebarPanelResponse, error) {
79
+ return &host.OpenClineSidebarPanelResponse{}, nil
80
+ }
81
+
82
+ // OpenTerminalPanel opens the terminal panel - no-op for console implementation
83
+ func (s *SimpleWorkspaceService) OpenTerminalPanel(ctx context.Context, req *host.OpenTerminalRequest) (*host.OpenTerminalResponse, error) {
84
+ return &host.OpenTerminalResponse{}, nil
85
+ }
@@ -0,0 +1,129 @@
1
+ package hostbridge
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "log"
7
+
8
+ proto "github.com/cline/grpc-go/host"
9
+ )
10
+
11
+ // WindowService implements the proto.WindowServiceServer interface
12
+ type WindowService struct {
13
+ proto.UnimplementedWindowServiceServer
14
+ verbose bool
15
+ }
16
+
17
+ // NewWindowService creates a new WindowService
18
+ func NewWindowService(verbose bool) *WindowService {
19
+ return &WindowService{
20
+ verbose: verbose,
21
+ }
22
+ }
23
+
24
+ // ShowTextDocument opens a text document for viewing/editing
25
+ func (s *WindowService) ShowTextDocument(ctx context.Context, req *proto.ShowTextDocumentRequest) (*proto.TextEditorInfo, error) {
26
+ if s.verbose {
27
+ log.Printf("ShowTextDocument called for path: %s", req.GetPath())
28
+ }
29
+
30
+ // For console implementation, we'll just log that we would open the document
31
+ fmt.Printf("[Cline] Would open document: %s\n", req.GetPath())
32
+
33
+ return &proto.TextEditorInfo{
34
+ DocumentPath: req.GetPath(),
35
+ IsActive: true,
36
+ }, nil
37
+ }
38
+
39
+ // ShowOpenDialogue shows a file open dialog
40
+ func (s *WindowService) ShowOpenDialogue(ctx context.Context, req *proto.ShowOpenDialogueRequest) (*proto.SelectedResources, error) {
41
+ if s.verbose {
42
+ log.Printf("ShowOpenDialogue called")
43
+ }
44
+
45
+ // For console implementation, return empty list (user cancelled)
46
+ return &proto.SelectedResources{
47
+ Paths: []string{},
48
+ }, nil
49
+ }
50
+
51
+ // ShowMessage displays a message to the user
52
+ func (s *WindowService) ShowMessage(ctx context.Context, req *proto.ShowMessageRequest) (*proto.SelectedResponse, error) {
53
+ if s.verbose {
54
+ log.Printf("ShowMessage called: %s", req.GetMessage())
55
+ }
56
+
57
+ // Display message to console
58
+ fmt.Printf("[Cline] %s\n", req.GetMessage())
59
+
60
+ return &proto.SelectedResponse{}, nil
61
+ }
62
+
63
+ // ShowInputBox shows an input dialog to the user
64
+ func (s *WindowService) ShowInputBox(ctx context.Context, req *proto.ShowInputBoxRequest) (*proto.ShowInputBoxResponse, error) {
65
+ if s.verbose {
66
+ log.Printf("ShowInputBox called: %s", req.GetTitle())
67
+ }
68
+
69
+ // For console implementation, return empty response (user cancelled)
70
+ return &proto.ShowInputBoxResponse{}, nil
71
+ }
72
+
73
+ // ShowSaveDialog shows a save file dialog
74
+ func (s *WindowService) ShowSaveDialog(ctx context.Context, req *proto.ShowSaveDialogRequest) (*proto.ShowSaveDialogResponse, error) {
75
+ if s.verbose {
76
+ log.Printf("ShowSaveDialog called")
77
+ }
78
+
79
+ // For console implementation, return empty response (user cancelled)
80
+ return &proto.ShowSaveDialogResponse{}, nil
81
+ }
82
+
83
+ // OpenFile opens a file in the editor
84
+ func (s *WindowService) OpenFile(ctx context.Context, req *proto.OpenFileRequest) (*proto.OpenFileResponse, error) {
85
+ if s.verbose {
86
+ log.Printf("OpenFile called for path: %s", req.GetFilePath())
87
+ }
88
+
89
+ // For console implementation, just log that we would open the file
90
+ fmt.Printf("[Cline] Would open file: %s\n", req.GetFilePath())
91
+
92
+ return &proto.OpenFileResponse{}, nil
93
+ }
94
+
95
+ // GetOpenTabs returns a list of currently open tabs
96
+ func (s *WindowService) GetOpenTabs(ctx context.Context, req *proto.GetOpenTabsRequest) (*proto.GetOpenTabsResponse, error) {
97
+ if s.verbose {
98
+ log.Printf("GetOpenTabs called")
99
+ }
100
+
101
+ // For console implementation, return empty list
102
+ return &proto.GetOpenTabsResponse{
103
+ Paths: []string{},
104
+ }, nil
105
+ }
106
+
107
+ // GetVisibleTabs returns a list of currently visible tabs
108
+ func (s *WindowService) GetVisibleTabs(ctx context.Context, req *proto.GetVisibleTabsRequest) (*proto.GetVisibleTabsResponse, error) {
109
+ if s.verbose {
110
+ log.Printf("GetVisibleTabs called")
111
+ }
112
+
113
+ // For console implementation, return empty list
114
+ return &proto.GetVisibleTabsResponse{
115
+ Paths: []string{},
116
+ }, nil
117
+ }
118
+
119
+ // GetActiveEditor returns information about the current active editor
120
+ func (s *WindowService) GetActiveEditor(ctx context.Context, req *proto.GetActiveEditorRequest) (*proto.GetActiveEditorResponse, error) {
121
+ if s.verbose {
122
+ log.Printf("GetActiveEditor called")
123
+ }
124
+
125
+ // Return empty response (no active file)
126
+ return &proto.GetActiveEditorResponse{
127
+ FilePath: nil,
128
+ }, nil
129
+ }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # CARET MODIFICATION: Publish script for @caretive/caret-cli using .env NPM_TOKEN
5
+
6
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
7
+ ENV_FILE="$ROOT_DIR/.env"
8
+ REPO_ROOT="$(cd "$ROOT_DIR/.." && pwd)"
9
+ NPMRC_TMP="$ROOT_DIR/.npmrc.tmp"
10
+
11
+ if [[ -f "$ENV_FILE" ]]; then
12
+ # shellcheck disable=SC1090
13
+ source "$ENV_FILE"
14
+ elif [[ -f "$REPO_ROOT/.env" ]]; then
15
+ # shellcheck disable=SC1090
16
+ source "$REPO_ROOT/.env"
17
+ fi
18
+
19
+ if [[ -z "${NPM_TOKEN:-}" && -n "${CARET_NPM_TOKEN:-}" ]]; then
20
+ NPM_TOKEN="${CARET_NPM_TOKEN}"
21
+ fi
22
+
23
+ if [[ -z "${NPM_TOKEN:-}" ]]; then
24
+ echo "NPM_TOKEN/CARET_NPM_TOKEN is not set. Please set it in .env or environment." >&2
25
+ exit 1
26
+ fi
27
+
28
+ export NPM_CONFIG_TOKEN="$NPM_TOKEN"
29
+ cat > "$NPMRC_TMP" <<EOF
30
+ //registry.npmjs.org/:_authToken=${NPM_TOKEN}
31
+ @caretive:registry=https://registry.npmjs.org/
32
+ EOF
33
+ export NPM_CONFIG_USERCONFIG="$NPMRC_TMP"
34
+
35
+ echo "Publishing @caretive/caret-cli ..."
36
+ npm publish --access public "$@"
37
+
38
+ rm -f "$NPMRC_TMP"
39
+ echo "Done."