Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ jobs:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
16 changes: 16 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,19 @@ nfpms:
contents:
- src: man/man1/*.1.gz
dst: /usr/share/man/man1/
homebrew_casks:
- name: cerca
repository:
owner: matrices
name: homebrew-cerca
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
homepage: https://cerca.dev
description: The official CLI for Cerca.
license: Apache-2.0
binary: "cerca"
completions:
bash: "completions/cerca.bash"
zsh: "completions/cerca.zsh"
fish: "completions/cerca.fish"
manpages:
- man/man1/cerca.1.gz
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0"
".": "0.2.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 64
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/calvinfo-o4h6u5/cerca-a3610b6045d1d701859276e09dff35829bdf50509b762116860d8005831b0297.yml
openapi_spec_hash: 2a240632b5ef4814881e36247ec3c8dc
config_hash: 5d687451efd1d2898e81fa3ddb25f8ed
configured_endpoints: 66
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/calvinfo-o4h6u5/cerca-f1c349d486ace3b0f8cfb765e3d56b561aac2cab99d5a87fd795c7d74db68311.yml
openapi_spec_hash: d1e63b49a56f6c27dc3dac475c34d612
config_hash: f6565c46c739d01060c1217b6a22045e
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.2.0 (2026-05-07)

Full Changelog: [v0.1.0...v0.2.0](https://github.com/matrices/cerca-cli/compare/v0.1.0...v0.2.0)

### Features

* **api:** api update ([c1baf5e](https://github.com/matrices/cerca-cli/commit/c1baf5e3302db60bc7fdc58265b0f72a4eba7687))
* **api:** api update ([babea2b](https://github.com/matrices/cerca-cli/commit/babea2ba706994b69fa8818fbc578f13a5fb1a2c))
* **api:** api update ([1864094](https://github.com/matrices/cerca-cli/commit/18640949eec015dcbfc4c972bed8c5d59e0fc526))

## 0.1.0 (2026-05-01)

Full Changelog: [v0.0.1...v0.1.0](https://github.com/matrices/cerca-cli/compare/v0.0.1...v0.1.0)
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ It is generated with [Stainless](https://www.stainless.com/).

## Installation

### Installing with Homebrew

```sh
brew install matrices/cerca/cerca
```

### Installing with Go

To test or install the CLI locally, you need [Go](https://go.dev/doc/install) version 1.22 or later installed.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/charmbracelet/x/term v0.2.1
github.com/goccy/go-yaml v1.18.0
github.com/itchyny/json2yaml v0.1.4
github.com/matrices/cerca-go v0.2.0
github.com/muesli/reflow v0.3.0
github.com/stretchr/testify v1.10.0
github.com/tidwall/gjson v1.18.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ github.com/itchyny/json2yaml v0.1.4 h1:/pErVOXGG5iTyXHi/QKR4y3uzhLjGTEmmJIy97YT+
github.com/itchyny/json2yaml v0.1.4/go.mod h1:6iudhBZdarpjLFRNj+clWLAkGft+9uCcjAZYXUH9eGI=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/matrices/cerca-go v0.2.0 h1:wE52htsGkLOwbEs3XvIqvLoFkQweNaxUBBLpYEpef0o=
github.com/matrices/cerca-go v0.2.0/go.mod h1:tit8ndfC5lSDCy9Pc+OMQ/Vi4hBTpDtYnsLdzpHh1g0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,11 @@ func init() {
&threadsCreate,
&threadsRetrieve,
&threadsList,
&threadsActivity,
&threadsCancel,
&threadsClose,
&threadsCompact,
&threadsListMessages,
&threadsStartTurn,
&threadsSteer,
},
Expand Down
194 changes: 193 additions & 1 deletion pkg/cmd/thread.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ var threadsRetrieve = cli.Command{
},
&requestflag.Flag[string]{
Name: "include-messages",
Usage: "When true, includes message content in the thread detail.",
Usage: "Deprecated compatibility flag. Thread detail includes a bounded recent message page by default; pass `false` only to opt out when no message pagination params are present.",
QueryPath: "includeMessages",
},
},
Expand Down Expand Up @@ -120,6 +120,31 @@ var threadsList = cli.Command{
HideHelpCommand: true,
}

var threadsActivity = cli.Command{
Name: "activity",
Usage: "Fetch compact current and recent activity for a thread without returning\ntranscript content or runtime debug state.",
Suggest: true,
Flags: []cli.Flag{
&requestflag.Flag[string]{
Name: "agent-id",
Required: true,
PathParam: "agentId",
},
&requestflag.Flag[string]{
Name: "thread-id",
Required: true,
PathParam: "threadId",
},
&requestflag.Flag[string]{
Name: "fleet-id",
Usage: "Optional fleet id for index-backed authorization.",
QueryPath: "fleetId",
},
},
Action: handleThreadsActivity,
HideHelpCommand: true,
}

var threadsCancel = cli.Command{
Name: "cancel",
Usage: "Cancel a running or awaiting thread. The underlying runtime treats repeat\ncancellation as an idempotent lifecycle operation when possible.",
Expand Down Expand Up @@ -180,6 +205,45 @@ var threadsCompact = cli.Command{
HideHelpCommand: true,
}

var threadsListMessages = cli.Command{
Name: "list-messages",
Usage: "List a bounded page of transcript messages for a thread, newest first. Use the\nreturned `cursor` to page older messages.",
Suggest: true,
Flags: []cli.Flag{
&requestflag.Flag[string]{
Name: "agent-id",
Required: true,
PathParam: "agentId",
},
&requestflag.Flag[string]{
Name: "thread-id",
Required: true,
PathParam: "threadId",
},
&requestflag.Flag[string]{
Name: "cursor",
Usage: "Cursor returned by a previous thread messages response.",
QueryPath: "cursor",
},
&requestflag.Flag[string]{
Name: "fleet-id",
Usage: "Optional fleet id for index-backed authorization.",
QueryPath: "fleetId",
},
&requestflag.Flag[string]{
Name: "limit",
Usage: "Maximum number of messages to include, capped at 500.",
QueryPath: "limit",
},
&requestflag.Flag[int64]{
Name: "max-items",
Usage: "The maximum number of items to return (use -1 for unlimited).",
},
},
Action: handleThreadsListMessages,
HideHelpCommand: true,
}

var threadsStartTurn = cli.Command{
Name: "start-turn",
Usage: "Create turn",
Expand Down Expand Up @@ -410,6 +474,60 @@ func handleThreadsList(ctx context.Context, cmd *cli.Command) error {
}
}

func handleThreadsActivity(ctx context.Context, cmd *cli.Command) error {
client := cercago.NewClient(getDefaultRequestOptions(cmd)...)
unusedArgs := cmd.Args().Slice()
if !cmd.IsSet("agent-id") && len(unusedArgs) > 0 {
cmd.Set("agent-id", unusedArgs[0])
unusedArgs = unusedArgs[1:]
}
if !cmd.IsSet("thread-id") && len(unusedArgs) > 0 {
cmd.Set("thread-id", unusedArgs[0])
unusedArgs = unusedArgs[1:]
}
if len(unusedArgs) > 0 {
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
}

options, err := flagOptions(
cmd,
apiquery.NestedQueryFormatBrackets,
apiquery.ArrayQueryFormatComma,
EmptyBody,
false,
)
if err != nil {
return err
}

params := cercago.ThreadActivityParams{}

var res []byte
options = append(options, option.WithResponseBodyInto(&res))
_, err = client.Threads.Activity(
ctx,
cmd.Value("agent-id").(string),
cmd.Value("thread-id").(string),
params,
options...,
)
if err != nil {
return err
}

obj := gjson.ParseBytes(res)
format := cmd.Root().String("format")
explicitFormat := cmd.Root().IsSet("format")
transform := cmd.Root().String("transform")
return ShowJSON(obj, ShowJSONOpts{
ExplicitFormat: explicitFormat,
Format: format,
RawOutput: cmd.Root().Bool("raw-output"),
Title: "threads activity",
Transform: transform,
})
}

func handleThreadsCancel(ctx context.Context, cmd *cli.Command) error {
client := cercago.NewClient(getDefaultRequestOptions(cmd)...)
unusedArgs := cmd.Args().Slice()
Expand Down Expand Up @@ -563,6 +681,80 @@ func handleThreadsCompact(ctx context.Context, cmd *cli.Command) error {
})
}

func handleThreadsListMessages(ctx context.Context, cmd *cli.Command) error {
client := cercago.NewClient(getDefaultRequestOptions(cmd)...)
unusedArgs := cmd.Args().Slice()
if !cmd.IsSet("agent-id") && len(unusedArgs) > 0 {
cmd.Set("agent-id", unusedArgs[0])
unusedArgs = unusedArgs[1:]
}
if !cmd.IsSet("thread-id") && len(unusedArgs) > 0 {
cmd.Set("thread-id", unusedArgs[0])
unusedArgs = unusedArgs[1:]
}
if len(unusedArgs) > 0 {
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
}

options, err := flagOptions(
cmd,
apiquery.NestedQueryFormatBrackets,
apiquery.ArrayQueryFormatComma,
EmptyBody,
false,
)
if err != nil {
return err
}

params := cercago.ThreadListMessagesParams{}

format := cmd.Root().String("format")
explicitFormat := cmd.Root().IsSet("format")
transform := cmd.Root().String("transform")
if format == "raw" {
var res []byte
options = append(options, option.WithResponseBodyInto(&res))
_, err = client.Threads.ListMessages(
ctx,
cmd.Value("agent-id").(string),
cmd.Value("thread-id").(string),
params,
options...,
)
if err != nil {
return err
}
obj := gjson.ParseBytes(res)
return ShowJSON(obj, ShowJSONOpts{
ExplicitFormat: explicitFormat,
Format: format,
RawOutput: cmd.Root().Bool("raw-output"),
Title: "threads list-messages",
Transform: transform,
})
} else {
iter := client.Threads.ListMessagesAutoPaging(
ctx,
cmd.Value("agent-id").(string),
cmd.Value("thread-id").(string),
params,
options...,
)
maxItems := int64(-1)
if cmd.IsSet("max-items") {
maxItems = cmd.Value("max-items").(int64)
}
return ShowJSONIterator(iter, maxItems, ShowJSONOpts{
ExplicitFormat: explicitFormat,
Format: format,
RawOutput: cmd.Root().Bool("raw-output"),
Title: "threads list-messages",
Transform: transform,
})
}
}

func handleThreadsStartTurn(ctx context.Context, cmd *cli.Command) error {
client := cercago.NewClient(getDefaultRequestOptions(cmd)...)
unusedArgs := cmd.Args().Slice()
Expand Down
29 changes: 29 additions & 0 deletions pkg/cmd/thread_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ func TestThreadsList(t *testing.T) {
})
}

func TestThreadsActivity(t *testing.T) {
t.Run("regular flags", func(t *testing.T) {
mocktest.TestRunMockTestWithFlags(
t,
"--api-key", "string",
"threads", "activity",
"--agent-id", "agent_abc123",
"--thread-id", "thread_abc123",
"--fleet-id", "fleetId",
)
})
}

func TestThreadsCancel(t *testing.T) {
t.Run("regular flags", func(t *testing.T) {
mocktest.TestRunMockTestWithFlags(
Expand Down Expand Up @@ -107,6 +120,22 @@ func TestThreadsCompact(t *testing.T) {
})
}

func TestThreadsListMessages(t *testing.T) {
t.Run("regular flags", func(t *testing.T) {
mocktest.TestRunMockTestWithFlags(
t,
"--api-key", "string",
"threads", "list-messages",
"--max-items", "10",
"--agent-id", "agent_abc123",
"--thread-id", "thread_abc123",
"--cursor", "42",
"--fleet-id", "fleetId",
"--limit", "100",
)
})
}

func TestThreadsStartTurn(t *testing.T) {
t.Run("regular flags", func(t *testing.T) {
mocktest.TestRunMockTestWithFlags(
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package cmd

const Version = "0.1.0" // x-release-please-version
const Version = "0.2.0" // x-release-please-version
Loading