Documentation
¶
Overview ¶
Package forge ties the Forge pipeline to the live rysh runtime: it stores per-project integration definitions, ingests their specs into the IR, builds tool-packs, and registers the resulting tools into the agent registry under the §5.6 exposure policy. It is the daemon-side counterpart to the `rysh forge` CLI (which generates artifacts to disk).
Index ¶
- Constants
- func AllowSharedOp(opName string, mutating bool, allow, block []string) bool
- func LoadSpecAPI(workDir string, def Integration) (*ir.API, error)
- func SaveStore(workDir string, defs []Integration) error
- func SpecDir(workDir, name string) string
- func StoreSpec(workDir, name string, spec []byte, ext string) (string, error)
- func ValidateGRPCProtocol(protocol, source string) error
- type Diff
- type Integration
- type Manager
- func (m *Manager) APIOps(name string) []SharedOp
- func (m *Manager) Bootstrap(ctx context.Context)
- func (m *Manager) Close()
- func (m *Manager) Disable(name string) error
- func (m *Manager) Enable(ctx context.Context, def Integration, target ScopeTarget) (int, toolpack.ExposureMode, error)
- func (m *Manager) EnableByName(ctx context.Context, name string, target ScopeTarget) (int, toolpack.ExposureMode, error)
- func (m *Manager) GlobalTarget() ScopeTarget
- func (m *Manager) List() []Status
- func (m *Manager) Remove(name string) error
- func (m *Manager) ReplayScope(ctx context.Context, scopeKey string, target ScopeTarget)
- func (m *Manager) RunOp(ctx context.Context, opName string, args json.RawMessage) (*sharedtools.ToolOutput, error)
- func (m *Manager) RunOpWithAuth(ctx context.Context, opName string, args json.RawMessage, bearer string) (*sharedtools.ToolOutput, error)
- func (m *Manager) SharedOps(scopeKeys map[string]bool) []SharedOp
- func (m *Manager) Tools(name string) ([]string, bool)
- func (m *Manager) UnregisterScope(scopeKey string)
- func (m *Manager) WorkDir() string
- type ScopeTarget
- type SharedOp
- type Status
Constants ¶
const ( SourceOpenAPI = "openapi" SourceGraphQL = "graphql" // SourceGRPC ingests a compiled protobuf FileDescriptorSet // (protoc --descriptor_set_out / buf build -o). Methods are modeled as // unary POSTs to the gRPC wire path, so calling them needs a server that // speaks JSON over that path (grpc-gateway transcoding or Connect) — see // ingest.GRPC. SourceGRPC = "grpc" )
Variables ¶
This section is empty.
Functions ¶
func AllowSharedOp ¶
AllowSharedOp reports whether a remote subscriber may invoke op `opName` (with the given `mutating` flag) given the owner's allow / block glob lists. It encodes the "default-deny mutation" policy from the plan:
- The block list always wins: any match → denied.
- If the allow list is non-empty, the op MUST match it to be permitted (an explicit owner opt-in for exactly the ops they choose to expose).
- If the allow list is empty, read ops (non-mutating) are permitted but mutating ops are denied — the owner must opt mutations in explicitly.
Patterns are shell-style globs over the op name (e.g. "weather_*", "*_getPet"); a malformed pattern simply never matches.
func LoadSpecAPI ¶
func LoadSpecAPI(workDir string, def Integration) (*ir.API, error)
LiveAPI ingests an enabled/known integration's spec into the IR (used by the CLI `rysh forge generate`/diff paths).
func SaveStore ¶
func SaveStore(workDir string, defs []Integration) error
SaveStore writes the integrations index atomically.
func StoreSpec ¶
StoreSpec writes spec bytes under the integration's directory and returns the workDir-relative path saved into the definition.
func ValidateGRPCProtocol ¶ added in v0.2.11
ValidateGRPCProtocol checks a --grpc-protocol value against the source it is attached to: only gRPC sources have streaming wire protocols to choose.
Types ¶
type Diff ¶
type Diff struct {
Added []string // operation ids present only in the new spec
Removed []string // operation ids present only in the old spec
Changed []string // operation ids whose method/path/params/mutating changed
// Stream deltas are reported SEPARATELY from the operation deltas above,
// never merged into them. Two reasons, both load-bearing:
//
// - The consequences differ. A removed stream breaks a background
// streaming session; a removed operation breaks a tool call. A caller
// deciding whether to adopt a new spec needs to tell them apart.
// - The id spaces overlap. ir.API.Streams and ir.API.Operations are
// separate lists of ir.Operation, so one id can name both a unary
// operation and a stream. Merging would collide and report one while
// hiding the other.
StreamsAdded []string // stream ids present only in the new spec
StreamsRemoved []string // stream ids present only in the old spec
StreamsChanged []string // stream ids whose signature changed
}
Diff is the operation-level delta between two versions of an API spec — the basis of spec-driven maintenance ("what changed when the spec changed").
type Integration ¶
type Integration struct {
Name string `json:"name"`
Source string `json:"source"` // "openapi" | "graphql" | "grpc"
SpecFile string `json:"spec_file"` // path under .rysh/forge/<name>/, relative to workDir
BaseURL string `json:"base_url,omitempty"` // override the spec's server URL
// WSURL overrides the websocket URL used for GraphQL subscriptions. When
// empty, it is derived from the endpoint by scheme convention (http→ws,
// https→wss). Set with `forge add --ws-url`.
WSURL string `json:"ws_url,omitempty"`
// GRPCProtocol selects the wire protocol for a gRPC source's
// server-streaming sessions: "" / "gateway" (grpc-gateway NDJSON) or
// "connect" (Connect enveloped framing, JSON codec — design 015 §5.3). A
// server accepts only its own request shape, so this is explicit, not
// sniffed. Set with `forge add --grpc-protocol`.
GRPCProtocol string `json:"grpc_protocol,omitempty"`
CredentialEnv string `json:"credential_env,omitempty"`
BasicUserEnv string `json:"basic_user_env,omitempty"`
BasicPassEnv string `json:"basic_pass_env,omitempty"`
// Auth declares a JWT/OAuth2 token-acquisition + refresh flow (forged-API auth
// plan, Phase A). When set, it supersedes the static CredentialEnv bearer.
// It holds only env-var names + URLs — never secret values.
Auth *runtime.AuthConfig `json:"auth,omitempty"`
Policy toolpack.Policy `json:"policy"`
Enabled bool `json:"enabled"`
Scope string `json:"scope,omitempty"` // scope key it was enabled at ("" / "global" ⇒ global)
}
Integration is a persisted, per-project integration definition. Secrets are never stored here; CredentialEnv names an environment variable that holds the credential at runtime.
func LoadStore ¶
func LoadStore(workDir string) ([]Integration, error)
LoadStore reads the integrations index. A missing file yields an empty slice.
func (Integration) Validate ¶
func (d Integration) Validate() error
Validate checks a definition is usable.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the live, per-session set of enabled integrations and registers their tools into the shared agent registry. Like the MCP manager, it registers into the SHARED registry that panes/agents clone at creation, so Bootstrap (startup) reaches every pane; a live `##integration enable` reaches panes/agents created afterward.
func NewManager ¶
func NewManager(reg *sharedtools.ToolRegistry, workDir string, redact func(string) string) *Manager
NewManager creates a Manager registering into reg. redact (optional) is applied to tool output before it leaves the session.
func (*Manager) APIOps ¶
APIOps returns the op specs for the integration named `name`, deduped across every scope it is enabled at. This is the name-keyed counterpart of SharedOps (which is scope-keyed): forged-API SHARING is by integration name, not by a pane/tab scope, so this is what `##forge share api <name>` exposes. Empty when the integration is not enabled anywhere (it must be enabled to be runnable).
func (*Manager) Bootstrap ¶
Bootstrap enables every persisted integration marked Enabled. Run once at startup, before panes clone the registry.
func (*Manager) Close ¶
func (m *Manager) Close()
Close unregisters all active integration tools and cancels every live streaming session. Called at workspace/daemon shutdown so no stream outlives the session that started it.
func (*Manager) Disable ¶
Disable unregisters an integration's tools at EVERY scope it is enabled at and persists Enabled=false.
func (*Manager) Enable ¶
func (m *Manager) Enable(ctx context.Context, def Integration, target ScopeTarget) (int, toolpack.ExposureMode, error)
Enable loads, registers (into target), and persists an integration as enabled.
func (*Manager) EnableByName ¶
func (m *Manager) EnableByName(ctx context.Context, name string, target ScopeTarget) (int, toolpack.ExposureMode, error)
EnableByName enables a previously-added integration by name into target.
func (*Manager) GlobalTarget ¶
func (m *Manager) GlobalTarget() ScopeTarget
GlobalTarget is the default scope target: the shared (session-wide) registry, the root of every pane's scope chain. Bootstrap and unscoped callers use it.
func (*Manager) List ¶
List returns a sorted snapshot of all known integrations (persisted + active).
func (*Manager) Remove ¶
Remove disables and deletes an integration definition (and its stored spec).
func (*Manager) ReplayScope ¶
func (m *Manager) ReplayScope(ctx context.Context, scopeKey string, target ScopeTarget)
ReplayScope re-enables any persisted integration that was enabled at scopeKey, into target. Called by a Tab/Lane/PaneGroup/Pane actor when it restores with a known (stable) scope-instance id, so scoped enablement survives detach/attach and restart. No-op for the global scope (handled at Bootstrap).
func (*Manager) RunOp ¶
func (m *Manager) RunOp(ctx context.Context, opName string, args json.RawMessage) (*sharedtools.ToolOutput, error)
RunOp executes a forge-registered operation by name on the owner side of a forged-API share (Task 2, phase 2b). It is the *forge-origin-enforcing* runner: it only ever runs an operation this Manager registered (looked up in the live `active` set). A built-in / MCP / per-pane tool name — or any op the owner never enabled — fails the lookup and returns ErrKindMissing, so the invocation path can never reach a non-forge executor.
The op runs with the owner's real credentials (the forge executor holds the upstream base URL + auth). Redaction and the allow/deny gate are applied by the caller (UpstreamShareActor) BEFORE and AFTER this call — RunOp itself performs no policy check beyond forge-origin, so it stays a pure primitive.
func (*Manager) RunOpWithAuth ¶
func (m *Manager) RunOpWithAuth(ctx context.Context, opName string, args json.RawMessage, bearer string) (*sharedtools.ToolOutput, error)
RunOpWithAuth is RunOp with an optional per-call bearer override (forged-API auth plan, Model B / delegated identity). When bearer is non-empty the op executes under the SUBSCRIBER's token for this one request: the token is injected via the request context and is never cached or persisted on the owner. An empty bearer is identical to RunOp (Model A / owner identity).
func (*Manager) SharedOps ¶
SharedOps returns the specs of forge-registered operations enabled at any of the given scope keys (e.g. "global", "tab:<id>", "pane:<id>"). This is the forge-origin filter for forged-API sharing: ONLY operations this manager registered are returned — built-in / MCP / per-pane tools are excluded by construction (they live in different registries / managers). Mutating comes from the op's RequiresApproval flag (forge sets it for non-GET/HEAD operations).
func (*Manager) Tools ¶
Tools returns the registered tool names for an enabled integration, unioned across every scope it is enabled at (deduplicated).
func (*Manager) UnregisterScope ¶
UnregisterScope retracts every active integration that was enabled at the given scope key (e.g. "lane:<id>") and forgets it. Called when the scope instance (tab/lane/group/pane) is torn down so its tools don't linger.
type ScopeTarget ¶
type ScopeTarget struct {
Key string // e.g. "global", "tab:<id>", "lane:<id>", "pane:<id>"
Registry *sharedtools.ToolRegistry // where the integration's tools are registered
}
ScopeTarget tells the manager which registry to enable an integration into and a stable key identifying that scope instance (for display/teardown). The caller (which knows the scope hierarchy) resolves it; this keeps forge free of any dependency on the scope service. Use Manager.GlobalTarget for the default.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package forgecmd implements the `forge` subcommand family (add / generate / list / diff / targets) independently of any particular front-end.
|
Package forgecmd implements the `forge` subcommand family (add / generate / list / diff / targets) independently of any particular front-end. |
|
Package gen defines the Forge generator framework: a pluggable Generator interface, a registry, and a FileSet output collector.
|
Package gen defines the Forge generator framework: a pluggable Generator interface, a registry, and a FileSet output collector. |
|
docs
Package docs generates Markdown API reference documentation from the IR.
|
Package docs generates Markdown API reference documentation from the IR. |
|
gosdk
Package gosdk is a Forge generator that emits a self-contained Go client SDK for an API described by the IR.
|
Package gosdk is a Forge generator that emits a self-contained Go client SDK for an API described by the IR. |
|
javasdk
Package javasdk is a Forge generator that emits a Java client SDK for an API described by the IR.
|
Package javasdk is a Forge generator that emits a Java client SDK for an API described by the IR. |
|
mcpserver
Package mcpserver generates a standalone Go MCP server for an API.
|
Package mcpserver generates a standalone Go MCP server for an API. |
|
pysdk
Package pysdk is a Forge generator that emits a Python client SDK (client.py + pyproject.toml + README.md) for an API described by the IR.
|
Package pysdk is a Forge generator that emits a Python client SDK (client.py + pyproject.toml + README.md) for an API described by the IR. |
|
tssdk
Package tssdk is a Forge generator that emits a TypeScript client SDK (client.ts + package.json + README.md) for an API described by the IR.
|
Package tssdk is a Forge generator that emits a TypeScript client SDK (client.ts + package.json + README.md) for an API described by the IR. |