client

package
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// NoAutostartEnv disables automatic server startup when set to "1".
	NoAutostartEnv = "BOID_NO_AUTOSTART"
)

Variables

View Source
var ErrAttachDetached = errors.New("attach detached")

Functions

func DefaultSocketPath

func DefaultSocketPath() string

func EnsureRunning

func EnsureRunning(ctx context.Context) error

EnsureRunning ensures the boid server is running at DefaultSocketPath(), starting it automatically if it is not. Kept for backward compatibility with pre-Phase-3 callers that never had a per-profile socket to name.

func EnsureRunningAt added in v0.0.13

func EnsureRunningAt(ctx context.Context, socketPath string) error

EnsureRunningAt ensures the boid server reachable at socketPath is running. This is the Phase 3 profile-aware entry point (docs/plans/cli-remote-connection.md PR1): root's PersistentPreRunE, once it resolves the invocation's connection profile, passes the profile's socket path here so autostart probes the SAME socket the CLI is about to talk to — not DefaultSocketPath() unconditionally.

Autostart machinery (spawnServer) only knows how to spin up a daemon on the default socket path (it re-execs `boid start`, which reads its own config for the socket path — there is no runtime override), so:

  • socketPath == DefaultSocketPath(): probe → autostart on miss (unchanged)
  • socketPath != DefaultSocketPath(): probe only; on miss, a clear error directing the operator to launch that daemon out-of-band, rather than silently spinning up a fresh default-socket daemon that would not be the one the CLI is about to connect to.

If BOID_NO_AUTOSTART=1, auto-start is skipped and an error is returned when the server is not reachable.

func WithClient added in v0.0.13

func WithClient(ctx context.Context, c *Client) context.Context

WithClient returns a copy of ctx carrying c as the resolved client for this invocation. A nil ctx (cobra's own zero value before Execute()/SetContext ever run — see cmd/root.go's PersistentPreRunE doc comment for why that is the normal case for the leaf command it is called with) is treated as context.Background() instead of panicking: context.WithValue itself panics on a nil parent.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a boid daemon API client. It is transport-agnostic at the call site (Do/GetRaw/... all build requests against baseURL) — NewUnixClient and NewClient's "https" branch are the two constructors that decide what baseURL and httpClient actually mean underneath.

func FromContext added in v0.0.13

func FromContext(ctx context.Context) *Client

FromContext returns the Client injected into ctx by root's PersistentPreRunE. If ctx is nil, or carries no client at all — every call that bypasses cobra's Execute()/PersistentPreRunE lifecycle, which today includes every cmd package test that invokes a runXxx(cmd, args) function directly against a freshly constructed *cobra.Command — this falls back to NewUnixClient(DefaultSocketPath()), this CLI's long- standing (and, until Phase 3, only) default. That fallback is deliberately identical to what profiles.Resolve itself produces when no config.yaml/--profile/BOID_PROFILE/default_profile is set at all (docs/plans/cli-remote-connection.md's "現行互換" contract), so the two paths never diverge for that common case, and this function never needs to return an error.

func FromContextOrNil added in v0.0.13

func FromContextOrNil(ctx context.Context) *Client

FromContextOrNil returns the Client injected into ctx by root's PersistentPreRunE, or nil if none was injected. Unlike FromContext, this does NOT fall back to the unix default — used by shell TAB completion (cmd/completion.go's completeProjectRefs) so a failed profile resolution degrades to "no candidates" instead of silently querying whichever daemon happens to be listening on the local unix socket. Foreground CLI commands keep using FromContext, whose fallback matches the "現行互換" contract profiles.Resolve itself produces when no profile is configured.

func NewClient added in v0.0.13

func NewClient(rawURL, token string) (*Client, error)

NewClient builds a Client from a profile URL (docs/plans/ cli-remote-connection.md "Transport 分岐"): the scheme decides transport.

  • "unix://<path>" — a local UNIX socket, dialed exactly like NewUnixClient(<path>). token is ignored (decision 4: a local socket needs no Bearer auth — connecting to it already implies local user trust).
  • "https://<host>[:port]" — TCP + TLS, with token sent as "Authorization: Bearer <token>" on every request (including same- origin redirects; decision 7 rejects cross-origin ones outright — see sameOriginCheckRedirect).
  • anything else ("http://" included — decision 4 explicitly leaves it unsupported; plain-HTTP remote daemons are not a supported configuration) — a hard error.

func NewUnixClient

func NewUnixClient(socketPath string) *Client

func (*Client) AnswerTask

func (c *Client) AnswerTask(taskID, questionID, answer string) error

AnswerTask submits an answer for an awaiting task via POST /api/tasks/{id}/answer.

func (*Client) ApplyAction

func (c *Client) ApplyAction(taskID string, req api.ApplyActionRequest) (*api.ActionApplication, error)

ApplyAction sends an action to POST /api/tasks/{taskID}/actions.

func (*Client) AttachJob

func (c *Client) AttachJob(jobID string, stdin io.Reader, stdout io.Writer) error

AttachJob opens a live interactive attach to jobID over WebSocket (docs/plans/cli-remote-connection.md Phase 3 PR3: "WebSocket attach 一本化") and blocks until the job's process exits (the server sends an "exit" frame, or the socket closes normally) or the caller detaches (stdin.Read returning ErrAttachDetached — see cmd/attach.go's detachReader). Works identically for a unix-scheme Client (the WS handshake dials over the same UNIX socket via c.httpClient's DialContext) and an https-scheme one (the handshake request carries the same Authorization: Bearer header every other request on c.httpClient does, via bearerTransport) — reusing c.httpClient rather than building a separate one is what gives WS attach Bearer auth for free, and is the point of "一本化": one transport, one auth path, for both local and remote profiles alike.

This replaces the old raw net.Dial("unix", ...) + hand-written `Upgrade: boid-attach` implementation, which only ever worked for a unix socket Client — an https-scheme Client had no socketPath to dial at all, so remote attach previously just returned a "not yet supported" error — and duplicated a second attach transport alongside the Web UI's existing WebSocket one for no reason beyond history (decision 5, docs/plans/ cli-remote-connection.md: two attach transports serving the same purpose is a maintenance burden the plan explicitly rejects).

stdin may be nil (no input forwarding) — used by TestServerJobRuntimeAttachAndResize (internal/server/server_phase3_test.go), which only cares about output replay.

func (*Client) CreateTask

func (c *Client) CreateTask(req api.CreateTaskRequest) (*orchestrator.Task, error)

CreateTask creates a new task via POST /api/tasks.

func (*Client) DeleteTask

func (c *Client) DeleteTask(id string) error

DeleteTask deletes a task via DELETE /api/tasks/{id}.

func (*Client) Do

func (c *Client) Do(method, path string, body any, result any) error

Do issues an HTTP request with no deadline. Suitable for foreground CLI commands where the user explicitly waits for a response. For latency- bounded callers (shell completion, health probes) use DoContext with a bounded context.Context so a slow / hung daemon never blocks the user's shell indefinitely.

func (*Client) DoContext added in v0.0.13

func (c *Client) DoContext(ctx context.Context, method, path string, body any, result any) error

DoContext is Do with a caller-supplied context — the request is canceled (and any in-flight IO unblocked) when ctx is Done, so completion and probe callers can enforce a wall-clock bound on the daemon round trip. Behaviorally identical to Do at the API surface (same URL construction, same headers, same status-code handling); the sole difference is the context propagation.

func (*Client) DoWithContentType

func (c *Client) DoWithContentType(method, path, contentType string, body []byte, result any) error

DoWithContentType performs an HTTP request with a custom Content-Type and raw body.

func (*Client) DuplicateTask

func (c *Client) DuplicateTask(id string) (*orchestrator.Task, error)

DuplicateTask duplicates a task via POST /api/tasks/{id}/duplicate.

func (*Client) GetProject

func (c *Client) GetProject(id string) (*orchestrator.Project, error)

GetProject fetches a single project by ID via GET /api/projects/{id}.

func (*Client) GetRaw

func (c *Client) GetRaw(path string) (statusCode int, body []byte, err error)

GetRaw performs a GET request and returns the raw response body and status code.

func (*Client) GetRawWithAccept added in v0.0.13

func (c *Client) GetRawWithAccept(path, accept string) (statusCode int, body []byte, err error)

GetRawWithAccept performs a GET request with a custom Accept header, returning the raw response body and status code regardless of status (mirrors GetRaw) — used by `boid workspace export` (docs/plans/workspace-db-consolidation.md PR5 Step D) to explicitly request the yaml export body, even though the server today always responds with application/yaml regardless of Accept.

func (*Client) GetTaskDetail

func (c *Client) GetTaskDetail(id string) (*api.TaskDetailView, error)

GetTaskDetail fetches task metadata + actions + jobs for a given task ID.

func (*Client) IsUnix added in v0.0.13

func (c *Client) IsUnix() bool

IsUnix reports whether c dials a local UNIX socket (NewUnixClient, or NewClient given a "unix://" url) rather than a remote HTTPS origin. root's PersistentPreRunE uses this to decide whether daemon autostart applies (decision 6: autostart only ever makes sense for a daemon this same host can spawn).

func (*Client) ListJobs

func (c *Client) ListJobs(filter api.JobListFilter) ([]api.JobWithContext, error)

ListJobs - フィルタ付きで全プロジェクト横断のジョブ一覧を取得

func (*Client) ListProjects

func (c *Client) ListProjects() ([]*orchestrator.Project, error)

ListProjects fetches all projects.

func (*Client) ListTasks

func (c *Client) ListTasks(filter TaskListFilter) ([]*orchestrator.Task, error)

ListTasks fetches tasks with optional status and project filters.

func (*Client) ListWorkspaces

func (c *Client) ListWorkspaces() ([]*orchestrator.WorkspaceSummary, error)

ListWorkspaces fetches all workspaces.

func (*Client) PostRaw added in v0.0.13

func (c *Client) PostRaw(path, contentType string, body []byte) (statusCode int, respBody []byte, err error)

PostRaw performs a POST request with a custom Content-Type and raw body, returning the raw response status code and body regardless of status (mirrors PutRawWithIfMatch's rationale) — used by `boid workspace import` (docs/plans/workspace-db-consolidation.md PR5 Step E) so the CLI can distinguish 409 (create-only conflict against an existing slug) from 400 (bad mode/host_commands reference) from 200 (success) instead of losing that distinction to a single generic error string.

func (*Client) ProbeAlive added in v0.0.13

func (c *Client) ProbeAlive(timeout time.Duration) bool

ProbeAlive reports whether the daemon behind this client is reachable within timeout, at the transport layer only (no auth, no request body). Used by cmd/completion.go so shell TAB completion can skip a daemon that is not going to answer without blocking the shell on a full API request.

The probe is scheme-aware:

  • unix: net.DialTimeout("unix", ...) as before
  • https: net.DialTimeout("tcp", host[:port default 443], ...) — just a TCP connect, not a TLS handshake, since the point is "is anyone listening on that port at all" not "is the cert valid" (a TLS-level failure means the daemon IS up and the follow-up API request will surface the real error to the user; a transport-level connect failure means no daemon).

func (*Client) PutRawWithIfMatch added in v0.0.13

func (c *Client) PutRawWithIfMatch(path, contentType string, body []byte, ifMatch string) (statusCode int, respBody []byte, err error)

PutRawWithIfMatch performs a PUT request with a custom Content-Type and (optional) If-Match header, returning the raw response status code and body regardless of status — unlike Do/DoWithContentType, which collapse every 4xx/5xx into a generic error. Used by `boid workspace edit` (docs/plans/workspace-db-consolidation.md PR4 Step E/H) so the CLI can distinguish 412 (stale revision) from 428 (missing If-Match) from 200 (success) instead of losing that distinction to a single error string.

func (*Client) RerunTask

func (c *Client) RerunTask(id string, autoStart bool) (*orchestrator.Task, error)

RerunTask resets a done/aborted task to pending via POST /api/tasks/{id}/rerun.

func (*Client) ResizeJob

func (c *Client) ResizeJob(jobID string, rows, cols int) error

func (*Client) SocketPath added in v0.0.13

func (c *Client) SocketPath() string

SocketPath returns the UNIX socket path this Client was built to dial, or "" for an https-scheme Client. root.PersistentPreRunE passes this to EnsureRunningAt so the autostart probe hits the same socket the CLI is about to talk to (docs/plans/cli-remote-connection.md PR1 codex review).

func (*Client) UpdateTask

func (c *Client) UpdateTask(id string, req api.UpdateTaskRequest) (*orchestrator.Task, error)

UpdateTask updates the title and description of a task via PATCH /api/tasks/{id}.

type TaskListFilter

type TaskListFilter struct {
	Status    string
	ProjectID string
}

TaskListFilter holds filters for listing tasks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL