Documentation
¶
Overview ¶
Package cli wires the kong grammar, the runtime, and the exit-code mapping. main() does nothing but os.Exit(cli.Run(...)) so every path is testable in-process.
Index ¶
- func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int
- type AgentCmd
- type AuthCmd
- type AuthLoginCmd
- type AuthLogoutCmd
- type AuthRefreshCmd
- type AuthStatusCmd
- type CLI
- type DoctorCmd
- type InsightsAccountCmd
- type InsightsCmd
- type InsightsPostCmd
- type MentionsCmd
- type MentionsListCmd
- type PostCmd
- type PostCreateCmd
- type PostDeleteCmd
- type PostGetCmd
- type PostListCmd
- type PostRepostCmd
- type ProfileCmd
- type ProfileGetCmd
- type ReplyCmd
- type ReplyCreateCmd
- type ReplyHideCmd
- type ReplyListCmd
- type ReplyTreeCmd
- type ReplyUnhideCmd
- type Runtime
- type SchemaCmd
- type SearchCmd
- type SearchPostsCmd
- type VersionCmd
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AuthCmd ¶
type AuthCmd struct {
Status AuthStatusCmd `cmd:"" help:"Test the token; report account, expiry, and source."`
Login AuthLoginCmd `cmd:"" help:"Authenticate (paste-the-callback-URL, or --token-stdin)."`
Logout AuthLogoutCmd `cmd:"" help:"Remove stored credentials from the keyring/file (local only)."`
Refresh AuthRefreshCmd `cmd:"" help:"Extend the long-lived (60-day) token; safe on a schedule."`
}
AuthCmd wires the Threads OAuth model (spec.md §Auth): --token-stdin (headless) + paste-the-callback-URL (human onboarding), long-lived 60d token with refresh. Secrets come via stdin/env (never argv) and persist in the OS keyring + 0600 fallback (contract §7).
type AuthLoginCmd ¶
type AuthLoginCmd struct {
TokenStdin bool `name:"token-stdin" help:"Read a pre-obtained token from stdin (headless; no browser)."`
}
func (*AuthLoginCmd) Run ¶
func (c *AuthLoginCmd) Run(rt *Runtime) error
type AuthLogoutCmd ¶
type AuthLogoutCmd struct{}
func (*AuthLogoutCmd) Run ¶
func (c *AuthLogoutCmd) Run(rt *Runtime) error
type AuthRefreshCmd ¶
type AuthRefreshCmd struct{}
func (*AuthRefreshCmd) Run ¶
func (c *AuthRefreshCmd) Run(rt *Runtime) error
type AuthStatusCmd ¶
type AuthStatusCmd struct{}
func (*AuthStatusCmd) Run ¶
func (c *AuthStatusCmd) Run(rt *Runtime) error
type CLI ¶
type CLI struct {
// Output (contract §1, §6)
Format string `enum:"json,plain,tsv" default:"plain" help:"Output format: json, plain, or tsv."`
JSON bool `help:"Shorthand for --format=json."`
NoColor bool `help:"Disable colored output."`
Limit int `default:"50" help:"Maximum items to return for list operations."`
Select string `help:"Comma-separated dot-path field projection, e.g. id,text."`
Concise bool `help:"Drop null/empty fields from output (fewer tokens)."`
// Safety (contract §2)
AllowMutations bool `help:"Permit state-changing operations (off by default)."`
DryRun bool `help:"Print intended mutations without performing them."`
NoInput bool `help:"Never prompt; fail with exit 13 instead."`
// Prompt-injection hardening (contract §8). Default-ON when an agent is consuming output
// (JSON or non-TTY); force either way with these flags.
WrapUntrusted bool `help:"Fence free text from Threads as untrusted (force on)."`
NoWrapUntrusted bool `help:"Do not fence untrusted text (force off)."`
// Commands (noun-verb, service-namespaced)
Profile ProfileCmd `cmd:"" help:"Read Threads profiles."`
Post PostCmd `cmd:"" help:"List, read, and publish posts."`
Reply ReplyCmd `cmd:"" help:"Read replies and manage replies on your posts."`
Search SearchCmd `cmd:"" help:"Search public posts by keyword or topic."`
Mentions MentionsCmd `cmd:"" help:"List public posts mentioning you."`
Insights InsightsCmd `cmd:"" help:"Read post- and account-level metrics."`
Auth AuthCmd `cmd:"" help:"Manage authentication."`
Doctor DoctorCmd `cmd:"" help:"Diagnose setup and report fixes."`
Schema SchemaCmd `cmd:"" help:"Print the machine-readable command schema (JSON)."`
Agent AgentCmd `cmd:"" help:"Print the bundled agent SKILL.md."`
Version VersionCmd `cmd:"" help:"Print the version."`
}
CLI is the kong grammar. Global flags are the universal agent-CLI contract surface; subcommands follow noun-verb grammar.
type DoctorCmd ¶
type DoctorCmd struct {
ForAgent bool `name:"for-agent" help:"Terser, machine-skimmable diagnostics for an agent."`
}
DoctorCmd runs real environment/auth/connectivity diagnostics.
type InsightsAccountCmd ¶
type InsightsAccountCmd struct {
Metrics []string `help:"Subset of metrics to return (default: all)."`
Since string `help:"ISO-8601 start of the window."`
Until string `help:"ISO-8601 end of the window."`
}
func (*InsightsAccountCmd) Run ¶
func (c *InsightsAccountCmd) Run(rt *Runtime) error
type InsightsCmd ¶
type InsightsCmd struct {
Post InsightsPostCmd `cmd:"" help:"Per-post metrics by media id."`
Account InsightsAccountCmd `cmd:"" help:"Account-level metrics + demographics."`
}
InsightsCmd reads post- and account-level metrics. Numeric → no injection fencing needed.
type InsightsPostCmd ¶
type InsightsPostCmd struct {
ID string `arg:"" help:"Media id of the post."`
}
func (*InsightsPostCmd) Run ¶
func (c *InsightsPostCmd) Run(rt *Runtime) error
type MentionsCmd ¶
type MentionsCmd struct {
List MentionsListCmd `cmd:"" help:"List public posts that mention you."`
}
MentionsCmd lists public posts mentioning the authenticated user. Free text from other users → fenced in agent mode (contract §8).
type MentionsListCmd ¶
type MentionsListCmd struct {
Cursor string `help:"Opaque pagination cursor."`
}
func (*MentionsListCmd) Run ¶
func (c *MentionsListCmd) Run(rt *Runtime) error
type PostCmd ¶
type PostCmd struct {
List PostListCmd `cmd:"" help:"List the authenticated user's posts."`
Get PostGetCmd `cmd:"" help:"Get one post by media id."`
Create PostCreateCmd `cmd:"" help:"Publish a post (mutation; reviewed-artifact via --dry-run/--apply)."`
Repost PostRepostCmd `cmd:"" help:"Repost a post by media id (mutation)."`
Delete PostDeleteCmd `cmd:"" help:"Delete a post by media id (mutation, idempotent)."`
}
PostCmd groups the post noun-verb subcommands (the primary noun).
type PostCreateCmd ¶
type PostCreateCmd struct {
Text string `help:"Post text."`
Image []string `help:"Image URL (repeatable for a carousel)."`
Video []string `help:"Video URL (repeatable for a carousel)."`
Link string `help:"Link attachment URL."`
ReplyTo string `help:"Reply to this media id."`
Quote string `help:"Quote this media id."`
Topic string `help:"Topic tag."`
ReplyAudience string `enum:",everyone,accounts_you_follow,mentioned_only" default:"" help:"Who can reply."`
Apply string `help:"Publish only the plan whose --dry-run hash equals this value."`
}
PostCreateCmd publishes a post. High-stakes + irreversible + public, so it uses the reviewed-artifact = approval pattern (contract §2): `--dry-run` emits the exact plan plus a content hash; `--apply <hash>` publishes only if the recomputed hash matches.
func (*PostCreateCmd) Run ¶
func (c *PostCreateCmd) Run(rt *Runtime) error
type PostDeleteCmd ¶
type PostDeleteCmd struct {
ID string `arg:"" help:"Media id to delete."`
}
func (*PostDeleteCmd) Run ¶
func (c *PostDeleteCmd) Run(rt *Runtime) error
type PostGetCmd ¶
type PostGetCmd struct {
ID string `arg:"" help:"Media id of the post."`
}
func (*PostGetCmd) Run ¶
func (c *PostGetCmd) Run(rt *Runtime) error
type PostListCmd ¶
type PostListCmd struct {
Since string `help:"Only posts on/after this ISO-8601 date."`
Until string `help:"Only posts on/before this ISO-8601 date."`
Cursor string `help:"Opaque pagination cursor from a previous nextCursor."`
}
func (*PostListCmd) Run ¶
func (c *PostListCmd) Run(rt *Runtime) error
type PostRepostCmd ¶
type PostRepostCmd struct {
ID string `arg:"" help:"Media id to repost."`
}
func (*PostRepostCmd) Run ¶
func (c *PostRepostCmd) Run(rt *Runtime) error
type ProfileCmd ¶
type ProfileCmd struct {
Get ProfileGetCmd `cmd:"" help:"Get a profile (self or by user id)."`
}
ProfileCmd reads a Threads profile. The biography is user-controlled → fenced in agent mode.
type ProfileGetCmd ¶
type ProfileGetCmd struct {
User string `arg:"" optional:"" default:"me" help:"User id, or 'me' (default)."`
}
func (*ProfileGetCmd) Run ¶
func (c *ProfileGetCmd) Run(rt *Runtime) error
type ReplyCmd ¶
type ReplyCmd struct {
List ReplyListCmd `cmd:"" help:"List top-level replies to a post."`
Tree ReplyTreeCmd `cmd:"" help:"Show the full conversation tree for a post."`
Create ReplyCreateCmd `cmd:"" help:"Reply to a post (mutation)."`
Hide ReplyHideCmd `cmd:"" help:"Hide a reply on your post (mutation, idempotent)."`
Unhide ReplyUnhideCmd `cmd:"" help:"Unhide a reply on your post (mutation, idempotent)."`
}
ReplyCmd groups reply reads + reply management. Reply text comes from other users → fenced in agent mode (contract §8). hide/unhide are idempotent (contract §9).
type ReplyCreateCmd ¶
type ReplyCreateCmd struct {
ID string `arg:"" help:"Media id to reply to."`
Text string `help:"Reply text."`
Image string `help:"Image URL."`
Apply string `help:"Publish only the plan whose --dry-run hash equals this value."`
}
func (*ReplyCreateCmd) Run ¶
func (c *ReplyCreateCmd) Run(rt *Runtime) error
type ReplyHideCmd ¶
type ReplyHideCmd struct {
ID string `arg:"" help:"Reply id to hide."`
}
func (*ReplyHideCmd) Run ¶
func (c *ReplyHideCmd) Run(rt *Runtime) error
type ReplyListCmd ¶
type ReplyListCmd struct {
ID string `arg:"" help:"Media id of the post."`
Cursor string `help:"Opaque pagination cursor."`
}
func (*ReplyListCmd) Run ¶
func (c *ReplyListCmd) Run(rt *Runtime) error
type ReplyTreeCmd ¶
type ReplyTreeCmd struct {
ID string `arg:"" help:"Media id of the post."`
Cursor string `help:"Opaque pagination cursor."`
}
func (*ReplyTreeCmd) Run ¶
func (c *ReplyTreeCmd) Run(rt *Runtime) error
type ReplyUnhideCmd ¶
type ReplyUnhideCmd struct {
ID string `arg:"" help:"Reply id to unhide."`
}
func (*ReplyUnhideCmd) Run ¶
func (c *ReplyUnhideCmd) Run(rt *Runtime) error
type Runtime ¶
type Runtime struct {
Cfg *CLI
Out *output.Writer
API api.Threads
Creds *auth.Credentials
Stdin io.Reader
Ctx context.Context
Wrap bool // effective prompt-injection fencing decision
}
Runtime is the per-invocation context bound into every command's Run method.
type SearchCmd ¶
type SearchCmd struct {
Posts SearchPostsCmd `cmd:"" help:"Search posts by keyword or topic tag."`
}
SearchCmd searches public Threads posts. Results are attacker-controllable free text → fenced in agent mode (contract §8). The envelope carries scope:public|self so an agent knows whether advanced access was actually in effect (without it, the API returns only own posts).
type SearchPostsCmd ¶
type SearchPostsCmd struct {
Keyword string `arg:"" help:"Keyword or topic to search."`
MediaType string `enum:",text,image,video" default:"" help:"Filter by media type."`
Mode string `enum:"keyword,tag" default:"keyword" help:"Search mode: keyword or topic tag."`
Cursor string `help:"Opaque pagination cursor."`
}
func (*SearchPostsCmd) Run ¶
func (c *SearchPostsCmd) Run(rt *Runtime) error
type VersionCmd ¶
type VersionCmd struct {
Check bool `help:"Check for a newer release (network, short timeout, fail-silent)."`
}
func (*VersionCmd) Run ¶
func (c *VersionCmd) Run(rt *Runtime) error