← back to keywaysh__cli

Function bodies 191 total

All specs Real LLM only Function bodies
cmd.RunDeviceLogin function · go · L86-L188 (103 LOC)
internal/cmd/login.go
func RunDeviceLogin() (string, error) {
	ctx := context.Background()
	client := api.NewClient("")

	// Detect repo for better UX
	repo, _ := git.DetectRepo()

	// Get repo IDs for deep linking (best effort)
	repoIds := getRepoIdsWithFallback(ctx, repo)

	start, err := client.StartDeviceLogin(ctx, repo, repoIds)
	if err != nil {
		return "", fmt.Errorf("failed to start login: %w", err)
	}

	verifyURL := start.VerificationURIComplete
	if verifyURL == "" {
		verifyURL = start.VerificationURI
	}

	ui.Step(fmt.Sprintf("Code: %s", ui.Bold(start.UserCode)))
	ui.Message(ui.Dim(fmt.Sprintf("Open: %s", verifyURL)))
	ui.Message(ui.Dim("If the browser doesn't open, copy the URL above and paste it in your browser."))

	// Try to open browser (in goroutine to avoid blocking in headless/CLI environments)
	go func() {
		_ = browser.OpenURL(verifyURL)
	}()

	pollInterval := time.Duration(start.Interval) * time.Second
	if pollInterval < 3*time.Second {
		pollInterval = 5 * time.Second
	}

	timeout := ti
cmd.runLogout function · go · L258-L271 (14 LOC)
internal/cmd/login.go
func runLogout(cmd *cobra.Command, args []string) error {
	ui.Intro("logout")

	store := auth.NewStore()
	if err := store.ClearAuth(); err != nil {
		ui.Error(err.Error())
		return err
	}

	ui.Success("Logged out of Keyway")
	ui.Message(ui.Dim(fmt.Sprintf("Auth cache cleared: %s", store.GetConfigPath())))

	return nil
}
cmd.EnsureLogin function · go · L274-L298 (25 LOC)
internal/cmd/login.go
func EnsureLogin() (string, error) {
	// Check env var first
	if token := os.Getenv("KEYWAY_TOKEN"); token != "" {
		return token, nil
	}

	// Check stored auth
	store := auth.NewStore()
	storedAuth, err := store.GetAuth()
	if err == nil && storedAuth != nil && storedAuth.KeywayToken != "" {
		return storedAuth.KeywayToken, nil
	}

	// Need to login
	if !ui.IsInteractive() {
		return "", fmt.Errorf("no Keyway session found - run 'keyway login' to authenticate")
	}

	proceed, _ := ui.Confirm("No Keyway session found. Open browser to sign in?", true)
	if !proceed {
		return "", fmt.Errorf("login required")
	}

	return RunDeviceLogin()
}
cmd.trimSpace function · go · L301-L311 (11 LOC)
internal/cmd/login.go
func trimSpace(s string) string {
	start := 0
	end := len(s)
	for start < end && (s[start] == ' ' || s[start] == '\t' || s[start] == '\n' || s[start] == '\r') {
		start++
	}
	for end > start && (s[end-1] == ' ' || s[end-1] == '\t' || s[end-1] == '\n' || s[end-1] == '\r') {
		end--
	}
	return s[start:end]
}
cmd.init function · go · L21-L26 (6 LOC)
internal/cmd/pull.go
func init() {
	pullCmd.Flags().StringP("env", "e", "development", "Environment name")
	pullCmd.Flags().StringP("file", "f", ".env", "Env file to write to")
	pullCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompt")
	pullCmd.Flags().Bool("force", false, "Replace entire file instead of merging")
}
cmd.runPull function · go · L38-L48 (11 LOC)
internal/cmd/pull.go
func runPull(cmd *cobra.Command, args []string) error {
	opts := PullOptions{
		EnvFlagSet: cmd.Flags().Changed("env"),
	}
	opts.EnvName, _ = cmd.Flags().GetString("env")
	opts.File, _ = cmd.Flags().GetString("file")
	opts.Yes, _ = cmd.Flags().GetBool("yes")
	opts.Force, _ = cmd.Flags().GetBool("force")

	return runPullWithDeps(opts, defaultDeps)
}
cmd.init function · go · L22-L27 (6 LOC)
internal/cmd/push.go
func init() {
	pushCmd.Flags().StringP("env", "e", "", "Environment name")
	pushCmd.Flags().StringP("file", "f", "", "Env file to push")
	pushCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompt")
	pushCmd.Flags().Bool("prune", false, "Remove secrets from vault that are not in local file")
}
Repobility · code-quality intelligence · https://repobility.com
cmd.runPush function · go · L39-L49 (11 LOC)
internal/cmd/push.go
func runPush(cmd *cobra.Command, args []string) error {
	opts := PushOptions{
		EnvFlagSet: cmd.Flags().Changed("env"),
	}
	opts.EnvName, _ = cmd.Flags().GetString("env")
	opts.File, _ = cmd.Flags().GetString("file")
	opts.Yes, _ = cmd.Flags().GetBool("yes")
	opts.Prune, _ = cmd.Flags().GetBool("prune")

	return runPushWithDeps(opts, defaultDeps)
}
cmd.FindReadmePath function · go · L41-L50 (10 LOC)
internal/cmd/readme.go
func FindReadmePath(dir string) string {
	candidates := []string{"README.md", "readme.md", "Readme.md", "README.markdown", "readme.markdown"}
	for _, candidate := range candidates {
		path := filepath.Join(dir, candidate)
		if _, err := os.Stat(path); err == nil {
			return path
		}
	}
	return ""
}
cmd.findLastBadgeEnd function · go · L63-L86 (24 LOC)
internal/cmd/readme.go
func findLastBadgeEnd(line string) int {
	lastEnd := -1
	matches := badgePrefixRegex.FindAllStringIndex(line, -1)

	for _, match := range matches {
		prefixEnd := match[1] - 1 // Position of the opening (
		remainder := line[prefixEnd:]

		// Find matching closing parenthesis
		depth := 0
		for i, ch := range remainder {
			if ch == '(' {
				depth++
			} else if ch == ')' {
				depth--
				if depth == 0 {
					lastEnd = prefixEnd + i + 1
					break
				}
			}
		}
	}
	return lastEnd
}
cmd.InsertBadgeIntoReadme function · go · L89-L171 (83 LOC)
internal/cmd/readme.go
func InsertBadgeIntoReadme(content, badge string) string {
	// Check if badge already exists (check for both default and custom dashboard URLs)
	if strings.Contains(content, "badge.svg?repo=") {
		return content
	}

	lines := strings.Split(content, "\n")

	inCodeBlock := false
	inHTMLComment := false
	lastBadgeLine := -1
	lastBadgeEndIndex := -1
	firstH1Line := -1

	for i, line := range lines {
		trimmed := strings.TrimSpace(line)

		// Track code blocks
		if codeFencePattern.MatchString(trimmed) {
			inCodeBlock = !inCodeBlock
			continue
		}
		if inCodeBlock {
			continue
		}

		// Track HTML comments
		if strings.Contains(trimmed, "<!--") {
			inHTMLComment = true
		}
		if strings.Contains(trimmed, "-->") {
			inHTMLComment = false
			continue
		}
		if inHTMLComment {
			continue
		}

		// Check for existing badges
		if badgePrefixRegex.MatchString(line) {
			lastBadgeLine = i
			lastBadgeEndIndex = findLastBadgeEnd(line)
		}

		// Find first H1
		if firstH1Line == -1 && h1Pattern.M
cmd.AddBadgeToReadme function · go · L175-L246 (72 LOC)
internal/cmd/readme.go
func AddBadgeToReadme(silent bool) (bool, error) {
	repo, err := git.DetectRepo()
	if err != nil {
		return false, fmt.Errorf("not in a git repository")
	}

	cwd, err := os.Getwd()
	if err != nil {
		return false, err
	}

	readmePath := FindReadmePath(cwd)
	if readmePath == "" {
		// No README found
		createReadme := false

		if silent {
			// In silent mode (called from init), auto-create README
			createReadme = true
		} else if ui.IsInteractive() {
			createReadme, _ = ui.Confirm("No README found. Create README.md?", false)
			if !createReadme {
				ui.Warn("Skipping badge insertion (no README)")
				return false, nil
			}
		} else {
			// Non-interactive and not silent: skip
			return false, nil
		}

		if createReadme {
			// Get repo name for title
			parts := strings.Split(repo, "/")
			repoName := parts[len(parts)-1]

			readmePath = filepath.Join(cwd, "README.md")
			initialContent := fmt.Sprintf("# %s\n\n", repoName)
			if err := os.WriteFile(readmePath, []byte(initialContent)
cmd.runRoot function · go · L33-L64 (32 LOC)
internal/cmd/root.go
func runRoot(cmd *cobra.Command, args []string) error {
	// Check if running in non-interactive mode
	if !ui.IsInteractive() {
		printCustomHelp(cmd)
		return nil
	}

	// Check if user is logged in
	store := auth.NewStore()
	storedAuth, err := store.GetAuth()
	var token string
	isLoggedIn := false

	if err == nil && storedAuth != nil && storedAuth.KeywayToken != "" {
		isLoggedIn = true
		token = storedAuth.KeywayToken
	}

	// Also check env var
	if envToken := os.Getenv("KEYWAY_TOKEN"); envToken != "" {
		isLoggedIn = true
		token = envToken
	}

	if !isLoggedIn {
		// Not logged in: run full onboarding flow
		return runOnboarding(cmd)
	}

	// Logged in: show action menu (will check if vault exists)
	return runActionMenu(cmd, token)
}
cmd.runOnboarding function · go · L66-L84 (19 LOC)
internal/cmd/root.go
func runOnboarding(cmd *cobra.Command) error {
	ui.Intro("welcome")

	ui.Message("Let's set up Keyway for this project.")
	ui.Message("")

	// Check if we're in a git repo
	repo, err := git.DetectRepo()
	if err != nil {
		ui.Error("Not in a git repository with GitHub remote")
		ui.Message(ui.Dim("Navigate to your project folder and try again."))
		return err
	}

	ui.Step(fmt.Sprintf("Repository: %s", ui.Value(repo)))

	// Run init (which handles login, GitHub App, vault creation, and push)
	return runInit(initCmd, nil)
}
cmd.runActionMenu function · go · L86-L177 (92 LOC)
internal/cmd/root.go
func runActionMenu(cmd *cobra.Command, token string) error {
	fmt.Println()

	// Check current repo
	repo, err := git.DetectRepo()
	if err != nil {
		ui.Error("Not in a git repository with GitHub remote")
		ui.Message(ui.Dim("Navigate to your project folder and try again."))
		return err
	}
	if repo == "" {
		ui.Error("Could not detect GitHub remote")
		ui.Message(ui.Dim("Make sure this repo has a GitHub remote configured."))
		return fmt.Errorf("no GitHub remote found")
	}

	ui.Step(fmt.Sprintf("Repository: %s", ui.Value(repo)))

	// Check vault status (single API call)
	client := api.NewClient(token)
	ctx := context.Background()
	vaultDetails, err := client.GetVaultDetails(ctx, repo)

	if err != nil {
		// Check error type
		if apiErr, ok := err.(*api.APIError); ok {
			switch apiErr.StatusCode {
			case 401:
				// Token expired: clear and prompt re-login
				store := auth.NewStore()
				_ = store.ClearAuth()
				ui.Warn("Session expired")
				ui.Message(ui.Dim("Run: keyway login"))
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
cmd.printCustomHelp function · go · L179-L219 (41 LOC)
internal/cmd/root.go
func printCustomHelp(cmd *cobra.Command) {
	fmt.Println()
	fmt.Printf("  %s  %s\n", bold("keyway"), dim("— Sync secrets with your team and infra"))
	fmt.Println()

	// Core Commands
	fmt.Printf("  %s\n", bold("Core Commands:"))
	fmt.Printf("    %s           %s\n", cyan("keyway init"), "Initialize vault for this repo")
	fmt.Printf("    %s           %s\n", cyan("keyway push"), "Upload secrets to vault")
	fmt.Printf("    %s           %s\n", cyan("keyway pull"), "Download secrets from vault")
	fmt.Printf("    %s            %s\n", cyan("keyway set"), "Set a single secret in vault")
	fmt.Printf("    %s            %s\n", cyan("keyway run"), "Run command with injected secrets (Zero-Trust)")
	fmt.Printf("    %s           %s\n", cyan("keyway login"), "Sign in with GitHub")
	fmt.Println()

	// Provider Sync
	fmt.Printf("  %s\n", bold("Provider Sync:"))
	fmt.Printf("    %s        %s\n", cyan("keyway connect"), "Connect to Vercel, Railway...")
	fmt.Printf("    %s           %s\n", cyan("keyway sync"
cmd.Execute function · go · L222-L257 (36 LOC)
internal/cmd/root.go
func Execute(ver string) error {
	rootCmd.Version = ver

	// Start non-blocking version check
	updateChan := make(chan *version.UpdateInfo, 1)
	go func() {
		ctx, cancel := context.WithTimeout(context.Background(), version.CheckTimeout)
		defer cancel()
		info := version.CheckForUpdate(ctx, ver)
		updateChan <- info
	}()

	// Execute the command
	err := rootCmd.Execute()

	// Display error and help for unknown commands
	if err != nil {
		red := color.New(color.FgRed).SprintFunc()
		fmt.Fprintf(os.Stderr, "\n  %s %s\n", red("Error:"), err)
		fmt.Println()
		printCustomHelp(rootCmd)
		return err
	}

	// Display update notice if available (non-blocking receive)
	select {
	case info := <-updateChan:
		if info != nil && info.Available {
			displayUpdateNotice(info)
		}
	default:
		// Check not complete, don't wait
	}

	return nil
}
cmd.displayUpdateNotice function · go · L259-L274 (16 LOC)
internal/cmd/root.go
func displayUpdateNotice(info *version.UpdateInfo) {
	// Skip update notice for self-hosted instances (no update command)
	if info.UpdateCommand == "" {
		return
	}

	yellow := color.New(color.FgYellow).SprintFunc()
	fmt.Println()
	fmt.Printf("  %s Update available: %s → %s\n",
		yellow("!"),
		dim(info.CurrentVersion),
		bold(info.LatestVersion))
	fmt.Printf("  %s Run: %s\n",
		dim("→"),
		cyan(info.UpdateCommand))
}
cmd.init function · go · L276-L293 (18 LOC)
internal/cmd/root.go
func init() {
	// Add commands
	rootCmd.AddCommand(loginCmd)
	rootCmd.AddCommand(logoutCmd)
	rootCmd.AddCommand(initCmd)
	rootCmd.AddCommand(pushCmd)
	rootCmd.AddCommand(pullCmd)
	rootCmd.AddCommand(setCmd)
	rootCmd.AddCommand(doctorCmd)
	rootCmd.AddCommand(connectCmd)
	rootCmd.AddCommand(connectionsCmd)
	rootCmd.AddCommand(disconnectCmd)
	rootCmd.AddCommand(syncCmd)
	rootCmd.AddCommand(readmeCmd)
	rootCmd.AddCommand(diffCmd)
	rootCmd.AddCommand(scanCmd)
	rootCmd.AddCommand(runCmd)
}
cmd.runRunCmd function · go · L42-L55 (14 LOC)
internal/cmd/run.go
func runRunCmd(cmd *cobra.Command, args []string) error {
	if len(args) == 0 {
		return fmt.Errorf("command required")
	}

	opts := RunOptions{
		EnvFlagSet: cmd.Flags().Changed("env"),
		Command:    args[0],
		Args:       args[1:],
	}
	opts.EnvName, _ = cmd.Flags().GetString("env")

	return runRunWithDeps(opts, defaultDeps)
}
cmd.runRunWithDeps function · go · L58-L136 (79 LOC)
internal/cmd/run.go
func runRunWithDeps(opts RunOptions, deps *Dependencies) error {
	// 1. Detect Repo
	repo, err := deps.Git.DetectRepo()
	if err != nil {
		deps.UI.Error("Not in a git repository with GitHub remote")
		return err
	}

	// 2. Ensure Login
	token, err := deps.Auth.EnsureLogin()
	if err != nil {
		deps.UI.Error(err.Error())
		return err
	}

	// 3. Setup Client
	client := deps.APIFactory.NewClient(token)
	ctx := context.Background()

	// 4. Determine Environment
	envName := opts.EnvName

	if !opts.EnvFlagSet && deps.UI.IsInteractive() {
		// Fetch available environments
		vaultEnvs, err := client.GetVaultEnvironments(ctx, repo)
		if err != nil || len(vaultEnvs) == 0 {
			vaultEnvs = []string{"development", "staging", "production"}
		}

		// Find default index (development)
		defaultIdx := 0
		for i, e := range vaultEnvs {
			if e == "development" {
				defaultIdx = i
				break
			}
		}

		// Reorder to put default first
		if defaultIdx > 0 {
			vaultEnvs[0], vaultEnvs[defaultIdx] = vaultEnvs
cmd.runScan function · go · L223-L324 (102 LOC)
internal/cmd/scan.go
func runScan(cmd *cobra.Command, args []string) error {
	excludePatterns, _ := cmd.Flags().GetStringSlice("exclude")
	jsonOutput, _ := cmd.Flags().GetBool("json")

	// Determine scan path
	scanPath := "."
	if len(args) > 0 {
		scanPath = args[0]
	}

	// Resolve to absolute path
	absPath, err := filepath.Abs(scanPath)
	if err != nil {
		if !jsonOutput {
			ui.Error(fmt.Sprintf("Invalid path: %s", scanPath))
		}
		return err
	}

	// Check path exists
	if _, err := os.Stat(absPath); os.IsNotExist(err) {
		if !jsonOutput {
			ui.Error(fmt.Sprintf("Path does not exist: %s", scanPath))
		}
		return err
	}

	// Combine default and user excludes
	allExcludes := append(defaultExcludes, excludePatterns...)

	if !jsonOutput {
		ui.Intro("scan")
		ui.Step(fmt.Sprintf("Scanning %s", ui.File(absPath)))
	}

	// Perform scan
	var filesScanned int
	var findings []Finding

	if !jsonOutput {
		err = ui.Spin("Scanning files...", func() error {
			var scanErr error
			filesScanned, findings, scanErr = scan
cmd.scanDirectory function · go · L326-L375 (50 LOC)
internal/cmd/scan.go
func scanDirectory(root string, excludes []string) (int, []Finding, error) {
	var filesScanned int
	var findings []Finding

	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil // Skip files we can't access
		}

		// Get relative path for cleaner output
		relPath, _ := filepath.Rel(root, path)
		if relPath == "" {
			relPath = path
		}

		// Skip excluded directories
		if info.IsDir() {
			for _, exclude := range excludes {
				if info.Name() == exclude || strings.HasPrefix(relPath, exclude) {
					return filepath.SkipDir
				}
			}
			return nil
		}

		// Skip binary files
		ext := strings.ToLower(filepath.Ext(path))
		if binaryExtensions[ext] {
			return nil
		}

		// Skip large files (> 1MB)
		if info.Size() > 1024*1024 {
			return nil
		}

		// Scan file
		fileFindings, err := scanFile(path, relPath)
		if err != nil {
			return nil // Skip files we can't read
		}

		filesScanned++
		findings = append(findings, fileFindin
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
cmd.maskSecret function · go · L421-L429 (9 LOC)
internal/cmd/scan.go
func maskSecret(secret string) string {
	if len(secret) <= 10 {
		return strings.Repeat("*", len(secret))
	}

	// Show first 4 and last 3 characters
	masked := secret[:4] + strings.Repeat("*", len(secret)-7) + secret[len(secret)-3:]
	return masked
}
cmd.isFalsePositive function · go · L432-L475 (44 LOC)
internal/cmd/scan.go
func isFalsePositive(match, line, filePath string) bool {
	lowerLine := strings.ToLower(line)
	lowerMatch := strings.ToLower(match)
	lowerPath := strings.ToLower(filePath)

	// Skip test/example files
	if strings.Contains(lowerPath, "test") ||
		strings.Contains(lowerPath, "spec") ||
		strings.Contains(lowerPath, "example") ||
		strings.Contains(lowerPath, "mock") ||
		strings.Contains(lowerPath, "fixture") ||
		strings.Contains(lowerPath, ".example") ||
		strings.Contains(lowerPath, ".sample") {
		return true
	}

	// Skip placeholder values
	placeholders := []string{
		"xxx", "your", "example", "placeholder", "changeme",
		"insert", "replace", "todo", "fixme", "dummy",
		"test", "fake", "mock", "sample", "demo",
		"<your", "${", "{{", "ENV[", "process.env",
	}
	for _, p := range placeholders {
		if strings.Contains(lowerMatch, p) || strings.Contains(lowerLine, p) {
			return true
		}
	}

	// Skip if it looks like a variable reference
	if strings.Contains(line, "${") || strings.Contain
cmd.runSet function · go · L47-L69 (23 LOC)
internal/cmd/set.go
func runSet(cmd *cobra.Command, args []string) error {
	opts := SetOptions{
		EnvFlagSet: cmd.Flags().Changed("env"),
	}

	// Parse KEY or KEY=VALUE from first arg
	if strings.Contains(args[0], "=") {
		parts := strings.SplitN(args[0], "=", 2)
		opts.Key = parts[0]
		opts.Value = parts[1]
	} else {
		opts.Key = args[0]
		if len(args) > 1 {
			opts.Value = args[1]
		}
	}

	opts.EnvName, _ = cmd.Flags().GetString("env")
	opts.LocalOnly, _ = cmd.Flags().GetBool("local")
	opts.Yes, _ = cmd.Flags().GetBool("yes")

	return runSetWithDeps(opts, defaultDeps)
}
cmd.runSetWithDeps function · go · L72-L116 (45 LOC)
internal/cmd/set.go
func runSetWithDeps(opts SetOptions, deps *Dependencies) error {
	deps.UI.Intro("set")

	// Validate key
	if opts.Key == "" {
		deps.UI.Error("Key is required")
		return fmt.Errorf("key is required")
	}

	// Validate key format (alphanumeric and underscores only)
	for _, c := range opts.Key {
		if !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_') {
			deps.UI.Error("Key must contain only alphanumeric characters and underscores")
			return fmt.Errorf("invalid key format")
		}
	}

	deps.UI.Step(fmt.Sprintf("Key: %s", deps.UI.Value(opts.Key)))

	// Prompt for value if not provided
	if opts.Value == "" {
		if !deps.UI.IsInteractive() {
			deps.UI.Error("Value is required in non-interactive mode")
			return fmt.Errorf("value is required")
		}
		value, err := deps.UI.Password(fmt.Sprintf("Enter value for %s:", opts.Key))
		if err != nil {
			return err
		}
		if value == "" {
			deps.UI.Error("Value cannot be empty")
			return fmt.Errorf("value cannot b
cmd.runSetLocal function · go · L119-L161 (43 LOC)
internal/cmd/set.go
func runSetLocal(opts SetOptions, deps *Dependencies) error {
	envFile := ".env"

	// Read existing local file
	var localSecrets map[string]string
	if content, err := deps.FS.ReadFile(envFile); err == nil {
		localSecrets = env.Parse(string(content))
	} else {
		localSecrets = make(map[string]string)
	}

	// Check if key exists
	if existingValue, ok := localSecrets[opts.Key]; ok {
		if !opts.Yes {
			deps.UI.Warn(fmt.Sprintf("%s already exists in %s", opts.Key, envFile))
			deps.UI.Message(fmt.Sprintf("  Current: %s", deps.UI.Dim(maskValue(existingValue))))
			deps.UI.Message(fmt.Sprintf("  New:     %s", deps.UI.Value(maskValue(opts.Value))))

			if !deps.UI.IsInteractive() {
				deps.UI.Error("Use --yes to update existing secret in non-interactive mode")
				return fmt.Errorf("confirmation required")
			}

			confirm, _ := deps.UI.Confirm("Update this secret?", false)
			if !confirm {
				deps.UI.Warn("Aborted.")
				return nil
			}
		}
	}

	// Update and write
	localSecrets[opts.Key]
cmd.runSetRemote function · go · L164-L331 (168 LOC)
internal/cmd/set.go
func runSetRemote(opts SetOptions, deps *Dependencies) error {
	// Detect repo
	repo, err := deps.Git.DetectRepo()
	if err != nil {
		deps.UI.Error("Not in a git repository with GitHub remote")
		return err
	}
	deps.UI.Step(fmt.Sprintf("Repository: %s", deps.UI.Value(repo)))

	// Ensure logged in
	token, err := deps.Auth.EnsureLogin()
	if err != nil {
		deps.UI.Error(err.Error())
		return err
	}

	client := deps.APIFactory.NewClient(token)
	ctx := context.Background()

	envName := opts.EnvName

	// Default to development if not specified
	if envName == "" {
		if !opts.EnvFlagSet && deps.UI.IsInteractive() {
			// Fetch available environments
			vaultEnvs, err := client.GetVaultEnvironments(ctx, repo)
			if err != nil || len(vaultEnvs) == 0 {
				vaultEnvs = []string{"development", "staging", "production"}
			}

			selected, err := deps.UI.Select("Environment:", vaultEnvs)
			if err != nil {
				return err
			}
			envName = selected
		} else {
			envName = "development"
		}
	}

	deps.UI
cmd.formatEnvContent function · go · L334-L346 (13 LOC)
internal/cmd/set.go
func formatEnvContent(secrets map[string]string) string {
	keys := make([]string, 0, len(secrets))
	for k := range secrets {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var lines []string
	for _, k := range keys {
		lines = append(lines, fmt.Sprintf("%s=%s", k, secrets[k]))
	}
	return strings.Join(lines, "\n") + "\n"
}
cmd.init function · go · L43-L52 (10 LOC)
internal/cmd/sync.go
func init() {
	syncCmd.Flags().Bool("push", false, "Push secrets from Keyway to provider")
	syncCmd.Flags().Bool("pull", false, "Pull secrets from provider to Keyway")
	syncCmd.Flags().StringP("env", "e", "", "Keyway environment (default: production)")
	syncCmd.Flags().String("provider-env", "", "Provider environment (auto-mapped if not specified)")
	syncCmd.Flags().StringP("project", "p", "", "Provider project name or ID")
	syncCmd.Flags().String("team", "", "Filter by team/organization")
	syncCmd.Flags().Bool("allow-delete", false, "Allow deleting secrets during push")
	syncCmd.Flags().BoolP("yes", "y", false, "Skip confirmation prompts")
}
Source: Repobility analyzer · https://repobility.com
cmd.mapToProviderEnvironment function · go · L55-L82 (28 LOC)
internal/cmd/sync.go
func mapToProviderEnvironment(provider, keywayEnv string) string {
	switch strings.ToLower(provider) {
	case "vercel":
		mapping := map[string]string{
			"production":  "production",
			"staging":     "preview",
			"dev":         "development",
			"development": "development",
		}
		if env, ok := mapping[strings.ToLower(keywayEnv)]; ok {
			return env
		}
		return "production"
	case "railway":
		mapping := map[string]string{
			"production":  "production",
			"staging":     "staging",
			"dev":         "development",
			"development": "development",
		}
		if env, ok := mapping[strings.ToLower(keywayEnv)]; ok {
			return env
		}
		return "production"
	default:
		return keywayEnv
	}
}
cmd.getProjectDisplayName function · go · L97-L102 (6 LOC)
internal/cmd/sync.go
func getProjectDisplayName(p ProjectWithLinkedRepo) string {
	if p.ServiceName != nil && *p.ServiceName != "" {
		return *p.ServiceName
	}
	return p.Name
}
cmd.projectMatchesRepo function · go · L104-L117 (14 LOC)
internal/cmd/sync.go
func projectMatchesRepo(project ProjectWithLinkedRepo, repoFullName string) bool {
	repoLower := strings.ToLower(repoFullName)
	repoName := strings.ToLower(strings.Split(repoFullName, "/")[1])

	if project.LinkedRepo != nil && strings.ToLower(*project.LinkedRepo) == repoLower {
		return true
	}

	if strings.ToLower(project.Name) == repoName {
		return true
	}

	return false
}
cmd.findMatchingProject function · go · L124-L160 (37 LOC)
internal/cmd/sync.go
func findMatchingProject(projects []ProjectWithLinkedRepo, repoFullName string) *projectMatch {
	repoLower := strings.ToLower(repoFullName)
	parts := strings.Split(repoFullName, "/")
	if len(parts) != 2 {
		return nil
	}
	repoName := strings.ToLower(parts[1])

	// Priority 1: Linked repo exact match
	for _, p := range projects {
		if p.LinkedRepo != nil && strings.ToLower(*p.LinkedRepo) == repoLower {
			return &projectMatch{Project: p, MatchType: "linked_repo"}
		}
	}

	// Priority 2: Exact name match
	for _, p := range projects {
		if strings.ToLower(p.Name) == repoName {
			return &projectMatch{Project: p, MatchType: "exact_name"}
		}
	}

	// Priority 3: Partial match (only if unique)
	var partialMatches []ProjectWithLinkedRepo
	for _, p := range projects {
		nameLower := strings.ToLower(p.Name)
		if strings.Contains(nameLower, repoName) || strings.Contains(repoName, nameLower) {
			partialMatches = append(partialMatches, p)
		}
	}

	if len(partialMatches) == 1 {
		return &projectMa
cmd.ensureProvider function · go · L163-L206 (44 LOC)
internal/cmd/sync.go
func ensureProvider(ctx context.Context, client *api.Client, args []string) (string, error) {
	if len(args) > 0 {
		return strings.ToLower(args[0]), nil
	}

	// No provider specified - show list
	providers, err := client.GetProviders(ctx)
	if err != nil {
		if apiErr, ok := err.(*api.APIError); ok {
			if apiErr.StatusCode == 401 {
				ui.Error("Authentication failed. Please login again.")
				ui.Message(ui.Dim("Run: keyway login"))
				return "", err
			}
			ui.Error(fmt.Sprintf("Failed to fetch providers: %s", apiErr.Error()))
		} else {
			ui.Error(fmt.Sprintf("Failed to fetch providers: %v", err))
		}
		return "", err
	}

	if len(providers) == 0 {
		ui.Error("No providers available")
		return "", fmt.Errorf("no providers")
	}

	options := make([]string, len(providers))
	for i, p := range providers {
		options[i] = p.DisplayName
	}

	selected, err := ui.Select("Select a provider to sync with:", options)
	if err != nil {
		return "", err
	}

	for _, p := range providers {
		if p.Disp
cmd.ensureVaultExists function · go · L209-L242 (34 LOC)
internal/cmd/sync.go
func ensureVaultExists(ctx context.Context, client *api.Client, repo string) error {
	exists, err := client.CheckVaultExists(ctx, repo)
	if err != nil {
		ui.Error("Failed to check vault")
		return err
	}

	if exists {
		return nil
	}

	ui.Warn(fmt.Sprintf("No vault found for %s.", repo))

	if !ui.IsInteractive() {
		return fmt.Errorf("vault not found")
	}

	shouldCreate, _ := ui.Confirm("Create vault now?", true)
	if !shouldCreate {
		return errVaultCreationCancelled
	}

	err = ui.Spin("Creating vault...", func() error {
		_, err := client.InitVault(ctx, repo)
		return err
	})
	if err != nil {
		ui.Error("Failed to create vault")
		return err
	}

	ui.Success("Vault created!")
	return nil
}
cmd.ensureProviderConnection function · go · L246-L284 (39 LOC)
internal/cmd/sync.go
func ensureProviderConnection(ctx context.Context, client *api.Client, provider, providerDisplayName string) ([]api.ProviderProject, []api.Connection, error) {
	allProjects, connections, err := client.GetAllProviderProjects(ctx, provider)

	notConnected := err != nil && (strings.Contains(err.Error(), "not connected") || strings.Contains(err.Error(), "no connections"))
	notConnected = notConnected || (err == nil && len(connections) == 0)

	if !notConnected {
		if err != nil {
			ui.Error("Failed to fetch provider projects")
			return nil, nil, err
		}
		return allProjects, connections, nil
	}

	ui.Warn(fmt.Sprintf("Not connected to %s.", providerDisplayName))

	if !ui.IsInteractive() {
		ui.Message(ui.Dim(fmt.Sprintf("Run `keyway connect %s` first.", provider)))
		return nil, nil, fmt.Errorf("not connected to provider")
	}

	shouldConnect, _ := ui.Confirm(fmt.Sprintf("Connect to %s now?", providerDisplayName), true)
	if !shouldConnect {
		return nil, nil, errConnectionCancelled
	}

	if 
cmd.selectSyncProject function · go · L287-L359 (73 LOC)
internal/cmd/sync.go
func selectSyncProject(projects []ProjectWithLinkedRepo, projectFlag, repo, providerDisplayName string, hasMultipleConnections bool) (ProjectWithLinkedRepo, error) {
	if projectFlag != "" {
		projectLower := strings.ToLower(projectFlag)
		for _, p := range projects {
			if p.ID == projectFlag ||
				strings.ToLower(p.Name) == projectLower ||
				(p.ServiceName != nil && strings.ToLower(*p.ServiceName) == projectLower) {
				if !projectMatchesRepo(p, repo) {
					ui.Warn("Project does not match current repository")
					yellow := color.New(color.FgYellow)
					yellow.Printf("Current repo:      %s\n", repo)
					yellow.Printf("Selected project:  %s\n", getProjectDisplayName(p))
				}
				return p, nil
			}
		}
		ui.Error(fmt.Sprintf("Project not found: %s", projectFlag))
		ui.Message(ui.Dim("Available projects:"))
		for _, p := range projects {
			ui.Message(ui.Dim(fmt.Sprintf("  - %s", getProjectDisplayName(p))))
		}
		return ProjectWithLinkedRepo{}, fmt.Errorf("project not found")
	}

Repobility · code-quality intelligence · https://repobility.com
cmd.selectSyncEnvironments function · go · L362-L415 (54 LOC)
internal/cmd/sync.go
func selectSyncEnvironments(ctx context.Context, client *api.Client, repo string, project ProjectWithLinkedRepo, envFlag, providerEnvFlag, provider, providerDisplayName string) (keywayEnv, providerEnv string, err error) {
	keywayEnv = envFlag
	providerEnv = providerEnvFlag

	if keywayEnv == "" && ui.IsInteractive() {
		vaultEnvs, err := client.GetVaultEnvironments(ctx, repo)
		if err != nil || len(vaultEnvs) == 0 {
			vaultEnvs = []string{"production", "staging", "development"}
		}

		selected, err := ui.Select("Keyway environment:", vaultEnvs)
		if err != nil {
			return "", "", err
		}
		keywayEnv = selected

		// Auto-map provider environment if not specified
		if providerEnv == "" {
			if len(project.Environments) > 0 {
				mapped := mapToProviderEnvironment(provider, keywayEnv)
				found := false
				for _, e := range project.Environments {
					if strings.EqualFold(e, mapped) {
						providerEnv = mapped
						found = true
						break
					}
				}
				if !found && len(project.Env
cmd.promptProjectSelection function · go · L659-L714 (56 LOC)
internal/cmd/sync.go
func promptProjectSelection(projects []ProjectWithLinkedRepo, repoFullName, providerDisplayName string, hasMultipleAccounts bool) (ProjectWithLinkedRepo, error) {
	repoName := strings.ToLower(strings.Split(repoFullName, "/")[1])

	options := make([]string, len(projects))
	for i, p := range projects {
		displayName := getProjectDisplayName(p)
		label := displayName

		var badges []string

		// Add team info if multiple accounts
		if hasMultipleAccounts {
			if p.TeamName != nil {
				badges = append(badges, color.CyanString("[%s]", *p.TeamName))
			} else if p.TeamID != nil {
				shortID := *p.TeamID
				if len(shortID) > 12 {
					shortID = shortID[:12] + "..."
				}
				badges = append(badges, color.CyanString("[team:%s]", shortID))
			} else {
				badges = append(badges, color.CyanString("[personal]"))
			}
		}

		// Add match badges
		if p.LinkedRepo != nil && strings.EqualFold(*p.LinkedRepo, repoFullName) {
			badges = append(badges, color.GreenString("← linked"))
		} else if strin
cmd.displayDiffSummary function · go · L716-L767 (52 LOC)
internal/cmd/sync.go
func displayDiffSummary(diff *api.SyncDiff, providerName string) {
	totalDiff := len(diff.OnlyInKeyway) + len(diff.OnlyInProvider) + len(diff.Different)

	if totalDiff == 0 && len(diff.Same) > 0 {
		ui.Success(fmt.Sprintf("Already in sync (%d secrets)", len(diff.Same)))
		return
	}

	ui.Step("Comparison Summary")
	ui.Message(ui.Dim(fmt.Sprintf("Keyway: %d secrets | %s: %d secrets", diff.KeywayCount, providerName, diff.ProviderCount)))

	cyan := color.New(color.FgCyan)
	magenta := color.New(color.FgMagenta)
	yellow := color.New(color.FgYellow)

	if len(diff.OnlyInKeyway) > 0 {
		cyan.Printf("→ %d only in Keyway\n", len(diff.OnlyInKeyway))
		for i, key := range diff.OnlyInKeyway {
			if i >= 3 {
				ui.Message(ui.Dim(fmt.Sprintf("  ... and %d more", len(diff.OnlyInKeyway)-3)))
				break
			}
			ui.Message(ui.Dim(fmt.Sprintf("  %s", key)))
		}
	}

	if len(diff.OnlyInProvider) > 0 {
		magenta.Printf("← %d only in %s\n", len(diff.OnlyInProvider), providerName)
		for i, key := range diff.Onl
cmd.executeSyncOperation function · go · L769-L903 (135 LOC)
internal/cmd/sync.go
func executeSyncOperation(client *api.Client, ctx context.Context, repo string, project ProjectWithLinkedRepo, keywayEnv, providerEnv, direction string, allowDelete, skipConfirm bool, provider string) error {
	providerName := cases.Title(language.English).String(provider)

	// Get preview
	var preview *api.SyncPreview
	err := ui.Spin("Generating preview...", func() error {
		var err error
		preview, err = client.GetSyncPreview(ctx, repo, api.SyncOptions{
			ConnectionID:        project.ConnectionID,
			ProjectID:           project.ID,
			ServiceID:           project.ServiceID,
			KeywayEnvironment:   keywayEnv,
			ProviderEnvironment: providerEnv,
			Direction:           direction,
			AllowDelete:         allowDelete,
		})
		return err
	})
	if err != nil {
		ui.Error("Failed to generate preview")
		return err
	}

	totalChanges := len(preview.ToCreate) + len(preview.ToUpdate) + len(preview.ToDelete)

	if totalChanges == 0 {
		ui.Success("Already in sync. No changes needed.")
		return ni
config.GetAPIURL function · go · L23-L28 (6 LOC)
internal/config/config.go
func GetAPIURL() string {
	if url := os.Getenv("KEYWAY_API_URL"); url != "" {
		return url
	}
	return DefaultAPIURL
}
config.GetDashboardURL function · go · L31-L36 (6 LOC)
internal/config/config.go
func GetDashboardURL() string {
	if url := os.Getenv("KEYWAY_DASHBOARD_URL"); url != "" {
		return url
	}
	return DefaultDashboardURL
}
config.GetPostHogHost function · go · L39-L44 (6 LOC)
internal/config/config.go
func GetPostHogHost() string {
	if host := os.Getenv("KEYWAY_POSTHOG_HOST"); host != "" {
		return host
	}
	return DefaultPostHogHost
}
config.GetPostHogKey function · go · L47-L52 (6 LOC)
internal/config/config.go
func GetPostHogKey() string {
	if key := os.Getenv("KEYWAY_POSTHOG_KEY"); key != "" {
		return key
	}
	return PostHogKey
}
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
config.GetGitHubURL function · go · L72-L77 (6 LOC)
internal/config/config.go
func GetGitHubURL() string {
	if url := os.Getenv("KEYWAY_GITHUB_URL"); url != "" {
		return strings.TrimSuffix(url, "/")
	}
	return DefaultGitHubBaseURL
}
config.GetGitHubAPIURL function · go · L80-L91 (12 LOC)
internal/config/config.go
func GetGitHubAPIURL() string {
	if url := os.Getenv("KEYWAY_GITHUB_API_URL"); url != "" {
		return strings.TrimSuffix(url, "/")
	}
	// If KEYWAY_GITHUB_URL is set (GHE), derive API URL from it
	if ghURL := os.Getenv("KEYWAY_GITHUB_URL"); ghURL != "" {
		ghURL = strings.TrimSuffix(ghURL, "/")
		// For GHE: https://github.example.com -> https://github.example.com/api/v3
		return ghURL + "/api/v3"
	}
	return DefaultGitHubAPIURL
}
config.GetDocsURL function · go · L100-L105 (6 LOC)
internal/config/config.go
func GetDocsURL() string {
	if url := os.Getenv("KEYWAY_DOCS_URL"); url != "" {
		return url
	}
	return DefaultDocsURL
}
‹ prevpage 3 / 4next ›