From 5af0b059e6fa9bec3f0c4210269f26a2e90882a4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Oct 2025 04:29:18 +0000 Subject: [PATCH 1/2] Initial plan From 61b6ac2c9e91449ebc609e054e797a960fae76a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Oct 2025 04:34:06 +0000 Subject: [PATCH 2/2] Fix README italic markdown documentation and apply go fmt Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> --- README.md | 2 +- main.go | 20 ++++++++++---------- main_test.go | 16 ++++++++-------- markdown.go | 6 +++--- mcp_test.go | 6 +++--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 53c9212..6781f9a 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ slack send-message alex_collins@intuit.com "**Bold**, *italic*, ~~strikethrough~ Messages automatically convert Markdown to Slack's Mrkdwn format. Supported features: - **Bold**: `**text**` or `__text__` → `*text*` -- **Italic**: `*text*` → `_text_` +- **Italic**: `*text*` or `_text_` → `_text_` (single underscores already in Mrkdwn format) - **Strikethrough**: `~~text~~` → `~text~` - **Inline code**: `` `code` `` (unchanged) - **Links**: `[text](url)` → `` diff --git a/main.go b/main.go index 8c8178e..ce9be2a 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func run(ctx context.Context, args []string) error { if len(args) < 3 { return fmt.Errorf("usage: slack send-message [thread-ts]") } - + token := getToken() if token == "" { return fmt.Errorf("Slack token must be set (use 'slack configure' or set SLACK_TOKEN env var)") @@ -65,13 +65,13 @@ func run(ctx context.Context, args []string) error { // disable HTTP/2 support as it causes issues with some proxies http.DefaultTransport.(*http.Transport).ForceAttemptHTTP2 = false api := slack.New(token) - + // Check if optional thread-ts parameter is provided for replying to a thread var timestamp string if len(args) >= 4 { timestamp = args[3] } - + _, err := sendMessage(ctx, api, args[1], args[2], timestamp) return err default: @@ -84,12 +84,12 @@ func getToken() string { if token := os.Getenv("SLACK_TOKEN"); token != "" { return token } - + keyringToken, err := keyring.Get(keyringService, keyringUser) if err == nil && keyringToken != "" { return keyringToken } - + return "" } @@ -110,7 +110,7 @@ func sendMessage(ctx context.Context, api *slack.Client, identifier, body, times // Build message options options := []slack.MsgOption{slack.MsgOptionText(mrkdwnBody, false)} - + // If timestamp is provided, add it to create a threaded reply if timestamp != "" { options = append(options, slack.MsgOptionTS(timestamp)) @@ -127,7 +127,7 @@ func sendMessage(ctx context.Context, api *slack.Client, identifier, body, times fmt.Printf("Message sent to %s (%s)\n", identifier, channel) fmt.Printf("thread-ts: %s\n", respTimestamp) } - + return respTimestamp, nil } @@ -135,15 +135,15 @@ func configureToken(ctx context.Context) error { fmt.Fprintln(os.Stderr, "To get your Slack API token, visit: https://api.slack.com/apps") fmt.Fprintln(os.Stderr, "Create an app, install it to your workspace, and copy the Bot User OAuth Token") fmt.Fprint(os.Stderr, "Enter your Slack API token: ") - + var token string - + // Check if stdin is a terminal if term.IsTerminal(int(os.Stdin.Fd())) { // Read password without echoing to terminal tokenBytes, err := term.ReadPassword(int(os.Stdin.Fd())) fmt.Fprintln(os.Stderr) // Print newline after password input - + if err != nil { return fmt.Errorf("failed to read token: %w", err) } diff --git a/main_test.go b/main_test.go index 5efb425..10bd09d 100644 --- a/main_test.go +++ b/main_test.go @@ -28,11 +28,11 @@ func TestConfigure_WhitespaceToken(t *testing.T) { func TestRun_MissingSubCommand(t *testing.T) { ctx := context.Background() err := run(ctx, []string{}) - + if err == nil { t.Error("Expected error for missing sub-command, got nil") } - + if !strings.Contains(err.Error(), "missing sub-command") { t.Errorf("Expected 'missing sub-command' error, got: %v", err) } @@ -52,11 +52,11 @@ func TestRun_UnknownSubCommand(t *testing.T) { ctx := context.Background() err := run(ctx, []string{"unknown-command"}) - + if err == nil { t.Error("Expected error for unknown sub-command, got nil") } - + if !strings.Contains(err.Error(), "unknown sub-command") { t.Errorf("Expected 'unknown sub-command' error, got: %v", err) } @@ -83,7 +83,7 @@ func TestRun_SendMessageMissingArgs(t *testing.T) { }() ctx := context.Background() - + // Test with no arguments err := run(ctx, []string{"send-message"}) if err == nil { @@ -92,7 +92,7 @@ func TestRun_SendMessageMissingArgs(t *testing.T) { if !strings.Contains(err.Error(), "usage:") { t.Errorf("Expected usage error, got: %v", err) } - + // Test with only channel err = run(ctx, []string{"send-message", "C1234567890"}) if err == nil { @@ -115,11 +115,11 @@ func TestRun_SendMessageMissingToken(t *testing.T) { ctx := context.Background() err := run(ctx, []string{"send-message", "C1234567890", "test message"}) - + if err == nil { t.Error("Expected error for missing token, got nil") } - + if !strings.Contains(err.Error(), "Slack token must be set") { t.Errorf("Expected 'Slack token must be set' error, got: %v", err) } diff --git a/markdown.go b/markdown.go index 94b9968..6eaf9a5 100644 --- a/markdown.go +++ b/markdown.go @@ -12,10 +12,10 @@ func convertMarkdownToMrkdwn(markdown string) string { // Placeholder to protect already-converted bold text const boldPlaceholder = "\x00BOLD\x00" - + // Store bold conversions with placeholders boldMatches := []string{} - + // Convert bold: **text** or __text__ -> placeholder boldPattern := regexp.MustCompile(`\*\*(.+?)\*\*`) text = boldPattern.ReplaceAllStringFunc(text, func(match string) string { @@ -27,7 +27,7 @@ func convertMarkdownToMrkdwn(markdown string) string { } return match }) - + boldUnderscorePattern := regexp.MustCompile(`__(.+?)__`) text = boldUnderscorePattern.ReplaceAllStringFunc(text, func(match string) string { content := boldUnderscorePattern.FindStringSubmatch(match) diff --git a/mcp_test.go b/mcp_test.go index f2a9bcf..261f1bb 100644 --- a/mcp_test.go +++ b/mcp_test.go @@ -22,7 +22,7 @@ func TestRun_MCPServer(t *testing.T) { // Test that mcp-server sub-command is recognized (won't actually run the server in this test) // We would need to mock stdin/stdout to fully test this args := []string{"mcp-server"} - + // We can't easily test the full server without mocking stdin/stdout // but we can verify the command is recognized and doesn't return "unknown sub-command" _ = args @@ -41,11 +41,11 @@ func TestRun_MCPServerMissingToken(t *testing.T) { ctx := context.Background() err := run(ctx, []string{"mcp-server"}) - + if err == nil { t.Error("Expected error for missing token, got nil") } - + if !strings.Contains(err.Error(), "Slack token must be set") { t.Errorf("Expected 'Slack token must be set' error, got: %v", err) }