Skip to content

This is a reference doc. It covers the OnboardingPlugin pipeline, request schema, idempotency guarantees, and trigger sources.


Overview ​

OnboardingPlugin (lib/plugins/onboarding.ts) runs the deterministic, idempotent side-effects of bringing a project online: registering its GitHub webhook, creating its Google Drive folder, and notifying downstream consumers.

Project registration itself lives in the GitHub-topic-driven project registry — the registry is compiled from every protoLabsAI repo tagged with the protoagent-plugin topic (plus an explicit base set) into a static projects.json served by the workstacean-projects nginx sidecar (see config-files and src/plugins/project-registry.ts). A repo is tagged with the protoagent-plugin topic before triggering onboarding here; this plugin does not create or persist a project record of its own. workstacean reads the canonical project list from the sidecar via the ProjectRegistry (exposed at GET /api/projects).


The pipeline ​

Steps run in sequence. Each step is individually idempotent — re-running the full pipeline for the same slug is safe.

#StepWhat it doesSkip condition
1validateChecks slug, title, and github are present; validates github is owner/repo format; rejects duplicate in-flight runs for the same slugMissing required fields or invalid format
2github_webhookRegisters a GitHub repo webhook for issues, issue_comment, pull_request, pull_request_review_comment events; lists existing webhooks first and skips if the target URL is already registeredNo GitHub auth (GITHUB_APP_ID or GITHUB_TOKEN), or WORKSTACEAN_PUBLIC_URL not set, or webhook already exists
3drive_folderCreates a Google Drive folder named after the project title, under the org root folder (drive.orgFolderId in workspace/google.yaml)Google credentials not set, google.yaml missing, or drive.orgFolderId empty
4bus_notifyPublishes message.inbound.onboard.complete with project metadata and per-step outcomes for downstream consumersNever skipped
5replySends a confirmation message (or error) to the inbound message's reply topicNo reply topic in the inbound message

Steps 2–3 are non-fatal: an error in one step is recorded in the step result and the pipeline continues. The plugin does not write any project file — it only performs the external side-effects and publishes the completion event.


OnboardRequest schema ​

Sent as the payload of a message.inbound.onboard bus message (or the JSON body of POST /api/onboard):

FieldTypeRequiredDefaultDescription
slugstring✅—Unique project identifier, e.g. "protolabsai-myproject"
titlestring✅—Human-readable project name
githubstring✅—Repository in "owner/repo" format
defaultBranchstring"main"Default git branch
teamstring"dev"Team assignment: "dev", "gtm", etc.
agentsstring[]["quinn"]Agent identifiers to associate
discordobject{}Discord channel IDs (general, updates, dev, alerts, releases)

These fields are echoed back on message.inbound.onboard.complete; the plugin does not persist them. Channel→agent bindings live in workspace/channels.yaml (ChannelRegistry), and project metadata lives in the GitHub-topic-driven project registry — neither is written by this plugin.


Idempotency guarantees ​

The pipeline is safe to re-run for the same project slug:

  1. Step 2 (github_webhook) lists existing webhooks before creating; skips if the target URL is already registered.
  2. Step 3 (drive_folder) is skipped entirely when Google credentials or the org folder ID are absent.
  3. In-flight guard — concurrent requests for the same slug are rejected with an error while the first run is in progress.

Inbound triggers ​

Bus topic (primary) ​

message.inbound.onboard

Any subscriber can publish to this topic to trigger onboarding. The payload must match the OnboardRequest schema above.

HTTP endpoint ​

POST /api/onboard
Content-Type: application/json

{
  "slug": "protolabsai-myproject",
  "title": "My Project",
  "github": "protoLabsAI/my-project"
}

The HTTP handler publishes to message.inbound.onboard and waits for the pipeline result on the reply topic.

Discord /onboard slash command ​

The Discord plugin routes slash commands to message.inbound.discord.slash.{interactionId} via the command config in workspace/discord.yaml. An /onboard command configured in discord.yaml can pass the project fields as options and publish to message.inbound.onboard.

GitHub org webhook: repository.created ​

When the GitHub org webhook is registered and a new repository is created under the org, lib/plugins/github.ts catches the repository + action: created event and publishes to message.inbound.onboard automatically. The payload uses the repository's full_name, name, owner.login, description, and visibility.


Outbound topics ​

TopicWhen publishedPayload highlights
message.inbound.onboard.completeAfter the pipeline runsslug, title, github, defaultBranch, team, agents, discord, driveFolderId, per-step status
{msg.reply.topic}After pipeline finishes (success or error)Full result with success, step, human-readable content

Environment variables ​

VariableRequired byDefaultPurpose
WORKSTACEAN_PUBLIC_URLgithub_webhook—Base URL for webhook registration (e.g. https://ws.example.com)
GITHUB_APP_IDgithub_webhook—GitHub App ID for auth (used by makeGitHubAuth)
GITHUB_APP_PRIVATE_KEYgithub_webhook—GitHub App private key
GITHUB_TOKENgithub_webhook—Alternative GitHub PAT for webhook registration
GITHUB_WEBHOOK_SECRETgithub_webhook—Optional HMAC secret for GitHub webhooks
GOOGLE_CLIENT_IDdrive_folder—Google OAuth client ID
GOOGLE_CLIENT_SECRETdrive_folder—Google OAuth client secret
GOOGLE_REFRESH_TOKENdrive_folder—Google OAuth refresh token

References ​

protoWorkstacean — a switchboard, not an agent.