Skip to content

Commit 829795e

Browse files
markturanskyclaude
andcommitted
feat(cli): acpctl session commands — messages, send, ag_ui, TUI dashboard, probe command
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 44add3b commit 829795e

32 files changed

Lines changed: 5482 additions & 54 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// Package agent implements noun-style subcommands for working with a specific agent.
2+
package agent
3+
4+
import (
5+
"context"
6+
"fmt"
7+
"time"
8+
9+
"github.com/ambient-code/platform/components/ambient-cli/pkg/connection"
10+
"github.com/ambient-code/platform/components/ambient-cli/pkg/output"
11+
sdkclient "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/client"
12+
sdktypes "github.com/ambient-code/platform/components/ambient-sdk/go-sdk/types"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
var agentID string
17+
18+
var Cmd = &cobra.Command{
19+
Use: "agent",
20+
Short: "Interact with agents",
21+
Long: `Interact with agents.
22+
23+
Examples:
24+
acpctl agent messages <id> # list agent messages
25+
acpctl agent send <id> "Hello!" # send a message to an agent`,
26+
RunE: func(cmd *cobra.Command, args []string) error {
27+
return cmd.Help()
28+
},
29+
}
30+
31+
var msgArgs struct {
32+
outputFormat string
33+
}
34+
35+
var agentMessagesCmd = &cobra.Command{
36+
Use: "messages <agent-id>",
37+
Short: "List messages for an agent",
38+
Args: cobra.ExactArgs(1),
39+
RunE: runAgentMessages,
40+
}
41+
42+
var agentSendCmd = &cobra.Command{
43+
Use: "send <agent-id> <message>",
44+
Short: "Send a message to an agent",
45+
Args: cobra.ExactArgs(2),
46+
RunE: runAgentSend,
47+
}
48+
49+
func init() {
50+
agentMessagesCmd.Flags().StringVarP(&msgArgs.outputFormat, "output", "o", "", "Output format: json")
51+
Cmd.AddCommand(agentMessagesCmd)
52+
Cmd.AddCommand(agentSendCmd)
53+
}
54+
55+
func runAgentMessages(cmd *cobra.Command, args []string) error {
56+
agentID = args[0]
57+
client, err := connection.NewClientFromConfig()
58+
if err != nil {
59+
return err
60+
}
61+
62+
format, err := output.ParseFormat(msgArgs.outputFormat)
63+
if err != nil {
64+
return err
65+
}
66+
printer := output.NewPrinter(format, cmd.OutOrStdout())
67+
68+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
69+
defer cancel()
70+
71+
return listAgentMessages(ctx, client, printer)
72+
}
73+
74+
func listAgentMessages(ctx context.Context, client *sdkclient.Client, printer *output.Printer) error {
75+
opts := sdktypes.NewListOptions().Size(100).Build()
76+
list, err := client.AgentMessages().List(ctx, opts)
77+
if err != nil {
78+
return fmt.Errorf("list agent messages: %w", err)
79+
}
80+
81+
var agentMsgs []sdktypes.AgentMessage
82+
for _, m := range list.Items {
83+
if m.RecipientAgentID == agentID {
84+
agentMsgs = append(agentMsgs, m)
85+
}
86+
}
87+
88+
if printer.Format() == output.FormatJSON {
89+
return printer.PrintJSON(agentMsgs)
90+
}
91+
92+
columns := []output.Column{
93+
{Name: "ID", Width: 27},
94+
{Name: "FROM", Width: 20},
95+
{Name: "READ", Width: 5},
96+
{Name: "AGE", Width: 10},
97+
{Name: "BODY", Width: 60},
98+
}
99+
table := output.NewTable(printer.Writer(), columns)
100+
table.WriteHeaders()
101+
102+
for _, m := range agentMsgs {
103+
age := ""
104+
if m.CreatedAt != nil {
105+
age = output.FormatAge(time.Since(*m.CreatedAt))
106+
}
107+
sender := m.SenderName
108+
if sender == "" {
109+
sender = m.SenderUserID
110+
}
111+
read := "false"
112+
if m.Read {
113+
read = "true"
114+
}
115+
body := m.Body
116+
if len(body) > 57 {
117+
body = body[:57] + "..."
118+
}
119+
table.WriteRow(m.ID, sender, read, age, body)
120+
}
121+
return nil
122+
}
123+
124+
func runAgentSend(cmd *cobra.Command, args []string) error {
125+
id := args[0]
126+
body := args[1]
127+
128+
client, err := connection.NewClientFromConfig()
129+
if err != nil {
130+
return err
131+
}
132+
133+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
134+
defer cancel()
135+
136+
msg, err := client.AgentMessages().Create(ctx, &sdktypes.AgentMessage{
137+
RecipientAgentID: id,
138+
Body: body,
139+
})
140+
if err != nil {
141+
return fmt.Errorf("send message: %w", err)
142+
}
143+
144+
fmt.Fprintf(cmd.OutOrStdout(), "sent (id=%s)\n", msg.ID)
145+
return nil
146+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package ambient
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
tea "github.com/charmbracelet/bubbletea"
8+
"github.com/spf13/cobra"
9+
10+
"github.com/ambient-code/platform/components/ambient-cli/cmd/acpctl/ambient/tui"
11+
"github.com/ambient-code/platform/components/ambient-cli/pkg/connection"
12+
)
13+
14+
var Cmd = &cobra.Command{
15+
Use: "ambient",
16+
Short: "Strategic dashboard — live view of your entire Ambient platform",
17+
Long: `Launches an interactive terminal dashboard for the Ambient platform.
18+
19+
Navigate with ↑↓ (or j/k) to switch sections:
20+
Cluster Pods system pods in the ambient-code namespace
21+
Namespaces all cluster namespaces (fleet-* highlighted)
22+
Projects all projects via SDK
23+
Sessions all sessions with phase status
24+
Agents all agents with current session
25+
Stats summary counts and phase breakdown
26+
27+
Controls:
28+
↑↓ / j/k navigate sections
29+
Tab focus command bar
30+
Esc unfocus command bar
31+
r force refresh
32+
PgUp/PgDn scroll main panel
33+
q / Ctrl+C quit
34+
35+
Command bar accepts any shell command (kubectl, oc, acpctl, etc.)
36+
Output streams line-by-line into the main panel.
37+
38+
Data refreshes automatically every 10 seconds.`,
39+
RunE: func(cmd *cobra.Command, args []string) error {
40+
client, err := connection.NewClientFromConfig()
41+
if err != nil {
42+
return fmt.Errorf("connect: %w", err)
43+
}
44+
45+
m := tui.NewModel(client)
46+
p := tea.NewProgram(m, tea.WithAltScreen(), tea.WithMouseCellMotion())
47+
if _, err := p.Run(); err != nil {
48+
fmt.Fprintf(os.Stderr, "TUI error: %v\n", err)
49+
return err
50+
}
51+
return nil
52+
},
53+
}

0 commit comments

Comments
 (0)