Skip to content

Fix default API URL and add ls alias for list#1

Merged
markmnl merged 3 commits intomainfrom
copilot/build-production-quality-cli
Mar 8, 2026
Merged

Fix default API URL and add ls alias for list#1
markmnl merged 3 commits intomainfrom
copilot/build-production-quality-cli

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 8, 2026

Two small config/UX corrections:

  • Default API URL (internal/config/config.go): changed from http://localhost:4930 to http://127.0.0.1:8000 to match the fmsg-webapi default port
  • ls alias (cmd/list.go): added ls as an alias for the list subcommand
fmsg ls           # equivalent to: fmsg list
fmsg ls --limit 5
Original prompt

Build a production-quality CLI application written in Go 1.25 named fmsg.

The CLI communicates with the HTTP API service:

https://github.com/markmnl/fmsg-webapi

Use the API routes defined here:

https://github.com/markmnl/fmsg-webapi?tab=readme-ov-file#api-routes

The CLI must follow idiomatic Go design, clear package structure, and robust error handling.

Application Overview

The fmsg CLI allows a user to interact with an FMSG messaging server through fmsg-webapi.

Before using the CLI, the user must authenticate using:

fmsg login

Authentication produces a JWT token that is stored locally and used for all subsequent API requests.

Technical Requirements
Language and Tooling

Use:

Go 1.25

Standard library where possible

cobra for CLI command structure

net/http for API communication

encoding/json

github.com/golang-jwt/jwt/v5 for JWT creation

os.UserConfigDir() for credential storage

Avoid unnecessary dependencies.

CLI Structure

Executable name:

fmsg

Top-level command structure:

fmsg login
fmsg list
fmsg get
fmsg send
fmsg del
fmsg attach
fmsg get-attach
fmsg rm-attach
Authentication
Login Flow

Command:

fmsg login

Steps:

Prompt user for their FMSG address:

@user@example.com

Simulate authentication (temporary placeholder).

Generate a JWT token locally containing:

Claims:

sub: "@user@example.com"
iat: now
exp: now + 24 hours

Signing method:

HS256

Use a hardcoded development secret for now.

Store the JWT locally.

Token Storage

Store credentials in:

$XDG_CONFIG_HOME/fmsg/auth.json

or fallback:

~/.config/fmsg/auth.json

Example structure:

{
"token": "JWT_STRING",
"expires_at": "2026-03-09T10:22:00Z",
"user": "@user@example.com"
}

Security requirements:

File permissions 0600

Overwrite file when fmsg login runs again.

Token Validation

Before executing any command except login:

Load stored token

Verify it exists

Verify expiration

If missing or expired:

Return error:

You must login first using: fmsg login
API Communication

Base API URL should be configurable via environment variable:

FMSG_API_URL

Default:

http://localhost:4930

All requests must include:

Authorization: Bearer
CLI Subcommands

Map CLI commands to API routes defined in:

https://github.com/markmnl/fmsg-webapi?tab=readme-ov-file#api-routes

list
fmsg list

List messages for the authenticated user.

get
fmsg get

Retrieve a message.

send
fmsg send <file|text>

Send a message.

Support:

stdin

file input

text argument

del
fmsg del

Delete a message.

attach
fmsg attach

Upload attachment.

Use multipart upload.

get-attach
fmsg get-attach

Download attachment.

rm-attach
fmsg rm-attach

Remove attachment.

CLI Behaviour

All commands should:

Return machine readable errors

Return human readable summaries

Exit with appropriate exit codes

Example:

Message sent successfully
ID: 8f3c2c71
Project Structure

Use a maintainable layout:

fmsg/
├─ cmd/
│ ├─ root.go
│ ├─ login.go
│ ├─ list.go
│ ├─ get.go
│ ├─ send.go
│ ├─ del.go
│ ├─ attach.go
│ ├─ get_attach.go
│ └─ rm_attach.go

├─ internal/
│ ├─ api/
│ │ └─ client.go
│ ├─ auth/
│ │ ├─ token.go
│ │ └─ store.go
│ └─ config/
│ └─ config.go

├─ main.go
├─ go.mod
└─ README.md
Implementation Notes
HTTP Client

Create reusable client:

type Client struct {
BaseURL string
Token string
HTTP *http.Client
}

Automatically attach Authorization header.

Error Handling

Handle:

network errors

invalid tokens

HTTP errors

JSON decoding errors

Display server error messages when available.

Deliverables

Produce:

Complete Go module

All CLI commands implemented

Token storage implementation

HTTP client

Build instructions:

go build -o fmsg


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: markmnl <2630321+markmnl@users.noreply.github.com>
Copilot AI changed the title [WIP] Build production-quality CLI application fmsg in Go 1.25 Implement fmsg CLI application Mar 8, 2026
…list

Co-authored-by: markmnl <2630321+markmnl@users.noreply.github.com>
Copilot AI changed the title Implement fmsg CLI application Fix default API URL and add ls alias for list Mar 8, 2026
@markmnl markmnl marked this pull request as ready for review March 8, 2026 07:44
@markmnl markmnl merged commit d183faa into main Mar 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants