Skip to content

Commit 10c391a

Browse files
committed
update extension API
1 parent 27707da commit 10c391a

File tree

15 files changed

+117
-45
lines changed

15 files changed

+117
-45
lines changed

extensions/bitwarden.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
set -euo pipefail
3+
set -eo pipefail
44

55
# check if jq is installed
66
if ! [ -x "$(command -v jq)" ]; then

extensions/extensions.sh

+9-11
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22

33
set -euo pipefail
44

5-
EXTENSIONS_DIR="${SUNBEAM_EXTENSIONS_DIR:-$HOME/.config/sunbeam/extensions}"
65

76
if [ $# -eq 0 ]; then
8-
jq -n --arg dir "$EXTENSIONS_DIR" '{
7+
jq -n '{
98
title: "Sunbeam",
109
actions: [
11-
{ title: "Search Extensions", type: "run", command: "ls" },
12-
{ title: "Open Extensions Dir", type: "open", target: $dir }
10+
{ title: "Search Extensions", type: "run", command: "ls" }
1311
],
1412
commands: [
1513
{ name: "ls", mode: "filter" },
@@ -23,18 +21,18 @@ COMMAND=$1
2321
PARAMS=$(cat)
2422

2523
if [ "$COMMAND" = "ls" ]; then
26-
find "$EXTENSIONS_DIR" -type f -or -type l | jq --arg dir "$EXTENSIONS_DIR" -R '{
27-
title: (. | split("/") | last),
24+
sunbeam| jq '.[] |{
25+
title: .name,
2826
accessories: [
29-
.
27+
.entrypoint
3028
],
3129
actions: [
32-
{ title: "Open extension", type: "open", target: . },
33-
{ title: "Copy Path", type: "copy", text: . },
34-
{ title: "Remove Extension", type: "run", command: "rm", params: { path: . }, reload: true }
30+
{ title: "Open extension", type: "open", target: .entrypoint },
31+
{ title: "Copy Path", type: "copy", text: .entrypoint },
32+
{ title: "Remove Extension", type: "run", command: "rm", params: { path: .entrypoint }, reload: true }
3533
]
3634
}' | jq -s '{ items: . }'
3735
elif [ "$COMMAND" = "rm" ]; then
3836
EXTENSION_PATH=$(jq -r '.path' <<< "$PARAMS")
39-
rm -r "$EXTENSION_PATH"
37+
rm "$EXTENSION_PATH"
4038
fi

extensions/rss.ts

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ const manifest = {
1515
command: "show",
1616
params: { url: "https://jvns.ca/atom.xml" },
1717
},
18+
{
19+
title: "Hackers News Replies",
20+
type: "run",
21+
command: "show",
22+
params: { url: "https://hnrss.org/replies?id=pomdtr" },
23+
},
1824
],
1925
commands: [
2026
{

extensions/tldr.sh

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ set -eu
1010
if [ $# -eq 0 ]; then
1111
jq -n '
1212
{
13-
title: "Browse TLDR Pages",
14-
description: "Browse TLDR Pages",
13+
title: "TLDR Pages",
1514
actions: [
16-
{ title: "List Pages", type: "run", command: "list" }
15+
{ title: "Search Pages", type: "run", command: "list" }
1716
],
1817
# each command can be called through the cli
1918
commands: [

internal/cli/edit.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func completeExtension(cmd *cobra.Command, args []string, toComplete string) ([]
4848

4949
var completions []string
5050
for _, extension := range extensions {
51-
completions = append(completions, fmt.Sprintf("%s\t%s", extension.Name, extension.Entrypoint))
51+
completions = append(completions, fmt.Sprintf("%s\t%s", extension.Name, extension.Title))
5252
}
5353

5454
return completions, cobra.ShellCompDirectiveNoFileComp

internal/cli/ls.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/pomdtr/sunbeam/internal/utils"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func NewCmdLs() *cobra.Command {
12+
return &cobra.Command{
13+
Use: "ls",
14+
Short: "List all extensions",
15+
Run: func(cmd *cobra.Command, args []string) {
16+
exts, err := LoadExtensions(utils.ExtensionsDir(), false)
17+
if err != nil {
18+
fmt.Fprintf(os.Stderr, "error: %s\n", err)
19+
os.Exit(1)
20+
}
21+
22+
for _, ext := range exts {
23+
cmd.Println(ext.Name)
24+
}
25+
},
26+
}
27+
}

internal/cli/reload.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/pomdtr/sunbeam/internal/extensions"
7+
"github.com/pomdtr/sunbeam/internal/utils"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
func NewCmdReload() *cobra.Command {
12+
return &cobra.Command{
13+
Use: "reload <extension>",
14+
Short: "Reload an extension",
15+
Args: cobra.ExactArgs(1),
16+
ValidArgsFunction: completeExtension,
17+
RunE: func(cmd *cobra.Command, args []string) error {
18+
entrypoint, err := extensions.FindEntrypoint(utils.ExtensionsDir(), args[0])
19+
if err != nil {
20+
return fmt.Errorf("failed to reload extensions: %w", err)
21+
}
22+
23+
ext, err := extensions.LoadExtension(entrypoint, true)
24+
if err != nil {
25+
return fmt.Errorf("failed to reload extensions: %w", err)
26+
}
27+
28+
cmd.PrintErrln("Extension reloaded:", ext.Name)
29+
return nil
30+
},
31+
}
32+
}

internal/cli/root.go

+2-13
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ var (
2424
)
2525

2626
func NewRootCmd() (*cobra.Command, error) {
27-
var flags struct {
28-
reload bool
29-
}
3027
// rootCmd represents the base command when called without any subcommands
3128
var rootCmd = &cobra.Command{
3229
Use: "sunbeam",
@@ -37,15 +34,6 @@ func NewRootCmd() (*cobra.Command, error) {
3734
3835
See https://pomdtr.github.io/sunbeam for more information.`,
3936
RunE: func(cmd *cobra.Command, args []string) error {
40-
if flags.reload {
41-
exts, err := LoadExtensions(utils.ExtensionsDir(), true)
42-
if err != nil {
43-
return fmt.Errorf("failed to reload extensions: %w", err)
44-
}
45-
46-
fmt.Fprintf(os.Stderr, "Reloaded %d extensions\n", len(exts))
47-
}
48-
4937
if !term.IsTerminal(int(os.Stdout.Fd())) {
5038
exts, err := LoadExtensions(utils.ExtensionsDir(), false)
5139
if err != nil {
@@ -80,11 +68,12 @@ See https://pomdtr.github.io/sunbeam for more information.`,
8068
},
8169
}
8270

83-
rootCmd.Flags().BoolVar(&flags.reload, "reload", false, "Reload extension manifests")
8471
rootCmd.AddCommand(NewCmdValidate())
72+
rootCmd.AddCommand(NewCmdLs())
8573
rootCmd.AddCommand(NewCmdFetch())
8674
rootCmd.AddCommand(NewCmdServe())
8775
rootCmd.AddCommand(NewCmdEdit())
76+
rootCmd.AddCommand(NewCmdReload())
8877

8978
exts, err := LoadExtensions(utils.ExtensionsDir(), false)
9079
if errors.Is(err, os.ErrNotExist) {

internal/cli/run.go

+1-13
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
func NewCmdRun(exts []extensions.Extension) *cobra.Command {
2121
cmd := &cobra.Command{
2222
Use: "run",
23-
Short: "Run an extension",
23+
Short: "Run an extension command",
2424
}
2525

2626
for _, extension := range exts {
@@ -39,19 +39,7 @@ func NewCmdExtension(alias string, extension extensions.Extension) (*cobra.Comma
3939
rootCmd := &cobra.Command{
4040
Use: alias,
4141
Short: extension.Manifest.Title,
42-
Long: extension.Manifest.Description,
4342
Args: cobra.NoArgs,
44-
RunE: func(cmd *cobra.Command, args []string) error {
45-
if !term.IsTerminal(int(os.Stdout.Fd())) {
46-
encoder := json.NewEncoder(os.Stdout)
47-
encoder.SetIndent("", " ")
48-
encoder.SetEscapeHTML(false)
49-
50-
return encoder.Encode(extension.Manifest)
51-
}
52-
53-
return cmd.Usage()
54-
},
5543
}
5644

5745
rootCmd.CompletionOptions.DisableDefaultCmd = true

internal/extensions/extensions.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
type Extension struct {
2020
Name string `json:"name"`
2121
sunbeam.Manifest
22-
Entrypoint string `json:"-"`
22+
Entrypoint string `json:"entrypoint"`
2323
}
2424

2525
type Preferences map[string]any

internal/tui/runner.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,28 @@ func (c *Runner) Update(msg tea.Msg) (Page, tea.Cmd) {
139139
case sunbeam.Action:
140140
switch msg.Type {
141141
case sunbeam.ActionTypeRun:
142-
command, ok := c.extension.GetCommand(msg.Run.Command)
142+
var extension extensions.Extension
143+
if msg.Run.Extension == "" || msg.Run.Extension == c.extension.Name {
144+
extension = c.extension
145+
} else {
146+
entrypoint, err := extensions.FindEntrypoint(utils.ExtensionsDir(), msg.Run.Extension)
147+
if err != nil {
148+
return c, func() tea.Msg {
149+
return fmt.Errorf("extension %s not found", msg.Run.Extension)
150+
}
151+
}
152+
153+
ext, err := extensions.LoadExtension(entrypoint, true)
154+
if err != nil {
155+
return c, func() tea.Msg {
156+
return err
157+
}
158+
}
159+
160+
extension = ext
161+
}
162+
163+
command, ok := extension.GetCommand(msg.Run.Command)
143164
if !ok {
144165
c.embed = NewErrorPage(fmt.Errorf("command %s not found", msg.Run.Command))
145166
c.embed.SetSize(c.width, c.height)

main.go

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import (
99

1010
func main() {
1111
rootCmd, err := cli.NewRootCmd()
12+
13+
rootCmd.SetIn(os.Stdin)
14+
rootCmd.SetErr(os.Stderr)
15+
rootCmd.SetOut(os.Stdout)
16+
1217
if err != nil {
1318
fmt.Fprintf(os.Stderr, "error: %s\n", err)
1419
os.Exit(1)

pkg/sunbeam/action.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func (a Action) MarshalJSON() ([]byte, error) {
5353
"command": a.Run.Command,
5454
}
5555

56+
if a.Run.Extension != "" {
57+
output["extension"] = a.Run.Extension
58+
}
59+
5660
if len(a.Run.Params) > 0 {
5761
output["params"] = a.Run.Params
5862
}
@@ -78,7 +82,7 @@ func (a Action) MarshalJSON() ([]byte, error) {
7882
type ReloadAction struct{}
7983

8084
type RunAction struct {
81-
Extension string `json:"-"`
85+
Extension string `json:"extension,omitempty"`
8286
Command string `json:"command,omitempty"`
8387
Params map[string]any `json:"params,omitempty"`
8488
}

typescript/pkg/action.ts

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type OpenAction = {
1515
export type RunAction = {
1616
type: "run";
1717
command: string;
18+
extension?: string;
1819
params?: Params;
1920
} & ActionProps;
2021

v2.md

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ There are for type of command modes:
4444
- `action`: return an action. Useful to copy a dynamic string to the clipboard (ex: `copy random uuid`)
4545
- `silent`: run a command, then exit
4646

47+
The `tty` mode has been dropped.
48+
4749
## Simplified actions spec
4850

4951
The pool of actions has been simplified to 3: `run`, `open`, and `copy`.

0 commit comments

Comments
 (0)