droid

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 11 Imported by: 0

README

droid-sdk-go

A Go client for the Droid Daemon (droid daemon), the JSON-RPC-over-WebSocket protocol that Factory's TypeScript SDK (@factory/droid-sdk) speaks. Pure Go, no Node at run time.

Checked against droid daemon 0.233.0 (protocol 1.245.0); types generated from @factory/droid-sdk 0.10.0 (protocol 1.269.0), plus what droid 1.0, 1.1 and 1.2 add that it lacks (see "Upgrading" below).

go get github.com/kkkk2323/droid-sdk-go@latest

It started in droi, which still uses it, with the Fake Daemon below.

Packages

Package What it is Written by
protocol Every type of the protocol (832), method and notification names, per-method ack/timeout table generated (gen/)
droid (root) Client: one authenticated connection; a typed method for each of the 148 RPCs (zz_client_methods.go, generated), Call, Subscribe, Handle/HandleLater/Respond for the Daemon's own requests, frame recording hand
controller Connects and authenticates, reconnects and reloads Sessions, loads a Session before a call that needs its worker, tracks permission and AskUser prompts (keeping an answer given while a worker is gone until it is back), feeds the store. Port of the TS DaemonSessionController hand
session The Sessions' state: transcript built from streamed deltas, working state, settings, token usage, todos, queued and optimistic messages, subagents, display filtering. Port of the TS MultiSessionStateManager/SessionStateManager/SessionStore. No I/O hand
fakedaemon Runs the Fake Daemon (Node) for Go tests hand

Use

ctl := controller.New(controller.Config{
	URL: "ws://127.0.0.1:37643",
	Credential: func(context.Context) (*droid.Credential, error) {
		return &droid.Credential{APIKey: os.Getenv("FACTORY_API_KEY")}, nil
	},
})
defer ctl.Close()
if err := ctl.Connect(ctx); err != nil { ... }

ctl.Subscribe(func(e controller.Event) {
	if p, ok := e.(controller.PermissionRequested); ok {
		ctl.RespondToPermission(ctx, p.Permission.RequestID,
			controller.PermissionAnswer{SelectedOption: protocol.ToolConfirmationOutcomeProceedOnce})
	}
})
ctl.Store().Subscribe(func(e session.Event) { /* re-render e.SessionID */ })

res, _ := ctl.InitializeSession(ctx, protocol.InitializeSessionParams{Cwd: dir})
ctl.AddUserMessage(ctx, protocol.AddUserMessageParams{SessionID: res.SessionID, Text: "Run the tests"})
msgs := ctl.Store().Session(res.SessionID).DisplayMessages()

cl, _ := ctl.Client() // every other RPC: cl.GetGitDiff, cl.ListSkills, ...

The full example is controller/example_test.go. The Controller wraps the calls that change its state (LoadSession, InitializeSession, AddUserMessage, InterruptSession, CloseSession, RespondToPermission, RespondToAskUser); the rest go straight to the generated methods of ctl.Client(). droid.Dial alone gives the bare connection.

Threading: Controller events come in order on a goroutine of their own, so a handler may call the Controller. Store events come on the goroutine that changed the store (for notifications, the connection's read goroutine): a store subscriber must not block.

What the Go port leaves out of the TS SDK

  • Cloud machines, relays, computers, missions, terminals, act-as grants, telemetry. The Controller is for a local Daemon or a Gateway in front of one.
  • After a reconnect the Controller loads again, at once, every Session that was loaded (TS marks them not loaded and loads on next use). It also loads on next use, as TS does.
  • The TS reconnect grace window for a prompt that a first snapshot omits is not ported: a reload replaces a Session's prompts with the Daemon's.
  • InterruptSession does not remove the half-streamed message (the store does not track streaming message ids); the Daemon's own notifications settle it.
  • The store leaves out progressive rendering, LRU eviction, MCP status, hook rows and the pending/default settings stores; session/store.go lists all of it.

Protocol facts found on a real Daemon

  • daemon.authenticate with caller sdk and no metadata.sdk fails with -32700; metadata.sdk.language only takes typescript or python. The Client sends caller go-sdk and no SDK metadata.
  • daemon.add_user_message answers {} (no ack), then create_message carries the request id; a message sent while the agent works is taken into the running turn at once.
  • Empty user_only user messages are stored but never sent as notifications; a store matches get_session_messages without them.
  • get_session_messages refuses limit: 500 (100 works).
  • An unknown Session is -32004 (controller.ErrSessionNotFound).
  • Spec mode (droid 0.244): ExitSpecMode asks with exit_spec_mode details that say supportsClientStartedHandoff. Answered with a proceed_new_session* option and clientStartsHandoffSession, the Daemon creates the new Session without starting it (spec_handoff_session_created) and the Client loads it and sends the plan: PermissionAnswer.ClientStartsHandoffSession, reported by SpecHandoffStarted or SpecHandoffFailed.
  • Queued AskUser (droid 1.1): daemon.ask_user with blocking: false and a context queues a question set; the agent keeps working. The Controller marks it AskUser.Queued: it does not put the Session in waiting, survives the turn ending or InterruptSession, and goes when it is answered or the Daemon sends ask_user_resolved (another Client answered, or the set was asked again under a new id). Answers come back to the agent as a user message with id ask-user-answer:<toolCallId>, after a user-only system receipt ask-user-receipt:<toolCallId> that renderers skip.
  • child_session_settled (droid 1.1) on a parent Session settles a Task child the Client may not reach (another computer): the store sets the child's summary status and its working state to idle.
  • behavesLikeModelId on a custom model (droid 1.1) names the built-in model it behaves like.
  • Background processes (droid 1.0): an Execute with fireAndForget answers Background process started (PID: …) and the Daemon reports the Session's processes with background_processes_changed (the whole list, capturedAtMs on the host's clock) and in load's backgroundProcesses. Session.BackgroundProcesses keeps them (cleared when the worker exits); daemon.kill_background_process (Client.KillBackgroundProcess) stops one, after which droid gives the agent the end as a model-only user message execute-completion:<toolUseId> that starts a turn.
  • Queued messages across a dropped connection (droid 1.1's reconciliation): they stay shown; the reload's pendingMessageRequestIds keeps the ones the Daemon admitted and drops the rest, and none of them is sent again. Messages carry seq, the order the store keeps them in.
  • AskUser option descriptions (droid 1.2): an Anthropic model may ask in Claude Code's AskUserQuestion shape (questions[].options[].{label, description}, behind Factory's claude_question_option_descriptions flag). The AskUser tool call's input then has questions and no questionnaire, and each question of daemon.ask_user carries optionDescriptions, index-aligned with options.
  • A Session seeded from another one (droid 1.2's seed on initialize_session) can start with a trailing window of the copied history: initialize's hasOlderMessages, kept by the store as load's is.
  • Automation run history (droid 1.2) carries failureReason and, when a user changed a run's outcome, outcomeOverride (the recorded outcome and who changed it); status is the changed outcome.

Fake Daemon

fake-daemon/ is a scripted stand-in for droid daemon and for droi's Gateway in front of it (Pairing Token, /meta, Scratch Workspaces, session files). It speaks the Daemon's protocol over WebSocket, replays a Scenario instead of running an agent, and checks every message it sends with @factory/droid-sdk's zod schemas (patched as droi patches them, in patches/). Clients' tests run against it, so they never need a Factory key.

  • Go: fakedaemon.Start(t, scenario) runs it in Node and gives its URL. The package embeds the Fake Daemon bundled into one script (fakedaemon/fake-daemon.mjs), so a test needs only node on PATH. fakedaemon.Turn scripts the agent: a reply, a permission, AskUser (blocking or queued, with droid 1.2's option descriptions), a todo list, structured output, spec (ExitSpecMode and its handoff, as droid 0.244 does them), or backgroundProcess (an Execute left running in the background, with droid 1.0's launch text, background_processes_changed and daemon.kill_background_process). Its load_session reports the scripted turn's state: the agent loop running, held messages (queuedMessages), pendingMessageRequestIds and background processes.

  • TypeScript: the npm package @droi/fake-daemon (fake-daemon/, with its built dist/), installed from this repository's tag:

    "@droi/fake-daemon": "github:kkkk2323/droid-sdk-go#v0.2.1&path:/fake-daemon"
    

    import { FakeDaemon } from '@droi/fake-daemon/fake-daemon'. Set FakeDaemon.appVersion to the Droi version /meta should answer.

After changing fake-daemon/ or fakedaemon/serve.ts, run pnpm build and commit what it writes (fake-daemon/dist, fakedaemon/fake-daemon.mjs); CI fails when they are out of date.

Tests

pnpm install && pnpm typecheck
go test -race ./...      # unit + Fake Daemon (skipped without Node)

Live tests run a throwaway droid daemon in a temporary HOME:

FACTORY_API_KEY=fk-... [FACTORY_API_BASE_URL=...] [DROID_LIVE_MODEL=...] \
  DROID_LIVE_RECORD=testdata/live go test -run 'Live|Replay' -v .

They cover a turn, a permission, a message sent while busy (store transcript equal to the Daemon's), settings, rename/archive/search, paging, context breakdown, skills, commands, MCP, git diff, file content, an unknown Session, a Daemon restart mid-Session (reconnect, reload, next turn) and compaction. TestReplayRecordings decodes every recorded frame (credentials redacted) with the generated types and lists fields they lack, so protocol drift shows without a network.

Upgrading to a new @factory/droid-sdk

gen/generate.sh 0.10.0 && go build ./... && go test -race ./...

generate.sh installs that release from npm, pulls the zod schemas and the DaemonClient method table out of its bundle, and rewrites protocol/ and zz_client_methods.go (same version in, same bytes out). What a newer droid has that the release lacks is listed in gen/gen.mjs: fields on generated structs in NEWER_FIELDS, whole types in NEWER_TYPES and methods in NEWER_METHODS; generation fails once a release has one of them itself. Against 0.10.0 they are:

  • NEWER_FIELDS: optionDescriptions on AskUserQuestion, hasOlderMessages on the initialize result, failureReason and outcomeOverride on AutomationRunRecord (droid 1.2); blocking and context on AskUser and on load's pending AskUser requests (droid 1.1); behavesLikeModelId on ModelMetadata (droid 1.1); backgroundWork on droid_working_state_changed and on the load result, and the load result's backgroundProcesses (droid 1.0).
  • NEWER_TYPES: AutomationRunOutcomeOverride (droid 1.2), SessionBackgroundProcess, SessionBackgroundProcessesSnapshot, BackgroundProcessesChangedNotification, and the params and result of daemon.kill_background_process (droid 1.0).
  • NEWER_METHODS: daemon.kill_background_process (droid 1.0).

Session notifications newer than the release are not in the generated union (Value() is nil); the code that handles them reads their raw JSON: ask_user_resolved (controller/queued.go), child_session_settled (session/settled.go) and background_processes_changed. The compiler points at the hand-written code that uses what changed.

Measured on 0.9.1 → 0.10.0: 171 types added (and droid 1.0's 5 in NEWER_TYPES), 5 renamed or dropped (EditableSkillSettingsLevel is ConfigItemsParamsLevel now), 132 → 148 methods (one of them droid 1.0's), 2 signatures changed (GetDefaultSettings and RelayStart take params), and the spec handoff's hand-written decoding replaced by the generated SpecHandoffSessionCreatedNotification. gen/ needed three fixes: 0.10's engine.request(...) calls, unions whose branch discriminator is a z.enum, and requests the TS client does not call (get_git_branch_divergence, warmup_cache, desktop.status), which are methods now rather than requests of the Daemon.

Measured on 0.8.0 → 0.9.1: 11 types added or renamed, ~500 changed lines of generated code, the same 132 methods, and 6 compile errors, all in session where it uses what 0.9 added (message retraction, rich message content). Regenerating takes about a minute; porting the new behaviour of a release is hand work on the TS sources (split readable with gen/split.cjs), typically hours, mostly in session and controller.

Documentation

Overview

Package droid is a Go client for the Droid Daemon (`droid daemon`): the JSON-RPC protocol over a WebSocket that Factory's TypeScript SDK (@factory/droid-sdk) speaks. Client is one authenticated connection; the session package builds Sessions, their state and reconnection on top.

Index

Constants

View Source
const (
	CodeAuthenticationError = -32001
)

JSON-RPC error codes the Daemon uses.

View Source
const Version = "0.1.0"

Version is this package's release, sent to the Daemon as the SDK version.

Variables

View Source
var ErrClosed = errors.New("droid: connection closed")

ErrClosed is the error of a connection the Client closed.

Functions

func RequestIDOf

func RequestIDOf(ctx context.Context) string

RequestIDOf is the id WithRequestID put on ctx, or "".

func WithRequestID

func WithRequestID(ctx context.Context, id string) context.Context

WithRequestID makes the request Call sends with ctx carry id, which the notifications it causes refer to (as create_message's requestId).

func WithResponseHook

func WithResponseHook(ctx context.Context, fn func(result json.RawMessage)) context.Context

WithResponseHook makes Call run fn with the result of the request it sends with ctx, on the read goroutine, as the response arrives and before any message that follows it is handled. fn must not block.

Types

type AuthError

type AuthError struct{ Err error }

AuthError is a credential the Daemon refused.

func (*AuthError) Error

func (e *AuthError) Error() string

func (*AuthError) Unwrap

func (e *AuthError) Unwrap() error

type Client

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

Client is one connection to the Daemon. Its methods are safe from any goroutine.

func Dial

func Dial(ctx context.Context, opts Options) (*Client, error)

Dial opens a connection and, when opts.Credential is set, authenticates it.

func (*Client) AcknowledgeMissionReadinessWarning

AcknowledgeMissionReadinessWarning calls daemon.acknowledge_mission_readiness_warning.

func (*Client) AddMCPServer

AddMCPServer calls daemon.add_mcp_server.

func (*Client) AddMarketplace

AddMarketplace calls daemon.add_marketplace.

func (*Client) AddUserMessage

AddUserMessage calls daemon.add_user_message.

func (*Client) ApplyAutomationConfig

ApplyAutomationConfig calls daemon.apply_automation_config.

func (*Client) ApplyUserPreferences added in v0.4.0

ApplyUserPreferences calls daemon.apply_user_preferences.

func (*Client) ArchiveSession

ArchiveSession calls daemon.archive_session.

func (*Client) Authenticate

Authenticate calls daemon.authenticate.

func (*Client) AuthenticateMCPServer

func (c *Client) AuthenticateMCPServer(ctx context.Context, params protocol.AuthenticateMCPServerParams) (*protocol.MCPSuccessResult, error)

AuthenticateMCPServer calls daemon.authenticate_mcp_server.

func (*Client) Call

func (c *Client) Call(ctx context.Context, method string, params, result any) error

Call sends a request and decodes its result into result (when not nil). For a method the Daemon acknowledges first (protocol.Methods), Call waits for the notification that completes it.

func (*Client) CancelMCPAuth

CancelMCPAuth calls daemon.cancel_mcp_auth.

func (*Client) CancelSearchSessions added in v0.4.0

CancelSearchSessions calls daemon.cancel_search_sessions.

func (*Client) ChangeWorkingDirectory

ChangeWorkingDirectory calls daemon.change_working_directory.

func (*Client) CheckFolderTrust

CheckFolderTrust calls daemon.check_folder_trust.

func (*Client) CheckoutGitBranch

CheckoutGitBranch calls daemon.checkout_git_branch.

func (*Client) CleanupWorktree

CleanupWorktree calls daemon.cleanup_worktree.

func (*Client) ClearMCPAuth

ClearMCPAuth calls daemon.clear_mcp_auth.

func (*Client) Close

func (c *Client) Close() error

Close ends the connection.

func (*Client) CloseSession

CloseSession calls daemon.close_session.

func (*Client) CloseTerminal

CloseTerminal calls daemon.close_terminal.

func (*Client) CompactSession

CompactSession calls daemon.compact_session.

func (*Client) ConfigItems added in v0.4.0

ConfigItems calls daemon.config_items.

func (*Client) CreateAutomation

CreateAutomation calls daemon.create_automation.

func (*Client) CreateCron

CreateCron calls daemon.create_cron.

func (*Client) CreatePR

CreatePR calls daemon.create_pr.

func (*Client) CreateTerminal

CreateTerminal calls daemon.create_terminal.

func (*Client) DeleteAutomation

DeleteAutomation calls daemon.delete_automation.

func (*Client) DeleteCron

DeleteCron calls daemon.delete_cron.

func (*Client) DeleteCustomModel

DeleteCustomModel calls daemon.delete_custom_model.

func (*Client) DeleteWorktreeSetupProfile

DeleteWorktreeSetupProfile calls daemon.delete_worktree_setup_profile.

func (*Client) DesktopEnsure added in v0.4.0

func (c *Client) DesktopEnsure(ctx context.Context) (*protocol.DaemonDesktopResult, error)

DesktopEnsure calls daemon.desktop.ensure.

func (*Client) DesktopInput added in v0.4.0

func (c *Client) DesktopInput(ctx context.Context) (*protocol.DesktopInputResult, error)

DesktopInput calls daemon.desktop.input.

func (*Client) DesktopStatus added in v0.4.0

func (c *Client) DesktopStatus(ctx context.Context) (*protocol.DaemonDesktopResult, error)

DesktopStatus calls daemon.desktop.status.

func (*Client) DispatchAutomationRun added in v0.4.0

DispatchAutomationRun calls daemon.dispatch_automation_run.

func (*Client) Done

func (c *Client) Done() <-chan struct{}

Done is closed when the connection ends; Err then says why.

func (*Client) Err

func (c *Client) Err() error

Err returns why the connection ended, or nil while it is open.

func (*Client) ExecuteRewind

ExecuteRewind calls daemon.execute_rewind.

func (*Client) ForkAutomation

ForkAutomation calls daemon.fork_automation.

func (*Client) ForkSession

ForkSession calls daemon.fork_session.

func (*Client) GenerateSemanticDiff

GenerateSemanticDiff calls daemon.generate_semantic_diff.

func (*Client) GetAutomationHistory

GetAutomationHistory calls daemon.get_automation_history.

func (*Client) GetAutomationVisual

GetAutomationVisual calls daemon.get_automation_visual.

func (*Client) GetCheckoutMetadata added in v0.4.0

GetCheckoutMetadata calls daemon.get_checkout_metadata.

func (*Client) GetContextBreakdown

GetContextBreakdown calls daemon.get_context_breakdown.

func (*Client) GetDefaultSettings

GetDefaultSettings calls daemon.get_default_settings.

func (*Client) GetGitBranchDivergence

GetGitBranchDivergence calls daemon.get_git_branch_divergence.

func (*Client) GetGitDiff

GetGitDiff calls daemon.get_git_diff.

func (*Client) GetGitDiffFileContents added in v0.4.0

GetGitDiffFileContents calls daemon.get_git_diff_file_contents.

func (*Client) GetMCPConfig

func (c *Client) GetMCPConfig(ctx context.Context) (*protocol.GetMCPConfigResult, error)

GetMCPConfig calls daemon.get_mcp_config.

func (*Client) GetProxyToken

func (c *Client) GetProxyToken(ctx context.Context, params json.RawMessage) (*protocol.GetProxyTokenResult, error)

GetProxyToken calls daemon.get_proxy_token.

func (*Client) GetRewindInfo

GetRewindInfo calls daemon.get_rewind_info.

func (*Client) GetSemanticDiffCache

GetSemanticDiffCache calls daemon.get_semantic_diff_cache.

func (*Client) GetSessionMessages

GetSessionMessages calls daemon.get_session_messages.

func (*Client) GetSessionTurnOutcome added in v0.4.0

GetSessionTurnOutcome calls daemon.get_session_turn_outcome.

func (*Client) GetUserPreferencesState added in v0.4.0

GetUserPreferencesState calls daemon.get_user_preferences_state.

func (*Client) GetWorkspaceFileContent

GetWorkspaceFileContent calls daemon.get_workspace_file_content.

func (*Client) GitCommit

GitCommit calls daemon.git_commit.

func (*Client) GitPush

GitPush calls daemon.git_push.

func (*Client) Handle

func (c *Client) Handle(method string, h RequestHandler)

Handle sets the handler of a request the Daemon sends (see protocol.ServerRequest*). A request without a handler is answered with an error.

func (*Client) HandleLater

func (c *Client) HandleLater(method string, fn func(Request))

HandleLater sets fn to receive the requests of method without answering them: answer each with Respond. fn runs on the read goroutine and must not block.

func (*Client) HoldSessionCrons

HoldSessionCrons calls daemon.hold_session_crons.

func (*Client) InitializeSession

InitializeSession calls daemon.initialize_session.

func (*Client) InspectMissionReadiness

InspectMissionReadiness calls daemon.inspect_mission_readiness.

func (*Client) InspectWorktreeDeletion

InspectWorktreeDeletion calls daemon.inspect_worktree_deletion.

func (*Client) InstallPlugin

InstallPlugin calls daemon.install_plugin.

func (*Client) InstallSSHKey

InstallSSHKey calls daemon.install_ssh_key.

func (*Client) InterruptSession

InterruptSession calls daemon.interrupt_session.

func (*Client) KillBackgroundProcess added in v0.4.0

KillBackgroundProcess calls daemon.kill_background_process.

func (*Client) KillWorkerSession

KillWorkerSession calls daemon.kill_worker_session.

func (*Client) ListAutomations

ListAutomations calls daemon.list_automations.

func (*Client) ListAvailablePlugins

ListAvailablePlugins calls daemon.list_available_plugins.

func (*Client) ListAvailableSessions

ListAvailableSessions calls daemon.list_available_sessions.

func (*Client) ListCommands

ListCommands calls daemon.list_commands.

func (*Client) ListCrons

ListCrons calls daemon.list_crons.

func (*Client) ListCustomModels

func (c *Client) ListCustomModels(ctx context.Context) (*protocol.ListCustomModelsResult, error)

ListCustomModels calls daemon.list_custom_models.

func (*Client) ListFiles

ListFiles calls daemon.list_files.

func (*Client) ListGitBranches

ListGitBranches calls daemon.list_git_branches.

func (*Client) ListInstalledPlugins

ListInstalledPlugins calls daemon.list_installed_plugins.

func (*Client) ListMCPRegistry

ListMCPRegistry calls daemon.list_mcp_registry.

func (*Client) ListMCPServers

ListMCPServers calls daemon.list_mcp_servers.

func (*Client) ListMCPTools

ListMCPTools calls daemon.list_mcp_tools.

func (*Client) ListManagedWorktrees

ListManagedWorktrees calls daemon.list_managed_worktrees.

func (*Client) ListMarketplaces

ListMarketplaces calls daemon.list_marketplaces.

func (*Client) ListModels

ListModels calls daemon.list_models.

func (*Client) ListOpenedSessions

ListOpenedSessions calls daemon.list_opened_sessions.

func (*Client) ListSkills

ListSkills calls daemon.list_skills.

func (*Client) ListTerminals

ListTerminals calls daemon.list_terminals.

func (*Client) ListWorktreeSetupProfiles

ListWorktreeSetupProfiles calls daemon.list_worktree_setup_profiles.

func (*Client) LoadSession

LoadSession calls daemon.load_session.

func (*Client) Logout

func (c *Client) Logout(ctx context.Context) (*protocol.LogoutResult, error)

Logout calls daemon.logout.

func (*Client) PauseAutomation

PauseAutomation calls daemon.pause_automation.

func (*Client) PullURLToCwdFile

PullURLToCwdFile calls daemon.pull_url_to_cwd_file.

func (*Client) PushCwdFileToURL

PushCwdFileToURL calls daemon.push_cwd_file_to_url.

func (*Client) RefreshConnectorToolCatalog added in v0.4.0

func (c *Client) RefreshConnectorToolCatalog(ctx context.Context) (*protocol.RefreshConnectorToolCatalogResult, error)

RefreshConnectorToolCatalog calls daemon.refresh_connector_tool_catalog.

func (*Client) RelayGetStatus

func (c *Client) RelayGetStatus(ctx context.Context) (*protocol.RelayGetStatusResult, error)

RelayGetStatus calls daemon.relay.get_status.

func (*Client) RelayStart

RelayStart calls daemon.relay.start.

func (*Client) RelayStop

func (c *Client) RelayStop(ctx context.Context) (*protocol.RelayStopResult, error)

RelayStop calls daemon.relay.stop.

func (*Client) RemoveMCPServer

func (c *Client) RemoveMCPServer(ctx context.Context, params protocol.RemoveMCPServerParams) (*protocol.MCPSuccessResult, error)

RemoveMCPServer calls daemon.remove_mcp_server.

func (*Client) RemoveMarketplace

RemoveMarketplace calls daemon.remove_marketplace.

func (*Client) RenameAutomation

RenameAutomation calls daemon.rename_automation.

func (*Client) RenameSession

RenameSession calls daemon.rename_session.

func (*Client) ResizeTerminal

func (c *Client) ResizeTerminal(ctx context.Context, params protocol.ResizeTerminalParams) (*protocol.ResizeResult, error)

ResizeTerminal calls daemon.resize_terminal.

func (*Client) ResolvePullRequestStatuses

ResolvePullRequestStatuses calls daemon.resolve_pull_request_statuses.

func (*Client) ResolveQueuedUserMessage

func (c *Client) ResolveQueuedUserMessage(ctx context.Context, params json.RawMessage) (*protocol.ResolveQueuedUserMessageResult, error)

ResolveQueuedUserMessage calls daemon.resolve_queued_user_message.

func (*Client) ResolveUserPreferences added in v0.4.0

ResolveUserPreferences calls daemon.resolve_user_preferences.

func (*Client) Respond

func (c *Client) Respond(ctx context.Context, id string, result any) error

Respond sends the result of a request the Daemon sent. The Daemon also takes the answer to a request it sent another connection, as one restored by daemon.load_session.

func (*Client) ResumeAutomation

ResumeAutomation calls daemon.resume_automation.

func (*Client) ResumeSessionCrons

ResumeSessionCrons calls daemon.resume_session_crons.

func (*Client) RunAutomation

RunAutomation calls daemon.run_automation.

func (*Client) SaveSemanticDiffCache

SaveSemanticDiffCache calls daemon.save_semantic_diff_cache.

func (*Client) SaveWorktreeSetupProfile

SaveWorktreeSetupProfile calls daemon.save_worktree_setup_profile.

func (*Client) SearchFiles

SearchFiles calls daemon.search_files.

func (*Client) SearchSessions

SearchSessions calls daemon.search_sessions.

func (*Client) SetPluginEnabled

SetPluginEnabled calls daemon.set_plugin_enabled.

func (*Client) SetSkillDisabled

SetSkillDisabled calls daemon.set_skill_disabled.

func (*Client) SfCreateWorkstream

SfCreateWorkstream calls daemon.sf.create_workstream.

func (*Client) SfDeleteWorkstream

SfDeleteWorkstream calls daemon.sf.delete_workstream.

func (*Client) SfGetWorkstream

SfGetWorkstream calls daemon.sf.get_workstream.

func (*Client) SfHydrateWorkstreamContent

SfHydrateWorkstreamContent calls daemon.sf.hydrate_workstream_content.

func (*Client) SfListActivities

SfListActivities calls daemon.sf.list_activities.

func (*Client) SfListChanges

SfListChanges calls daemon.sf.list_changes.

func (*Client) SfListEvents

SfListEvents calls daemon.sf.list_events.

func (*Client) SfListSignals

SfListSignals calls daemon.sf.list_signals.

func (*Client) SfListWorkstreams

SfListWorkstreams calls daemon.sf.list_workstreams.

func (*Client) SfMarkEventsRead

SfMarkEventsRead calls daemon.sf.mark_events_read.

func (*Client) SfMarkEventsUnread

SfMarkEventsUnread calls daemon.sf.mark_events_unread.

func (*Client) SfPublishWorkstreamContent

SfPublishWorkstreamContent calls daemon.sf.publish_workstream_content.

func (*Client) SfResolveActivityReview

SfResolveActivityReview calls daemon.sf.resolve_activity_review.

func (*Client) SfUpdateWorkstream

SfUpdateWorkstream calls daemon.sf.update_workstream.

func (*Client) StartPullRequestLayerManifestGeneration added in v0.4.0

StartPullRequestLayerManifestGeneration calls daemon.start_pull_request_layer_manifest_generation.

func (*Client) SubmitBugReport

SubmitBugReport calls daemon.submit_bug_report.

func (*Client) SubmitMCPAuthCode

func (c *Client) SubmitMCPAuthCode(ctx context.Context, params protocol.SubmitMCPAuthCodeParams) (*protocol.MCPSuccessResult, error)

SubmitMCPAuthCode calls daemon.submit_mcp_auth_code.

func (*Client) SubmitMCPAuthError

func (c *Client) SubmitMCPAuthError(ctx context.Context, params protocol.SubmitMCPAuthErrorParams) (*protocol.MCPSuccessResult, error)

SubmitMCPAuthError calls daemon.submit_mcp_auth_error.

func (*Client) Subscribe

func (c *Client) Subscribe(fn func(Notification)) (unsubscribe func())

Subscribe calls fn with every notification, on the connection's read goroutine, in order; fn must not block. The returned function unsubscribes.

func (*Client) ToggleMCPServer

func (c *Client) ToggleMCPServer(ctx context.Context, params protocol.ToggleMCPServerParams) (*protocol.MCPSuccessResult, error)

ToggleMCPServer calls daemon.toggle_mcp_server.

func (*Client) ToggleMCPTool

ToggleMCPTool calls daemon.toggle_mcp_tool.

func (*Client) TriggerUpdate

func (c *Client) TriggerUpdate(ctx context.Context) (*protocol.TriggerUpdateResult, error)

TriggerUpdate calls daemon.trigger_update.

func (*Client) TrustFolder

TrustFolder calls daemon.trust_folder.

func (*Client) UnarchiveSession

UnarchiveSession calls daemon.unarchive_session.

func (*Client) UninstallPlugin

UninstallPlugin calls daemon.uninstall_plugin.

func (*Client) UpdateAutomation

UpdateAutomation calls daemon.update_automation.

func (*Client) UpdateAutomationModel

UpdateAutomationModel calls daemon.update_automation_model.

func (*Client) UpdateAutomationPrivacy

UpdateAutomationPrivacy calls daemon.update_automation_privacy.

func (*Client) UpdateAutomationPrompt

UpdateAutomationPrompt calls daemon.update_automation_prompt.

func (*Client) UpdateAutomationSchedule

UpdateAutomationSchedule calls daemon.update_automation_schedule.

func (*Client) UpdateCron

UpdateCron calls daemon.update_cron.

func (*Client) UpdateMCPConfig

UpdateMCPConfig calls daemon.update_mcp_config.

func (*Client) UpdateMarketplace

UpdateMarketplace calls daemon.update_marketplace.

func (*Client) UpdatePlugin

UpdatePlugin calls daemon.update_plugin.

func (*Client) UpdateSessionDefaults

UpdateSessionDefaults calls daemon.update_session_defaults.

func (*Client) UpdateSessionSettings

UpdateSessionSettings calls daemon.update_session_settings.

func (*Client) UpsertCustomModel

UpsertCustomModel calls daemon.upsert_custom_model.

func (*Client) ValidateWorkingDirectory

ValidateWorkingDirectory calls daemon.validate_working_directory.

func (*Client) WarmupCache added in v0.4.0

WarmupCache calls daemon.warmup_cache.

func (*Client) WriteTerminalData

func (c *Client) WriteTerminalData(ctx context.Context, params protocol.WriteTerminalDataParams) (*protocol.WriteDataResult, error)

WriteTerminalData calls daemon.write_terminal_data.

func (*Client) WriteWorkspaceFileContent

WriteWorkspaceFileContent calls daemon.write_workspace_file_content.

type ClosedError

type ClosedError struct {
	Status websocket.StatusCode
	Err    error
}

ClosedError is a connection the Daemon or the network closed.

func (*ClosedError) Error

func (e *ClosedError) Error() string

func (*ClosedError) Unwrap

func (e *ClosedError) Unwrap() error

type Credential

type Credential struct {
	APIKey string
	Token  string
}

Credential is what daemon.authenticate accepts: a Factory API key or an access token.

type DialError

type DialError struct {
	StatusCode int
	Err        error
}

DialError is a failure to open the WebSocket; StatusCode is the HTTP status of a refused handshake (401: a Gateway refused the token; 503: the Daemon is not running behind it).

func (*DialError) Error

func (e *DialError) Error() string

func (*DialError) Unwrap

func (e *DialError) Unwrap() error

type Direction

type Direction int

Direction tells a recorded frame's way.

const (
	Sent Direction = iota
	Received
)

func (Direction) String

func (d Direction) String() string

type Notification

type Notification struct {
	Method string
	Params json.RawMessage
}

Notification is a message the Daemon sends unasked.

type Options

type Options struct {
	// URL of the Daemon's WebSocket, as ws://127.0.0.1:<port>, or of a
	// Gateway that forwards to it.
	URL string
	// Credential authenticates the connection (daemon.authenticate). Leave
	// it nil to connect without authenticating, as a trusted transport does.
	Credential *Credential
	// Caller and Surface say which kind of client this is; they default to
	// "go-sdk" and "sdk". The Daemon refuses caller "sdk" without SDK
	// metadata, whose language can only be typescript or python.
	Caller  string
	Surface string
	// RequestTimeout bounds a request that its context does not; 30s by
	// default. Some methods take longer (protocol.Methods).
	RequestTimeout time.Duration
	// ConnectTimeout bounds opening the socket; 5s by default.
	ConnectTimeout time.Duration
	// Header is sent with the WebSocket handshake.
	Header http.Header
	// Record, when set, sees every frame as it is sent or received, for
	// tests and diagnosis. It must not keep the slice.
	Record func(dir Direction, frame []byte)
	// BeforeCall, when set, runs before every request with its method and
	// the sessionId of its params ("" when it has none); an error fails the
	// request. Its ctx has the request's deadline but not its id or
	// response hook, which a call it makes must not take.
	BeforeCall func(ctx context.Context, method, sessionID string) error
	Logger     *slog.Logger
}

Options configure a connection.

type RPCError

type RPCError struct {
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

RPCError is an error the Daemon answered a request with.

func (*RPCError) Error

func (e *RPCError) Error() string

type Request

type Request struct {
	ID     string
	Method string
	Params json.RawMessage
}

Request is a request the Daemon sent the Client.

type RequestHandler

type RequestHandler func(ctx context.Context, params json.RawMessage) (any, error)

RequestHandler answers a request the Daemon sends the Client (a permission or AskUser prompt). The result is sent back as the response.

type TimeoutError

type TimeoutError struct {
	Method string
	Err    error
}

TimeoutError is a request that got no answer in time.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

func (*TimeoutError) Unwrap

func (e *TimeoutError) Unwrap() error

Directories

Path Synopsis
Package controller keeps a connection to the Droid Daemon usable and the Sessions loaded over it current: it connects and authenticates, reconnects after the connection drops and loads the Sessions again, tracks pending permission and AskUser prompts (keeping an answer given while a Session's worker is gone until the worker is back), and applies every session notification to a session.Manager.
Package controller keeps a connection to the Droid Daemon usable and the Sessions loaded over it current: it connects and authenticates, reconnects after the connection drops and loads the Sessions again, tracks pending permission and AskUser prompts (keeping an answer given while a Session's worker is gone until the worker is back), and applies every session notification to a session.Manager.
Package fakedaemon runs the Fake Daemon (../fake-daemon), the Node stand-in for `droid daemon` and droi's Gateway, for Go tests.
Package fakedaemon runs the Fake Daemon (../fake-daemon), the Node stand-in for `droid daemon` and droi's Gateway, for Go tests.
Package protocol holds the Droid Daemon's wire types, generated from the zod schemas of @factory/droid-sdk (see gen/).
Package protocol holds the Droid Daemon's wire types, generated from the zod schemas of @factory/droid-sdk (see gen/).
Package session keeps the state of the Daemon's Sessions as one Client sees it: each Session's transcript, working state, settings, token usage, task list, queued and optimistic user messages, and how subagent Sessions hang under their parents.
Package session keeps the state of the Daemon's Sessions as one Client sees it: each Session's transcript, working state, settings, token usage, task list, queued and optimistic user messages, and how subagent Sessions hang under their parents.

Jump to

Keyboard shortcuts

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