Documentation
¶
Overview ¶
provision_credentials.go — provision support for OrgCredential resources.
Mirrors playbook.go shape: list, match by name, upsert. Idempotent: re-running with the same YAML produces NOOPs after the first apply.
Schema (studio/credentials/<name>.yaml):
name: slack-webhook-milestones
credential_type: webhook
description: Slack incoming webhook for #milestones channel
values:
default_url:
secret_env: SLACK_WEBHOOK_MILESTONES # CI-friendly
# OR
default_url:
secret_vault: taufinity/slack-webhook-milestones # local: shells out to token-vault
# Plain (non-secret) values:
auth_header:
value: Authorization
Resolution order per field: value → secret_env → secret_vault. Exactly one must be set per field; provision fails loud if zero or multiple are set.
Secrets never touch disk. They're read at apply time, marshalled into a JSON blob, and posted to the credentials API which encrypts at rest.
provision_image_taxonomy.go — provision support for the per-org image classification taxonomy.
PHASE-A STUB. The image_tags lookup table and its accompanying taxonomy storage land in Phase B4 of the image-asset POC. The taxonomy is referenced by the classify_image playbook step (added in Phase B3); the step validates produced tags against the vocabulary server-side. Until B4 lands, this handler validates the YAML schema and prints the intended action.
Plan reference: cto-as-a-service/docs/plans/2026-05-13-efteling-image-asset-poc.md
provision_images.go — provision support for seeding image knowledge files from a manifest of source URLs.
Flow per entry:
- download bytes from source_url
- name-based dedupe BEFORE upload (no classify cost on re-runs): if an image KnowledgeFile with the same derived name already exists in the org, skip
- resize down to download_max_dim longest edge if larger (cheap storage + keeps payload under the 25 MB upload cap)
- POST multipart to /api/knowledge-files (the real upload endpoint; never a direct DB write)
- the org's router rule (source=knowledge_file, mime~image/*) then auto-triggers the classify_image playbook asynchronously
Idempotent: re-running on an already-seeded org is a NOOP (step 2).
ground_truth_tags in the manifest are for offline eval only — they are NOT sent to the classify step (that's the model's job).
Plan reference: cto-as-a-service/docs/plans/2026-05-13-efteling-image-asset-poc.md
provision_knowledge.go — provision support for knowledge files (price lists, templates, golden records).
Calls POST /api/admin/knowledge-files/upsert (admin endpoint) which:
- matches existing rows by (org_id, name [, file_type]),
- short-circuits to NOOP if SHA256(content) == existing.Checksum,
- writes a v1 version snapshot on initial CREATE,
- tags the version row with X-Change-Source: provision (set by provision_client.go).
Each YAML file under studio/knowledge-base/ becomes one knowledge file. `content_path` (preferred) loads from a sibling file on disk so big price lists don't bloat the YAML; `content` (inline) is supported for small payloads.
provision_playbooks.go — provision support for playbook resources.
Mirrors the dashboards.go pattern: list, match by name, upsert, then reconcile child rows (steps). Idempotent: re-running with the same YAML produces NOOPs after the first apply.
Versioning: every PUT/POST hits the standard /api/playbooks endpoints, which call SaveVersionWithSummary internally. The X-Change-Source: provision header is set automatically by the client (see provision_client.go), which the handlers honour via middleware.ResolveChangedByType — version rows are tagged "provision" instead of "user"/"system".
provision_router_rules.go — provision support for router rules.
Phase B2 activates this handler. It now:
- Auto-creates a knowledge_file source-type router for the org if one doesn't exist (one router per org per source_type is enough — each carries N rules).
- Resolves the dispatch playbook by name → ID.
- Translates YAML conditions to the JSON config blob expected by the internal/router knowledge_file_match evaluator.
- Match-by-Name on rules within the router; PUT existing or POST new. Uniqueness is enforced server-side by migration 184's partial unique index on (router_id, name).
provision_test_suites.go — provision support for test suite resources.
Pattern mirrors provision_playbooks.go: list → name-match → upsert → reconcile cases. The suite's target playbook is resolved from a name to a numeric ID at apply time, so the YAML never carries environment-specific IDs.
provision_widgets.go — provision support for chat widget resources.
Pattern mirrors provision_playbooks.go: list, match by name, upsert. Widgets do not have child rows in our model, so reconciliation is single-call.
Index ¶
- Constants
- Variables
- func Execute() error
- func GetAPIURL() string
- func GetFormat() string
- func GetOrg() string
- func GetSite() string
- func IsDebug() bool
- func IsDryRun() bool
- func IsQuiet() bool
- func Print(format string, args ...any)
- func PrintLn(msg string)
- func RunStdioBridge(ctx context.Context, cfg StdioBridgeConfig) error
- func SetSite(site string)
- type DeviceCodeResponse
- type DeviceCodeStatusResponse
- type StdioBridgeConfig
- type TokenSource
Constants ¶
const DefaultAPIURL = "https://studio.taufinity.io"
DefaultAPIURL is the default Taufinity API endpoint.
Variables ¶
var ( Version = "dev" GitCommit = "unknown" BuildTime = "unknown" )
Build-time variables (set via ldflags). Kept as package-level vars so the Makefile's -X linker flags still work; buildinfo.FromBuildtime falls back to debug.BuildInfo when they're left at their defaults.
Functions ¶
func RunStdioBridge ¶
func RunStdioBridge(ctx context.Context, cfg StdioBridgeConfig) error
RunStdioBridge runs the stdio bridge against the configured upstream. It blocks until ctx is canceled, stdin reaches EOF, or a fatal error occurs.
Types ¶
type DeviceCodeResponse ¶
type DeviceCodeResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval"`
}
DeviceCodeResponse matches the API response.
type DeviceCodeStatusResponse ¶
type DeviceCodeStatusResponse struct {
Status string `json:"status"`
AccessToken string `json:"access_token,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Email string `json:"email,omitempty"`
OrganizationName string `json:"organization_name,omitempty"`
}
DeviceCodeStatusResponse matches the API response.
type StdioBridgeConfig ¶
type StdioBridgeConfig struct {
UpstreamURL string
TokenSource TokenSource
Token string // static fallback; ignored if TokenSource is set
OrgID string // if set, sends X-Organization-ID on every request
UserAgent string
Timeout time.Duration
MaxFrameBytes int // 0 → defaultMaxFrameBytes
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
StdioBridgeConfig configures the stdio MCP bridge.
Either TokenSource or Token may be set. TokenSource is preferred — it is called per-request so a token rotated outside the process (e.g. user re-running `taufinity auth login`) is picked up without restarting the bridge. Token is a static fallback for tests and embedded callers; it never expires for the bridge's purposes.
type TokenSource ¶
TokenSource produces a bearer token for the upstream /mcp endpoint. It is called once per outbound HTTP request (via WithHTTPHeaderFunc), with results cached in-memory until the token is within tokenRefreshLeeway of expiry. Implementations should be cheap (single file read) but safe to call concurrently. Returning an error suppresses the Authorization header for that request, surfacing a clear upstream 401 to the client rather than silently sending a stale bearer.
Source Files
¶
- as_user.go
- auth.go
- config.go
- dashboards.go
- deliverable.go
- mcp.go
- mcp_clients.go
- mcp_install.go
- mcp_stdio.go
- org.go
- playbook.go
- provision.go
- provision_client.go
- provision_client_groups.go
- provision_credentials.go
- provision_dashboards_apply.go
- provision_image_taxonomy.go
- provision_images.go
- provision_knowledge.go
- provision_kpi.go
- provision_nav.go
- provision_org.go
- provision_playbooks.go
- provision_portal.go
- provision_provider.go
- provision_pull.go
- provision_router_rules.go
- provision_sites.go
- provision_slug.go
- provision_stubs.go
- provision_test_suites.go
- provision_widget_slug_resolve.go
- provision_widgets.go
- root.go
- telemetry.go
- template.go
- tokens.go
- update.go
- version.go