Skip to content

Plugin System

Primary: npm (global install)

Terminal window
npm install -g @orgloop/cli
# or
pnpm add -g @orgloop/cli

This installs the orgloop binary. Requires Node.js >= 22.

Secondary: Homebrew (macOS/Linux)

Terminal window
brew install orgloop

The Homebrew formula bundles Node.js via Single Executable Application (SEA) — no external Node dependency.

Tertiary: Docker

Terminal window
docker run -v $(pwd):/config ghcr.io/c-h-/orgloop start

For server deployments where OrgLoop runs as a daemon.

Future: curl installer

Terminal window
curl -fsSL https://get.orgloop.dev | bash

Downloads the SEA binary for the detected platform. Yes, curl | bash is ironic given our security posture — but it’s what developers expect. The script is auditable and checksummed.

Bundled connectors (first-party):

The @orgloop/cli package includes a “batteries-included” set of common connectors:

  • @orgloop/connector-github
  • @orgloop/connector-webhook

Additional first-party connectors are installed separately:

Terminal window
npm install @orgloop/connector-linear
npm install @orgloop/connector-openclaw
npm install @orgloop/connector-claude-code

Or via the CLI:

Terminal window
orgloop add connector linear
# → runs: npm install @orgloop/connector-linear
# → adds to orgloop.yaml connectors list

Community connectors:

Terminal window
npm install orgloop-connector-jira
orgloop add connector jira --package orgloop-connector-jira

No approval needed. If it implements the interface, it works. See Zero Bottleneck to Adoption.

Runtime plugin loading (not compile-time).

When orgloop start starts:

  1. Read orgloop.yaml -> get list of connector YAML files (file paths, not package names)
  2. Load each ConnectorGroup YAML -> collect source/actor definitions with their connector package refs
  3. The CLI’s resolveConnectors() function collects unique connector package names, await import()s each, and calls its default export (the registration function):
connectors/github/src/index.ts
import { ConnectorRegistration } from '@orgloop/sdk';
import { GitHubSource } from './source';
export default function register(): ConnectorRegistration {
return {
id: 'github',
source: GitHubSource,
setup: {
env_vars: ['GITHUB_TOKEN'],
},
};
}
  1. For each source/actor in config, resolveConnectors() instantiates new reg.source() or new reg.target(), building sources: Map<string, SourceConnector> and actors: Map<string, ActorConnector>
  2. These Maps are passed to runtime.loadModule(config, { sources, actors }). (The OrgLoop wrapper class still accepts new OrgLoop(config, { sources, actors }) for backward compatibility — it creates a Runtime internally and loads a single “default” module.)
  3. If a connector import fails, the CLI suggests pnpm add <package> to the user

Plugin resolution order:

  1. Workspace node_modules/ (local install)
  2. Global node_modules/ (global install)
  3. Built-in (bundled with CLI)

Connectors optionally export setup metadata that the CLI uses for onboarding guidance. This follows a progressive maturity model — connectors start minimal and add capabilities over time.

The setup.env_vars field provides per-variable guidance rendered by orgloop env, orgloop init, and error messages:

setup: {
env_vars: [
{
name: 'GITHUB_TOKEN',
description: 'Personal access token with repo scope',
help_url: 'https://github.com/settings/tokens/new?scopes=repo,read:org',
},
{
name: 'GITHUB_REPO',
description: 'Repository in org/repo format',
},
],
}

When a variable is unset, the CLI renders:

✗ GITHUB_TOKEN — Personal access token with repo scope
→ https://github.com/settings/tokens/new?scopes=repo,read:org

Connectors that depend on external services can export a ServiceDetector:

interface ServiceDetector {
detect(): Promise<{
running: boolean;
version?: string;
endpoint?: string;
details?: Record<string, unknown>;
}>;
}

Used by orgloop doctor to report service availability. External tools (see orgctl RFP) can also consume this interface.

Connectors can validate that a credential actually works, not just that the env var is set:

interface CredentialValidator {
validate(value: string): Promise<{
valid: boolean;
identity?: string; // e.g., "user: @alice"
scopes?: string[]; // e.g., ["repo", "read:org"]
error?: string;
}>;
}

Used by orgloop doctor and orgloop setup for deep environment validation.

Connectors may eventually export CredentialAcquirer for OAuth flows and API-based token generation. See Scope Boundaries for the maturity model.

interface ConnectorRegistration {
id: string;
source?: new () => SourceConnector;
target?: new () => ActorConnector;
configSchema?: Record<string, unknown>;
setup?: ConnectorSetup;
// Stage 2: discoverable
service_detector?: ServiceDetector;
credential_validators?: Record<string, CredentialValidator>;
// Stage 3: self-service (future)
// credential_acquirers?: Record<string, CredentialAcquirer>;
}
interface ConnectorSetup {
env_vars?: (string | EnvVarDefinition)[];
integrations?: ConnectorIntegration[];
}
interface EnvVarDefinition {
name: string;
description: string;
help_url?: string;
help_command?: string;
required?: boolean;
}
PlatformMVPv1.0
macOS (Apple Silicon)YesYes
macOS (Intel)YesYes
Linux (x64)YesYes
Linux (ARM64)YesYes
WindowsNoBest-effort

Windows is out of MVP scope because:

  • Shell script transforms assume POSIX (#!/bin/bash, pipes, etc.)
  • Our team and early users are macOS/Linux
  • WSL2 is a viable escape hatch for Windows users