diff --git a/.github/workflows/deploy-site.yml b/.github/workflows/deploy-site.yml new file mode 100644 index 0000000..02f1fb4 --- /dev/null +++ b/.github/workflows/deploy-site.yml @@ -0,0 +1,56 @@ +name: Deploy site + +# Publishes the auto-generated jc CLI showcase site to GitHub Pages on +# every merge to main. The site is regenerated from internal/schema in +# the workflow itself (defense in depth — the verify-site CI gate on PRs +# already keeps the committed docs/site/ in sync). This way Pages always +# reflects what's actually shipping. + +on: + push: + branches: [main] + paths: + - 'docs/site/**' + - 'cmd/sitegen/**' + - 'internal/schema/**' + - 'Makefile' + - '.github/workflows/deploy-site.yml' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +# Only one Pages deploy at a time. If a second merge lands while one is +# deploying, the second waits — we want the latest deploy to win, not the +# earliest. cancel-in-progress: false because actions/deploy-pages doesn't +# tolerate mid-flight cancellation cleanly. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + + - name: Regenerate site artifacts + run: make site + + - uses: actions/configure-pages@v5 + + - uses: actions/upload-pages-artifact@v3 + with: + path: docs/site + + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/verify-site.yml b/.github/workflows/verify-site.yml new file mode 100644 index 0000000..afd4fef --- /dev/null +++ b/.github/workflows/verify-site.yml @@ -0,0 +1,33 @@ +name: Verify site + +# Catches stale docs/site/ artifacts on incoming PRs. If a contributor +# touched internal/schema, cmd/sitegen, the Makefile site target, or +# docs/site/ directly without running `make site`, this job fails and +# tells them how to fix it. Complements the deploy-site workflow, which +# regenerates at deploy time but only after merge. + +on: + pull_request: + branches: [main] + paths: + - 'internal/schema/**' + - 'cmd/sitegen/**' + - 'docs/site/**' + - 'Makefile' + - '.github/workflows/verify-site.yml' + +permissions: + contents: read + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + + - name: Verify docs/site/ is up to date + run: make verify-site diff --git a/Makefile b/Makefile index 723067d..6a1fbcc 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ BIN := jc DIST := dist PLATFORMS := darwin/amd64 darwin/arm64 linux/amd64 linux/arm64 windows/amd64 -.PHONY: build test lint install clean vet integration-test integration-test-readonly clean-dist dist release +.PHONY: build test lint install clean vet integration-test integration-test-readonly clean-dist dist release site verify-site build: go build -ldflags "$(LDFLAGS)" -o $(BIN) ./cmd/jc @@ -64,3 +64,26 @@ integration-test: build integration-test-readonly: build @JC=./$(BIN) ./scripts/integration-test.sh --skip-mutable + +# Regenerate docs/site/ artifacts (commands.json, llms.txt, llms-full.txt) +# from the schema manifest. Run after touching internal/schema or any +# command that should appear in the public catalog. +site: + go run ./cmd/sitegen -out docs/site + +# CI gate: fail if docs/site/ is stale relative to the current schema. +# Regenerates into a temp dir and diffs the three generated artifacts +# against the committed copies. Catches "added a new command but forgot +# to run make site." +verify-site: + @tmp=$$(mktemp -d) && \ + go run ./cmd/sitegen -out $$tmp >/dev/null && \ + for f in commands.json llms.txt llms-full.txt; do \ + diff -u docs/site/$$f $$tmp/$$f || { \ + echo "verify-site: docs/site/$$f is stale — run 'make site' and commit"; \ + rm -rf $$tmp; \ + exit 1; \ + }; \ + done && \ + rm -rf $$tmp && \ + echo "verify-site: docs/site/ is up to date" diff --git a/README.md b/README.md index 484026b..c7cff16 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Single Go binary. Full API coverage (V1, V2, Directory Insights, Graph). Six output formats. Built-in MCP server for AI assistants. Interactive TUI browser with full CRUD. Recipe engine for multi-step workflows. Plan mode for safe mutation previews. Natural language interface via `jc ask`. +**Browse the full command catalog:** [thejumpcloud.github.io/jc-cli](https://thejumpcloud.github.io/jc-cli/) — searchable reference for every command and flag, plus [`llms.txt`](https://thejumpcloud.github.io/jc-cli/llms.txt) / [`llms-full.txt`](https://thejumpcloud.github.io/jc-cli/llms-full.txt) for AI agents. + --- ## Installation @@ -912,8 +914,14 @@ make lint # Run go vet make install # Install to $GOPATH/bin make integration-test # Full integration test (requires auth) make integration-test-readonly # Read-only probes only (no create/delete) +make site # Regenerate docs/site/ from the schema manifest +make verify-site # Fail if docs/site/ drifted from the schema ``` +### Showcase site + +The public command catalog at [thejumpcloud.github.io/jc-cli](https://thejumpcloud.github.io/jc-cli/) is generated from `internal/schema/schema.go` (the same source the `jc schema` command uses). After adding or renaming a command, run `make site` and commit the regenerated files under `docs/site/`. The `verify-site` CI gate fails the PR if you forget. + ### Shell Completion ```bash diff --git a/cmd/sitegen/main.go b/cmd/sitegen/main.go new file mode 100644 index 0000000..97b1d66 --- /dev/null +++ b/cmd/sitegen/main.go @@ -0,0 +1,299 @@ +// Command sitegen renders the jc CLI command manifest into the static +// showcase site artifacts under docs/site/: +// +// - commands.json — the manifest, augmented with sidebar categories +// - llms.txt — short agent-facing index (https://llmstxt.org/) +// - llms-full.txt — full agent-facing reference +// +// The single source of truth is schema.BuildCommandManifest() — this tool +// is just a renderer. To regenerate, run `make site`. The CI gate +// `make verify-site` diffs the committed artifacts against a fresh +// regeneration and fails if they drifted. +package main + +import ( + "encoding/json" + "flag" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/klaassen-consulting/jc/internal/schema" +) + +// category groups command paths under a sidebar heading on the site. +// Order matters — it controls sidebar order. A command path that doesn't +// match any category falls under "Other" at the bottom. +type category struct { + Name string + Commands []string +} + +var categories = []category{ + { + Name: "Identity & Access", + Commands: []string{ + "jc users", "jc groups", "jc admins", + "jc auth-policies", "jc iplists", "jc identity-providers", + }, + }, + { + Name: "Devices & MDM", + Commands: []string{"jc devices", "jc apple-mdm"}, + }, + { + Name: "Apps & SSO", + Commands: []string{"jc apps", "jc app-templates", "jc saas-management"}, + }, + { + Name: "Policies & Commands", + Commands: []string{ + "jc policies", "jc policy-templates", "jc policy-groups", "jc commands", + }, + }, + { + Name: "Insights", + Commands: []string{"jc insights", "jc system-insights"}, + }, + { + Name: "Integrations", + Commands: []string{ + "jc ad", "jc gsuite", "jc office365", "jc duo", + "jc ldap", "jc radius", "jc software", "jc assets", + }, + }, + { + Name: "Org & Lifecycle", + Commands: []string{ + "jc org", "jc user-states", "jc access-requests", + "jc custom-emails", "jc bulk", "jc graph", + }, + }, + { + Name: "AI & Automation", + Commands: []string{ + "jc recipe", "jc mcp", "jc ask", "jc explain", "jc schema", + }, + }, + { + Name: "Setup", + Commands: []string{"jc auth", "jc config"}, + }, +} + +type enrichedCommand struct { + Path string `json:"path"` + Description string `json:"description"` + Long string `json:"long,omitempty"` + Category string `json:"category"` + Subcommands []string `json:"subcommands,omitempty"` + Flags []schema.FlagEntry `json:"flags,omitempty"` +} + +type output struct { + Name string `json:"name"` + Description string `json:"description"` + Categories []string `json:"categories"` + Commands []enrichedCommand `json:"commands"` + GlobalFlags []schema.FlagEntry `json:"global_flags"` + Resources []string `json:"resources"` +} + +func main() { + outDir := flag.String("out", "docs/site", "output directory") + flag.Parse() + + if err := run(*outDir); err != nil { + fmt.Fprintln(os.Stderr, "sitegen:", err) + os.Exit(1) + } +} + +func run(outDir string) error { + manifest := schema.BuildCommandManifest() + o := enrich(manifest) + + if err := os.MkdirAll(outDir, 0o755); err != nil { + return err + } + + if err := writeJSON(filepath.Join(outDir, "commands.json"), o); err != nil { + return fmt.Errorf("commands.json: %w", err) + } + if err := writeFile(filepath.Join(outDir, "llms.txt"), renderLLMs(o)); err != nil { + return fmt.Errorf("llms.txt: %w", err) + } + if err := writeFile(filepath.Join(outDir, "llms-full.txt"), renderLLMsFull(o)); err != nil { + return fmt.Errorf("llms-full.txt: %w", err) + } + + fmt.Fprintf(os.Stderr, "sitegen: wrote %d commands under %d categories to %s\n", + len(o.Commands), len(o.Categories), outDir) + return nil +} + +// enrich joins the schema manifest with the hardcoded category map. +// The version field is deliberately dropped: it tracks git-describe and +// would churn commands.json on every commit, defeating `make verify-site`. +func enrich(m schema.CommandManifest) output { + catByPath := make(map[string]string, len(categories)*4) + var catNames []string + for _, c := range categories { + catNames = append(catNames, c.Name) + for _, p := range c.Commands { + catByPath[p] = c.Name + } + } + const fallback = "Other" + hasFallback := false + + enriched := make([]enrichedCommand, 0, len(m.Commands)) + for _, c := range m.Commands { + cat, ok := catByPath[c.Path] + if !ok { + cat = fallback + hasFallback = true + } + enriched = append(enriched, enrichedCommand{ + Path: c.Path, + Description: c.Description, + Long: c.Long, + Category: cat, + Subcommands: c.Subcommands, + Flags: c.Flags, + }) + } + if hasFallback { + catNames = append(catNames, fallback) + } + + return output{ + Name: m.Name, + Description: m.Description, + Categories: catNames, + Commands: enriched, + GlobalFlags: m.GlobalFlags, + Resources: m.Resources, + } +} + +func writeJSON(path string, v any) error { + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + return err + } + b = append(b, '\n') + return os.WriteFile(path, b, 0o644) +} + +func writeFile(path, content string) error { + return os.WriteFile(path, []byte(content), 0o644) +} + +// renderLLMs emits the short llms.txt index per https://llmstxt.org/. +func renderLLMs(o output) string { + var b strings.Builder + fmt.Fprintf(&b, "# %s\n\n", o.Name) + fmt.Fprintf(&b, "> %s\n\n", o.Description) + fmt.Fprintln(&b, "The jc CLI is a Go-based command-line tool for JumpCloud — managing users, devices, groups, policies, applications, commands, insights, and more. It exposes every JumpCloud resource through a consistent verb-noun grammar with structured JSON output, an MCP server for AI agents, and a recipe system for declarative automation.") + fmt.Fprintln(&b) + fmt.Fprintln(&b, "## Command catalog") + fmt.Fprintln(&b) + + byCategory := groupByCategory(o) + for _, cat := range o.Categories { + cmds := byCategory[cat] + if len(cmds) == 0 { + continue + } + fmt.Fprintf(&b, "### %s\n\n", cat) + for _, c := range cmds { + fmt.Fprintf(&b, "- `%s` — %s\n", c.Path, c.Description) + } + fmt.Fprintln(&b) + } + + fmt.Fprintln(&b, "## See also") + fmt.Fprintln(&b) + fmt.Fprintln(&b, "- [Full reference](llms-full.txt)") + fmt.Fprintln(&b, "- [Machine-readable manifest](commands.json)") + fmt.Fprintln(&b, "- [Source repository](https://github.com/TheJumpCloud/jc-cli)") + return b.String() +} + +// renderLLMsFull emits the long-form reference: every command, every flag, +// global flags, and the full resource list. +func renderLLMsFull(o output) string { + var b strings.Builder + fmt.Fprintf(&b, "# %s — full reference\n\n", o.Name) + fmt.Fprintf(&b, "> %s\n\n", o.Description) + + fmt.Fprintln(&b, "## Global flags") + fmt.Fprintln(&b) + fmt.Fprintln(&b, "These flags work on every `jc` subcommand:") + fmt.Fprintln(&b) + for _, f := range o.GlobalFlags { + renderFlag(&b, f) + } + fmt.Fprintln(&b) + + fmt.Fprintln(&b, "## Commands") + fmt.Fprintln(&b) + byCategory := groupByCategory(o) + for _, cat := range o.Categories { + cmds := byCategory[cat] + if len(cmds) == 0 { + continue + } + fmt.Fprintf(&b, "### %s\n\n", cat) + for _, c := range cmds { + fmt.Fprintf(&b, "#### `%s`\n\n", c.Path) + fmt.Fprintf(&b, "%s\n\n", c.Description) + if c.Long != "" { + fmt.Fprintf(&b, "%s\n\n", c.Long) + } + if len(c.Subcommands) > 0 { + fmt.Fprintln(&b, "**Subcommands:**", "`"+strings.Join(c.Subcommands, "`, `")+"`") + fmt.Fprintln(&b) + } + if len(c.Flags) > 0 { + fmt.Fprintln(&b, "**Flags:**") + fmt.Fprintln(&b) + for _, f := range c.Flags { + renderFlag(&b, f) + } + fmt.Fprintln(&b) + } + } + } + + fmt.Fprintln(&b, "## Resource types") + fmt.Fprintln(&b) + fmt.Fprintln(&b, "Every resource has a JSON schema available via `jc schema `:") + fmt.Fprintln(&b) + for _, r := range o.Resources { + fmt.Fprintf(&b, "- `%s`\n", r) + } + return b.String() +} + +func renderFlag(b *strings.Builder, f schema.FlagEntry) { + short := "" + if f.Shorthand != "" { + short = fmt.Sprintf(", `-%s`", f.Shorthand) + } + def := "" + if f.Default != "" { + def = fmt.Sprintf(" (default `%s`)", f.Default) + } + fmt.Fprintf(b, "- `--%s`%s `<%s>`%s — %s\n", f.Name, short, f.Type, def, f.Description) +} + +func groupByCategory(o output) map[string][]enrichedCommand { + m := make(map[string][]enrichedCommand, len(o.Categories)) + for _, c := range o.Commands { + m[c.Category] = append(m[c.Category], c) + } + return m +} diff --git a/docs/site/commands.json b/docs/site/commands.json new file mode 100644 index 0000000..8716be5 --- /dev/null +++ b/docs/site/commands.json @@ -0,0 +1,1381 @@ +{ + "name": "jc", + "description": "JumpCloud CLI — manage users, devices, groups, policies, commands, insights, and more", + "categories": [ + "Identity \u0026 Access", + "Devices \u0026 MDM", + "Apps \u0026 SSO", + "Policies \u0026 Commands", + "Insights", + "Integrations", + "Org \u0026 Lifecycle", + "AI \u0026 Automation", + "Setup" + ], + "commands": [ + { + "path": "jc auth", + "description": "Authentication commands", + "long": "Manage JumpCloud credentials and switch between organizations. The CLI supports two credential types: a static API key (read from `JC_API_KEY`, the config, or the system keychain), or an OAuth service account (client ID + secret), with automatic token refresh. Credentials can be stored as plaintext, in macOS Keychain / GNOME libsecret / Windows Credential Manager via a `keychain://` reference, or supplied per-invocation with `--api-key`. Multiple named profiles let MSPs and admins flip between orgs without re-authenticating (`jc auth switch \u003cprofile\u003e`), and `jc auth status` reveals the active profile, credential type, fingerprint, and source.", + "category": "Setup", + "subcommands": [ + "login", + "logout", + "status", + "switch" + ] + }, + { + "path": "jc config", + "description": "Configuration management", + "long": "View and update jc CLI configuration — default output format, color/pager behavior, TUI refresh interval, plan-mode safety toggles, cache TTLs, and dozens of other preferences. Settings live in `~/.config/jc/config.yaml` and can be overridden per-command via `JC_*` environment variables or flags (env \u003e flag \u003e config \u003e built-in default). Use `jc config view` for the full effective configuration including override sources, or `jc config set \u003ckey\u003e \u003cvalue\u003e` to persist a change.", + "category": "Setup", + "subcommands": [ + "view", + "set" + ] + }, + { + "path": "jc users", + "description": "Manage JumpCloud system users", + "category": "Identity \u0026 Access", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "search", + "lock", + "unlock", + "reset-mfa", + "reset-password", + "ssh-keys", + "ssh-key-add", + "ssh-key-delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list/search)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field, prefix - for descending (list/search)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "search", + "type": "string", + "description": "Full-text search term (list)" + } + ] + }, + { + "path": "jc devices", + "description": "Manage JumpCloud devices (systems)", + "category": "Devices \u0026 MDM", + "subcommands": [ + "list", + "get", + "update", + "delete", + "search", + "lock", + "restart", + "erase", + "fde-key" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field, prefix - for descending (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "confirm-erase", + "type": "bool", + "description": "Required safety flag for erase command" + } + ] + }, + { + "path": "jc groups", + "description": "Manage user and device groups", + "category": "Identity \u0026 Access", + "subcommands": [ + "user list", + "user get", + "user create", + "user update", + "user delete", + "device list", + "device get", + "device create", + "device update", + "device delete", + "add-member", + "remove-member" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + } + ] + }, + { + "path": "jc commands", + "description": "Manage JumpCloud commands", + "category": "Policies \u0026 Commands", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "run", + "results", + "trigger" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "type", + "type": "string", + "description": "Command type filter: linux, mac, windows (list)" + }, + { + "name": "data", + "type": "string", + "description": "JSON payload for trigger" + } + ] + }, + { + "path": "jc policies", + "description": "Manage JumpCloud policies", + "category": "Policies \u0026 Commands", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "results" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + } + ] + }, + { + "path": "jc apps", + "description": "Manage SSO applications", + "category": "Apps \u0026 SSO", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "sso-type", + "type": "string", + "description": "SSO type (create, required)" + }, + { + "name": "config", + "type": "string", + "description": "SSO-specific config as JSON (create/update)" + } + ] + }, + { + "path": "jc admins", + "description": "Manage JumpCloud administrators", + "category": "Identity \u0026 Access", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "email", + "type": "string", + "description": "Admin email address (create, required)" + }, + { + "name": "role", + "type": "string", + "description": "Admin role name (create/update)" + }, + { + "name": "enable-mfa", + "type": "bool", + "description": "Enable multi-factor authentication (create/update)" + }, + { + "name": "disable-mfa", + "type": "bool", + "description": "Disable multi-factor authentication (update)" + } + ] + }, + { + "path": "jc insights", + "description": "Query Directory Insights audit events", + "category": "Insights", + "subcommands": [ + "query", + "count", + "distinct", + "save", + "run", + "saved" + ], + "flags": [ + { + "name": "service", + "type": "string", + "description": "Event service: sso, radius, ldap, user_portal, admin, mdm, directory, software, systems, password_manager, all" + }, + { + "name": "last", + "type": "string", + "description": "Time range: 24h, 7d, 30d, 1m" + }, + { + "name": "start", + "type": "string", + "description": "Start time (RFC 3339 or YYYY-MM-DD)" + }, + { + "name": "end", + "type": "string", + "description": "End time (RFC 3339 or YYYY-MM-DD)" + }, + { + "name": "event-type", + "type": "string", + "description": "Filter by event type" + }, + { + "name": "limit", + "type": "int", + "description": "Maximum events to return" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field" + } + ] + }, + { + "path": "jc auth-policies", + "description": "Manage authentication policies for conditional access", + "category": "Identity \u0026 Access", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "enable", + "disable", + "simulate", + "blast-radius" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "conditions", + "type": "string", + "description": "Conditions tree as raw JSON (create/update)" + }, + { + "name": "user", + "type": "string", + "description": "User name or ID (simulate)" + }, + { + "name": "ip", + "type": "string", + "description": "Source IP address (simulate)" + }, + { + "name": "device", + "type": "string", + "description": "Device name or ID (simulate)" + }, + { + "name": "location", + "type": "string", + "description": "Country code (simulate)" + } + ] + }, + { + "path": "jc iplists", + "description": "Manage IP lists for authentication policies", + "category": "Identity \u0026 Access", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "ips", + "type": "string", + "description": "Comma-separated IP entries (create/update)" + } + ] + }, + { + "path": "jc identity-providers", + "description": "Manage JumpCloud identity providers for SSO/OIDC federation", + "category": "Identity \u0026 Access", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum results (list)" + }, + { + "name": "name", + "type": "string", + "description": "Provider name (create/update)" + }, + { + "name": "type", + "type": "string", + "description": "Provider type: OIDC, GOOGLE, OKTA, AZURE (create)" + }, + { + "name": "client-id", + "type": "string", + "description": "OIDC client ID (create/update)" + }, + { + "name": "client-secret", + "type": "string", + "description": "OIDC client secret (create/update)" + }, + { + "name": "url", + "type": "string", + "description": "OIDC issuer URL (create/update)" + } + ] + }, + { + "path": "jc saas-management", + "description": "Manage JumpCloud SaaS Management applications", + "category": "Apps \u0026 SSO", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "accounts", + "account-get", + "account-delete", + "usage", + "licenses", + "catalog-get" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "catalog-app-id", + "type": "string", + "description": "Catalog application ID (create)" + }, + { + "name": "status", + "type": "string", + "description": "App status: APPROVED, UNAPPROVED, IGNORED (create/update)" + }, + { + "name": "access-restriction", + "type": "string", + "description": "Access restriction: DEFAULT_ACTION, NO_ACTION, BLOCK, DISMISSIBLE_WARNING (create/update)" + }, + { + "name": "account-id", + "type": "string", + "description": "Account ID (account-get/account-delete)" + }, + { + "name": "day-count", + "type": "int", + "description": "Number of days of usage data (usage, default 30)" + } + ] + }, + { + "path": "jc software", + "description": "Manage JumpCloud software apps", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "statuses", + "associations", + "reclaim-license" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "name", + "type": "string", + "description": "App display name (create/update)" + }, + { + "name": "settings", + "type": "string", + "description": "Package settings as raw JSON (create/update)" + } + ] + }, + { + "path": "jc assets", + "description": "Manage JumpCloud assets (devices, accessories, locations)", + "category": "Integrations", + "subcommands": [ + "devices", + "accessories", + "locations" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "field", + "type": "string[]", + "description": "Set field value as 'Label=Value' (create/update)" + } + ] + }, + { + "path": "jc ldap", + "description": "Manage JumpCloud LDAP servers", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "samba-domains", + "samba-domain-get", + "samba-domain-create", + "samba-domain-update", + "samba-domain-delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "name", + "type": "string", + "description": "LDAP server name (create/update) or samba domain workgroup name" + }, + { + "name": "user-lockout-action", + "type": "string", + "description": "Action on user lockout (create/update)" + }, + { + "name": "user-password-expiration-action", + "type": "string", + "description": "Action on password expiration (create/update)" + }, + { + "name": "domain-id", + "type": "string", + "description": "Samba domain ID (samba-domain-get/update/delete)" + }, + { + "name": "sid", + "type": "string", + "description": "Samba domain security identifier (samba-domain-create/update)" + } + ] + }, + { + "path": "jc access-requests", + "description": "Manage JumpCloud temporary elevated device privilege requests", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "list", + "get", + "create", + "update", + "revoke" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "user", + "type": "string", + "description": "User name or ID (create)" + }, + { + "name": "device", + "type": "string", + "description": "Device name or ID (create)" + }, + { + "name": "expiry", + "type": "string", + "description": "Expiry time RFC 3339 (create/update)" + }, + { + "name": "sudo", + "type": "bool", + "description": "Enable sudo access (create)" + }, + { + "name": "sudo-nopasswd", + "type": "bool", + "description": "Enable passwordless sudo (create)" + }, + { + "name": "remarks", + "type": "string", + "description": "Optional remarks (create/update)" + } + ] + }, + { + "path": "jc ad", + "description": "Manage JumpCloud Active Directory integrations", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "domain", + "type": "string", + "description": "AD domain name (create, required)" + }, + { + "name": "use-case", + "type": "string", + "description": "Integration use case (create/update)" + }, + { + "name": "groups-enabled", + "type": "bool", + "description": "Enable group sync (update)" + } + ] + }, + { + "path": "jc org", + "description": "View and update JumpCloud organization information", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "list", + "get", + "settings", + "update" + ], + "flags": [ + { + "name": "name", + "type": "string", + "description": "Organization display name (update)" + }, + { + "name": "settings-json", + "type": "string", + "description": "Raw JSON for complex settings fields (update)" + } + ] + }, + { + "path": "jc system-insights", + "description": "Query osquery system insight tables", + "category": "Insights", + "subcommands": [ + "list", + "tables" + ], + "flags": [ + { + "name": "system-id", + "type": "string", + "description": "Filter by device hostname or ID" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions" + }, + { + "name": "limit", + "type": "int", + "description": "Maximum number of results" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field" + } + ] + }, + { + "path": "jc radius", + "description": "Manage RADIUS servers", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "name", + "type": "string", + "description": "RADIUS server name (create/update)" + }, + { + "name": "shared-secret", + "type": "string", + "description": "RADIUS shared secret (create, required)" + }, + { + "name": "auth-port", + "type": "int", + "default": "1812", + "description": "Authentication port (create/update)" + }, + { + "name": "accounting-port", + "type": "int", + "default": "1813", + "description": "Accounting port (create/update)" + } + ] + }, + { + "path": "jc policy-templates", + "description": "View policy templates", + "category": "Policies \u0026 Commands", + "subcommands": [ + "list", + "get" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + } + ] + }, + { + "path": "jc apple-mdm", + "description": "Manage Apple MDM configurations", + "category": "Devices \u0026 MDM", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete", + "enrollment-profiles", + "devices" + ], + "flags": [ + { + "name": "name", + "type": "string", + "description": "MDM configuration name (create/update)" + }, + { + "name": "org-name", + "type": "string", + "description": "Organization name (create/update)" + } + ] + }, + { + "path": "jc policy-groups", + "description": "Manage policy groups", + "category": "Policies \u0026 Commands", + "subcommands": [ + "list", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + }, + { + "name": "name", + "type": "string", + "description": "Policy group name (create/update)" + }, + { + "name": "description", + "type": "string", + "description": "Policy group description (create/update)" + } + ] + }, + { + "path": "jc user-states", + "description": "Manage scheduled user state transitions", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "list", + "create", + "get", + "delete" + ], + "flags": [ + { + "name": "user", + "type": "string", + "description": "User name or ID (create, required)" + }, + { + "name": "state", + "type": "string", + "description": "Target state: suspended or activated (create, required)" + }, + { + "name": "start-date", + "type": "string", + "description": "Date for state change (create, required)" + }, + { + "name": "end-date", + "type": "string", + "description": "Optional end date to revert (create)" + } + ] + }, + { + "path": "jc gsuite", + "description": "Manage JumpCloud Google Workspace (G Suite) integrations", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "translation-rules", + "import-users" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + } + ] + }, + { + "path": "jc office365", + "description": "Manage JumpCloud Office 365 integrations", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "translation-rules", + "import-users" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + }, + { + "name": "filter", + "type": "string[]", + "description": "Filter expressions (list)" + } + ] + }, + { + "path": "jc duo", + "description": "Manage JumpCloud Duo accounts and applications", + "category": "Integrations", + "subcommands": [ + "list", + "get", + "create", + "delete", + "apps", + "app-get", + "app-create", + "app-delete" + ], + "flags": [ + { + "name": "name", + "type": "string", + "description": "Duo account name (create)" + }, + { + "name": "app-id", + "type": "string", + "description": "Duo application ID (app-get, app-delete)" + }, + { + "name": "api-host", + "type": "string", + "description": "Duo API host (app-create)" + } + ] + }, + { + "path": "jc custom-emails", + "description": "Manage custom email templates", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "templates", + "get", + "create", + "update", + "delete" + ], + "flags": [ + { + "name": "type", + "type": "string", + "description": "Custom email type (create, required)" + }, + { + "name": "subject", + "type": "string", + "description": "Email subject line (create/update)" + }, + { + "name": "title", + "type": "string", + "description": "Email title (create/update)" + }, + { + "name": "body", + "type": "string", + "description": "Email body text (create/update)" + }, + { + "name": "header", + "type": "string", + "description": "Email header text (create/update)" + }, + { + "name": "button", + "type": "string", + "description": "Email button text (create/update)" + } + ] + }, + { + "path": "jc app-templates", + "description": "View application templates", + "category": "Apps \u0026 SSO", + "subcommands": [ + "list", + "get" + ], + "flags": [ + { + "name": "limit", + "type": "int", + "description": "Maximum number of results (list)" + }, + { + "name": "sort", + "type": "string", + "description": "Sort field (list)" + } + ] + }, + { + "path": "jc graph", + "description": "Manage JumpCloud resource associations", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "traverse", + "bind", + "unbind" + ], + "flags": [ + { + "name": "from", + "type": "string", + "description": "Source: type:identifier (e.g. user:jdoe)" + }, + { + "name": "to", + "type": "string", + "description": "Target type: user, system, user_group, system_group, application, policy, command" + } + ] + }, + { + "path": "jc bulk", + "description": "Bulk operations from CSV files", + "category": "Org \u0026 Lifecycle", + "subcommands": [ + "users" + ], + "flags": [ + { + "name": "file", + "type": "string", + "description": "Path to CSV file" + } + ] + }, + { + "path": "jc recipe", + "description": "Manage and run automation recipes", + "long": "Recipes turn JumpCloud workflows into declarative, version-controlled YAML files instead of one-off shell scripts. Each step is a `jc` invocation with template variables (`{{ .param.user }}`, `{{ .step.created_user.id }}`), conditional execution based on prior step outputs, and structured output capture that downstream steps can reference — so a single recipe can create a user, add them to groups, assign devices, send a welcome email, and bail out cleanly if any step fails or a precondition isn't met. The `--plan` flag walks every step without mutation, surfacing exactly what would change before you commit; `--param k=v` makes the same recipe reusable across users, orgs, or MSP customers. Built-ins ship for the workflows admins write over and over (onboarding, offboarding, MFA-reset campaigns, quarterly compliance audits); custom recipes live in `~/.config/jc/recipes/` and can be authored in `$EDITOR` via the TUI (`jc tui` → recipes → `n`). Recipes are also a first-class MCP primitive — agents can invoke `recipe.run` as a single tool call instead of orchestrating five separate ones, dramatically reducing the surface area for LLM missteps on multi-step changes.", + "category": "AI \u0026 Automation", + "subcommands": [ + "list", + "show", + "run", + "validate", + "create", + "import", + "export" + ], + "flags": [ + { + "name": "param", + "type": "string[]", + "description": "Recipe parameters as key=value (run)" + }, + { + "name": "file", + "type": "string", + "description": "Output file path (export)" + } + ] + }, + { + "path": "jc mcp", + "description": "MCP server for AI agent integration", + "long": "Run the jc CLI as a Model Context Protocol (MCP) server, exposing JumpCloud resources as typed tools to MCP-aware clients (Claude Code, Claude Desktop, Cursor, and any other host that speaks MCP). Includes per-minute rate limiting, an optional `--read-only` mode that disables every mutation tool, and a step-up authentication flow (TTY prompt, Touch ID, or webhook) for high-impact operations. Transport is stdio by default — point your MCP client at `jc mcp serve` and the CLI's full surface area becomes available to the agent.", + "category": "AI \u0026 Automation", + "subcommands": [ + "serve" + ], + "flags": [ + { + "name": "rate-limit", + "type": "int", + "default": "60", + "description": "Maximum tool calls per minute" + }, + { + "name": "read-only", + "type": "bool", + "description": "Disable all mutation tools" + } + ] + }, + { + "path": "jc schema", + "description": "Machine-readable schema and command manifest", + "long": "Return machine-readable JSON for every JumpCloud resource type and the full CLI command tree. Designed for LLMs, IDE plugins, code generators, and the public showcase site itself — `jc schema resources` lists every resource with its API version and supported verbs, `jc schema \u003cresource\u003e` returns the typed field list, and `jc schema commands` returns the full command manifest (paths, subcommands, flags, descriptions). The schema is the single source of truth — this site, the MCP server, and `jc ask` all read from it.", + "category": "AI \u0026 Automation", + "subcommands": [ + "resources", + "commands" + ] + }, + { + "path": "jc ask", + "description": "Translate natural language queries into jc CLI commands", + "long": "Translate plain-English questions into runnable `jc` commands using the bundled schema manifest plus an LLM prompt template. Useful for one-off queries like *\"show me admins who haven't logged in for 90 days\"* without remembering exact `jc insights query` flag syntax, or for *\"suspend everyone in the contractors group\"* without hand-piping `jc groups user list` into a `for` loop. The translated command is always printed for review before execution, and pairs naturally with `--plan` to preview any mutation before committing.", + "category": "AI \u0026 Automation" + }, + { + "path": "jc explain", + "description": "Explain what a command would do without executing", + "long": "Describe what a `jc` invocation would do — in plain English — without running it. Useful for sanity-checking LLM-generated commands before execution, understanding an unfamiliar invocation copied from a runbook, or onboarding new admins. The explanation covers the action type, target resource, affected scope (single object vs. batch), and a reversibility warning for destructive operations (`delete`, `lock`, `erase`).", + "category": "AI \u0026 Automation" + } + ], + "global_flags": [ + { + "name": "output", + "shorthand": "o", + "type": "string", + "default": "json", + "description": "Output format: json, table, csv, human, yaml, ndjson" + }, + { + "name": "table", + "shorthand": "t", + "type": "bool", + "description": "Shorthand for --output table" + }, + { + "name": "verbose", + "shorthand": "v", + "type": "bool", + "description": "Enable verbose HTTP logging" + }, + { + "name": "debug", + "type": "bool", + "description": "Enable debug logging" + }, + { + "name": "quiet", + "shorthand": "q", + "type": "bool", + "description": "Suppress output, exit code only" + }, + { + "name": "force", + "shorthand": "f", + "type": "bool", + "description": "Skip confirmation prompts" + }, + { + "name": "plan", + "type": "bool", + "description": "Preview changes without executing" + }, + { + "name": "ids", + "type": "bool", + "description": "Output one ID per line (for piping)" + }, + { + "name": "fields", + "type": "string", + "description": "Comma-separated list of fields to include" + }, + { + "name": "exclude", + "type": "string", + "description": "Comma-separated list of fields to exclude" + }, + { + "name": "all", + "type": "bool", + "description": "Include all available fields in output" + }, + { + "name": "org", + "type": "string", + "description": "Override active profile for this command" + }, + { + "name": "api-key", + "type": "string", + "description": "Override API key for this command" + }, + { + "name": "no-cache", + "type": "bool", + "description": "Bypass name-to-ID cache" + }, + { + "name": "no-color", + "type": "bool", + "description": "Disable color output" + }, + { + "name": "non-interactive", + "type": "bool", + "description": "Disable all interactive prompts" + } + ], + "resources": [ + "access-requests", + "ad", + "admins", + "app-templates", + "apple-mdm", + "apps", + "assets", + "auth-policies", + "commands", + "custom-emails", + "devices", + "duo", + "groups", + "gsuite", + "identity-providers", + "insights", + "iplists", + "ldap", + "office365", + "org", + "policies", + "policy-groups", + "policy-templates", + "radius", + "saas-management", + "software", + "system-insights", + "user-states", + "users" + ] +} diff --git a/docs/site/index.html b/docs/site/index.html new file mode 100644 index 0000000..79c971f --- /dev/null +++ b/docs/site/index.html @@ -0,0 +1,490 @@ + + + + + +jc — JumpCloud CLI + + + + + + + +
+ +
+ +
+

jc CLI

+

+ +
+
+ + +
+
+ + + + diff --git a/docs/site/llms-full.txt b/docs/site/llms-full.txt new file mode 100644 index 0000000..8722039 --- /dev/null +++ b/docs/site/llms-full.txt @@ -0,0 +1,557 @@ +# jc — full reference + +> JumpCloud CLI — manage users, devices, groups, policies, commands, insights, and more + +## Global flags + +These flags work on every `jc` subcommand: + +- `--output`, `-o` `` (default `json`) — Output format: json, table, csv, human, yaml, ndjson +- `--table`, `-t` `` — Shorthand for --output table +- `--verbose`, `-v` `` — Enable verbose HTTP logging +- `--debug` `` — Enable debug logging +- `--quiet`, `-q` `` — Suppress output, exit code only +- `--force`, `-f` `` — Skip confirmation prompts +- `--plan` `` — Preview changes without executing +- `--ids` `` — Output one ID per line (for piping) +- `--fields` `` — Comma-separated list of fields to include +- `--exclude` `` — Comma-separated list of fields to exclude +- `--all` `` — Include all available fields in output +- `--org` `` — Override active profile for this command +- `--api-key` `` — Override API key for this command +- `--no-cache` `` — Bypass name-to-ID cache +- `--no-color` `` — Disable color output +- `--non-interactive` `` — Disable all interactive prompts + +## Commands + +### Identity & Access + +#### `jc users` + +Manage JumpCloud system users + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `search`, `lock`, `unlock`, `reset-mfa`, `reset-password`, `ssh-keys`, `ssh-key-add`, `ssh-key-delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list/search) +- `--sort` `` — Sort field, prefix - for descending (list/search) +- `--filter` `` — Filter expressions (list) +- `--search` `` — Full-text search term (list) + +#### `jc groups` + +Manage user and device groups + +**Subcommands:** `user list`, `user get`, `user create`, `user update`, `user delete`, `device list`, `device get`, `device create`, `device update`, `device delete`, `add-member`, `remove-member` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) + +#### `jc admins` + +Manage JumpCloud administrators + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--email` `` — Admin email address (create, required) +- `--role` `` — Admin role name (create/update) +- `--enable-mfa` `` — Enable multi-factor authentication (create/update) +- `--disable-mfa` `` — Disable multi-factor authentication (update) + +#### `jc auth-policies` + +Manage authentication policies for conditional access + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `enable`, `disable`, `simulate`, `blast-radius` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--conditions` `` — Conditions tree as raw JSON (create/update) +- `--user` `` — User name or ID (simulate) +- `--ip` `` — Source IP address (simulate) +- `--device` `` — Device name or ID (simulate) +- `--location` `` — Country code (simulate) + +#### `jc iplists` + +Manage IP lists for authentication policies + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--ips` `` — Comma-separated IP entries (create/update) + +#### `jc identity-providers` + +Manage JumpCloud identity providers for SSO/OIDC federation + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum results (list) +- `--name` `` — Provider name (create/update) +- `--type` `` — Provider type: OIDC, GOOGLE, OKTA, AZURE (create) +- `--client-id` `` — OIDC client ID (create/update) +- `--client-secret` `` — OIDC client secret (create/update) +- `--url` `` — OIDC issuer URL (create/update) + +### Devices & MDM + +#### `jc devices` + +Manage JumpCloud devices (systems) + +**Subcommands:** `list`, `get`, `update`, `delete`, `search`, `lock`, `restart`, `erase`, `fde-key` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field, prefix - for descending (list) +- `--filter` `` — Filter expressions (list) +- `--confirm-erase` `` — Required safety flag for erase command + +#### `jc apple-mdm` + +Manage Apple MDM configurations + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `enrollment-profiles`, `devices` + +**Flags:** + +- `--name` `` — MDM configuration name (create/update) +- `--org-name` `` — Organization name (create/update) + +### Apps & SSO + +#### `jc apps` + +Manage SSO applications + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--sso-type` `` — SSO type (create, required) +- `--config` `` — SSO-specific config as JSON (create/update) + +#### `jc saas-management` + +Manage JumpCloud SaaS Management applications + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `accounts`, `account-get`, `account-delete`, `usage`, `licenses`, `catalog-get` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--filter` `` — Filter expressions (list) +- `--catalog-app-id` `` — Catalog application ID (create) +- `--status` `` — App status: APPROVED, UNAPPROVED, IGNORED (create/update) +- `--access-restriction` `` — Access restriction: DEFAULT_ACTION, NO_ACTION, BLOCK, DISMISSIBLE_WARNING (create/update) +- `--account-id` `` — Account ID (account-get/account-delete) +- `--day-count` `` — Number of days of usage data (usage, default 30) + +#### `jc app-templates` + +View application templates + +**Subcommands:** `list`, `get` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) + +### Policies & Commands + +#### `jc commands` + +Manage JumpCloud commands + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `run`, `results`, `trigger` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--type` `` — Command type filter: linux, mac, windows (list) +- `--data` `` — JSON payload for trigger + +#### `jc policies` + +Manage JumpCloud policies + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `results` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) + +#### `jc policy-templates` + +View policy templates + +**Subcommands:** `list`, `get` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--filter` `` — Filter expressions (list) + +#### `jc policy-groups` + +Manage policy groups + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--name` `` — Policy group name (create/update) +- `--description` `` — Policy group description (create/update) + +### Insights + +#### `jc insights` + +Query Directory Insights audit events + +**Subcommands:** `query`, `count`, `distinct`, `save`, `run`, `saved` + +**Flags:** + +- `--service` `` — Event service: sso, radius, ldap, user_portal, admin, mdm, directory, software, systems, password_manager, all +- `--last` `` — Time range: 24h, 7d, 30d, 1m +- `--start` `` — Start time (RFC 3339 or YYYY-MM-DD) +- `--end` `` — End time (RFC 3339 or YYYY-MM-DD) +- `--event-type` `` — Filter by event type +- `--limit` `` — Maximum events to return +- `--sort` `` — Sort field + +#### `jc system-insights` + +Query osquery system insight tables + +**Subcommands:** `list`, `tables` + +**Flags:** + +- `--system-id` `` — Filter by device hostname or ID +- `--filter` `` — Filter expressions +- `--limit` `` — Maximum number of results +- `--sort` `` — Sort field + +### Integrations + +#### `jc software` + +Manage JumpCloud software apps + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `statuses`, `associations`, `reclaim-license` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--name` `` — App display name (create/update) +- `--settings` `` — Package settings as raw JSON (create/update) + +#### `jc assets` + +Manage JumpCloud assets (devices, accessories, locations) + +**Subcommands:** `devices`, `accessories`, `locations` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--field` `` — Set field value as 'Label=Value' (create/update) + +#### `jc ldap` + +Manage JumpCloud LDAP servers + +**Subcommands:** `list`, `get`, `create`, `update`, `delete`, `samba-domains`, `samba-domain-get`, `samba-domain-create`, `samba-domain-update`, `samba-domain-delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--name` `` — LDAP server name (create/update) or samba domain workgroup name +- `--user-lockout-action` `` — Action on user lockout (create/update) +- `--user-password-expiration-action` `` — Action on password expiration (create/update) +- `--domain-id` `` — Samba domain ID (samba-domain-get/update/delete) +- `--sid` `` — Samba domain security identifier (samba-domain-create/update) + +#### `jc ad` + +Manage JumpCloud Active Directory integrations + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--domain` `` — AD domain name (create, required) +- `--use-case` `` — Integration use case (create/update) +- `--groups-enabled` `` — Enable group sync (update) + +#### `jc radius` + +Manage RADIUS servers + +**Subcommands:** `list`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) +- `--name` `` — RADIUS server name (create/update) +- `--shared-secret` `` — RADIUS shared secret (create, required) +- `--auth-port` `` (default `1812`) — Authentication port (create/update) +- `--accounting-port` `` (default `1813`) — Accounting port (create/update) + +#### `jc gsuite` + +Manage JumpCloud Google Workspace (G Suite) integrations + +**Subcommands:** `list`, `get`, `translation-rules`, `import-users` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) + +#### `jc office365` + +Manage JumpCloud Office 365 integrations + +**Subcommands:** `list`, `get`, `translation-rules`, `import-users` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--sort` `` — Sort field (list) +- `--filter` `` — Filter expressions (list) + +#### `jc duo` + +Manage JumpCloud Duo accounts and applications + +**Subcommands:** `list`, `get`, `create`, `delete`, `apps`, `app-get`, `app-create`, `app-delete` + +**Flags:** + +- `--name` `` — Duo account name (create) +- `--app-id` `` — Duo application ID (app-get, app-delete) +- `--api-host` `` — Duo API host (app-create) + +### Org & Lifecycle + +#### `jc access-requests` + +Manage JumpCloud temporary elevated device privilege requests + +**Subcommands:** `list`, `get`, `create`, `update`, `revoke` + +**Flags:** + +- `--limit` `` — Maximum number of results (list) +- `--filter` `` — Filter expressions (list) +- `--user` `` — User name or ID (create) +- `--device` `` — Device name or ID (create) +- `--expiry` `` — Expiry time RFC 3339 (create/update) +- `--sudo` `` — Enable sudo access (create) +- `--sudo-nopasswd` `` — Enable passwordless sudo (create) +- `--remarks` `` — Optional remarks (create/update) + +#### `jc org` + +View and update JumpCloud organization information + +**Subcommands:** `list`, `get`, `settings`, `update` + +**Flags:** + +- `--name` `` — Organization display name (update) +- `--settings-json` `` — Raw JSON for complex settings fields (update) + +#### `jc user-states` + +Manage scheduled user state transitions + +**Subcommands:** `list`, `create`, `get`, `delete` + +**Flags:** + +- `--user` `` — User name or ID (create, required) +- `--state` `` — Target state: suspended or activated (create, required) +- `--start-date` `` — Date for state change (create, required) +- `--end-date` `` — Optional end date to revert (create) + +#### `jc custom-emails` + +Manage custom email templates + +**Subcommands:** `templates`, `get`, `create`, `update`, `delete` + +**Flags:** + +- `--type` `` — Custom email type (create, required) +- `--subject` `` — Email subject line (create/update) +- `--title` `` — Email title (create/update) +- `--body` `` — Email body text (create/update) +- `--header` `` — Email header text (create/update) +- `--button` `` — Email button text (create/update) + +#### `jc graph` + +Manage JumpCloud resource associations + +**Subcommands:** `traverse`, `bind`, `unbind` + +**Flags:** + +- `--from` `` — Source: type:identifier (e.g. user:jdoe) +- `--to` `` — Target type: user, system, user_group, system_group, application, policy, command + +#### `jc bulk` + +Bulk operations from CSV files + +**Subcommands:** `users` + +**Flags:** + +- `--file` `` — Path to CSV file + +### AI & Automation + +#### `jc recipe` + +Manage and run automation recipes + +Recipes turn JumpCloud workflows into declarative, version-controlled YAML files instead of one-off shell scripts. Each step is a `jc` invocation with template variables (`{{ .param.user }}`, `{{ .step.created_user.id }}`), conditional execution based on prior step outputs, and structured output capture that downstream steps can reference — so a single recipe can create a user, add them to groups, assign devices, send a welcome email, and bail out cleanly if any step fails or a precondition isn't met. The `--plan` flag walks every step without mutation, surfacing exactly what would change before you commit; `--param k=v` makes the same recipe reusable across users, orgs, or MSP customers. Built-ins ship for the workflows admins write over and over (onboarding, offboarding, MFA-reset campaigns, quarterly compliance audits); custom recipes live in `~/.config/jc/recipes/` and can be authored in `$EDITOR` via the TUI (`jc tui` → recipes → `n`). Recipes are also a first-class MCP primitive — agents can invoke `recipe.run` as a single tool call instead of orchestrating five separate ones, dramatically reducing the surface area for LLM missteps on multi-step changes. + +**Subcommands:** `list`, `show`, `run`, `validate`, `create`, `import`, `export` + +**Flags:** + +- `--param` `` — Recipe parameters as key=value (run) +- `--file` `` — Output file path (export) + +#### `jc mcp` + +MCP server for AI agent integration + +Run the jc CLI as a Model Context Protocol (MCP) server, exposing JumpCloud resources as typed tools to MCP-aware clients (Claude Code, Claude Desktop, Cursor, and any other host that speaks MCP). Includes per-minute rate limiting, an optional `--read-only` mode that disables every mutation tool, and a step-up authentication flow (TTY prompt, Touch ID, or webhook) for high-impact operations. Transport is stdio by default — point your MCP client at `jc mcp serve` and the CLI's full surface area becomes available to the agent. + +**Subcommands:** `serve` + +**Flags:** + +- `--rate-limit` `` (default `60`) — Maximum tool calls per minute +- `--read-only` `` — Disable all mutation tools + +#### `jc schema` + +Machine-readable schema and command manifest + +Return machine-readable JSON for every JumpCloud resource type and the full CLI command tree. Designed for LLMs, IDE plugins, code generators, and the public showcase site itself — `jc schema resources` lists every resource with its API version and supported verbs, `jc schema ` returns the typed field list, and `jc schema commands` returns the full command manifest (paths, subcommands, flags, descriptions). The schema is the single source of truth — this site, the MCP server, and `jc ask` all read from it. + +**Subcommands:** `resources`, `commands` + +#### `jc ask` + +Translate natural language queries into jc CLI commands + +Translate plain-English questions into runnable `jc` commands using the bundled schema manifest plus an LLM prompt template. Useful for one-off queries like *"show me admins who haven't logged in for 90 days"* without remembering exact `jc insights query` flag syntax, or for *"suspend everyone in the contractors group"* without hand-piping `jc groups user list` into a `for` loop. The translated command is always printed for review before execution, and pairs naturally with `--plan` to preview any mutation before committing. + +#### `jc explain` + +Explain what a command would do without executing + +Describe what a `jc` invocation would do — in plain English — without running it. Useful for sanity-checking LLM-generated commands before execution, understanding an unfamiliar invocation copied from a runbook, or onboarding new admins. The explanation covers the action type, target resource, affected scope (single object vs. batch), and a reversibility warning for destructive operations (`delete`, `lock`, `erase`). + +### Setup + +#### `jc auth` + +Authentication commands + +Manage JumpCloud credentials and switch between organizations. The CLI supports two credential types: a static API key (read from `JC_API_KEY`, the config, or the system keychain), or an OAuth service account (client ID + secret), with automatic token refresh. Credentials can be stored as plaintext, in macOS Keychain / GNOME libsecret / Windows Credential Manager via a `keychain://` reference, or supplied per-invocation with `--api-key`. Multiple named profiles let MSPs and admins flip between orgs without re-authenticating (`jc auth switch `), and `jc auth status` reveals the active profile, credential type, fingerprint, and source. + +**Subcommands:** `login`, `logout`, `status`, `switch` + +#### `jc config` + +Configuration management + +View and update jc CLI configuration — default output format, color/pager behavior, TUI refresh interval, plan-mode safety toggles, cache TTLs, and dozens of other preferences. Settings live in `~/.config/jc/config.yaml` and can be overridden per-command via `JC_*` environment variables or flags (env > flag > config > built-in default). Use `jc config view` for the full effective configuration including override sources, or `jc config set ` to persist a change. + +**Subcommands:** `view`, `set` + +## Resource types + +Every resource has a JSON schema available via `jc schema `: + +- `access-requests` +- `ad` +- `admins` +- `app-templates` +- `apple-mdm` +- `apps` +- `assets` +- `auth-policies` +- `commands` +- `custom-emails` +- `devices` +- `duo` +- `groups` +- `gsuite` +- `identity-providers` +- `insights` +- `iplists` +- `ldap` +- `office365` +- `org` +- `policies` +- `policy-groups` +- `policy-templates` +- `radius` +- `saas-management` +- `software` +- `system-insights` +- `user-states` +- `users` diff --git a/docs/site/llms.txt b/docs/site/llms.txt new file mode 100644 index 0000000..2a2ae2a --- /dev/null +++ b/docs/site/llms.txt @@ -0,0 +1,78 @@ +# jc + +> JumpCloud CLI — manage users, devices, groups, policies, commands, insights, and more + +The jc CLI is a Go-based command-line tool for JumpCloud — managing users, devices, groups, policies, applications, commands, insights, and more. It exposes every JumpCloud resource through a consistent verb-noun grammar with structured JSON output, an MCP server for AI agents, and a recipe system for declarative automation. + +## Command catalog + +### Identity & Access + +- `jc users` — Manage JumpCloud system users +- `jc groups` — Manage user and device groups +- `jc admins` — Manage JumpCloud administrators +- `jc auth-policies` — Manage authentication policies for conditional access +- `jc iplists` — Manage IP lists for authentication policies +- `jc identity-providers` — Manage JumpCloud identity providers for SSO/OIDC federation + +### Devices & MDM + +- `jc devices` — Manage JumpCloud devices (systems) +- `jc apple-mdm` — Manage Apple MDM configurations + +### Apps & SSO + +- `jc apps` — Manage SSO applications +- `jc saas-management` — Manage JumpCloud SaaS Management applications +- `jc app-templates` — View application templates + +### Policies & Commands + +- `jc commands` — Manage JumpCloud commands +- `jc policies` — Manage JumpCloud policies +- `jc policy-templates` — View policy templates +- `jc policy-groups` — Manage policy groups + +### Insights + +- `jc insights` — Query Directory Insights audit events +- `jc system-insights` — Query osquery system insight tables + +### Integrations + +- `jc software` — Manage JumpCloud software apps +- `jc assets` — Manage JumpCloud assets (devices, accessories, locations) +- `jc ldap` — Manage JumpCloud LDAP servers +- `jc ad` — Manage JumpCloud Active Directory integrations +- `jc radius` — Manage RADIUS servers +- `jc gsuite` — Manage JumpCloud Google Workspace (G Suite) integrations +- `jc office365` — Manage JumpCloud Office 365 integrations +- `jc duo` — Manage JumpCloud Duo accounts and applications + +### Org & Lifecycle + +- `jc access-requests` — Manage JumpCloud temporary elevated device privilege requests +- `jc org` — View and update JumpCloud organization information +- `jc user-states` — Manage scheduled user state transitions +- `jc custom-emails` — Manage custom email templates +- `jc graph` — Manage JumpCloud resource associations +- `jc bulk` — Bulk operations from CSV files + +### AI & Automation + +- `jc recipe` — Manage and run automation recipes +- `jc mcp` — MCP server for AI agent integration +- `jc schema` — Machine-readable schema and command manifest +- `jc ask` — Translate natural language queries into jc CLI commands +- `jc explain` — Explain what a command would do without executing + +### Setup + +- `jc auth` — Authentication commands +- `jc config` — Configuration management + +## See also + +- [Full reference](llms-full.txt) +- [Machine-readable manifest](commands.json) +- [Source repository](https://github.com/TheJumpCloud/jc-cli) diff --git a/internal/schema/schema.go b/internal/schema/schema.go index ac30da0..ba3f756 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -43,9 +43,16 @@ type CommandManifest struct { } // CommandEntry describes a CLI command group with its subcommands and flags. +// +// Long is an optional multi-sentence elaboration shown on the showcase +// site and in llms-full.txt. It's deliberately hand-curated rather than +// pulled from Cobra's Long string — the audience here is "someone +// browsing the public catalog," which wants more context than `jc +// --help` typically gives. Leave empty if Description is sufficient. type CommandEntry struct { Path string `json:"path"` Description string `json:"description"` + Long string `json:"long,omitempty"` Subcommands []string `json:"subcommands,omitempty"` Flags []FlagEntry `json:"flags,omitempty"` } @@ -711,11 +718,13 @@ func BuildCommandManifest() CommandManifest { { Path: "jc auth", Description: "Authentication commands", + Long: "Manage JumpCloud credentials and switch between organizations. The CLI supports two credential types: a static API key (read from `JC_API_KEY`, the config, or the system keychain), or an OAuth service account (client ID + secret), with automatic token refresh. Credentials can be stored as plaintext, in macOS Keychain / GNOME libsecret / Windows Credential Manager via a `keychain://` reference, or supplied per-invocation with `--api-key`. Multiple named profiles let MSPs and admins flip between orgs without re-authenticating (`jc auth switch `), and `jc auth status` reveals the active profile, credential type, fingerprint, and source.", Subcommands: []string{"login", "logout", "status", "switch"}, }, { Path: "jc config", Description: "Configuration management", + Long: "View and update jc CLI configuration — default output format, color/pager behavior, TUI refresh interval, plan-mode safety toggles, cache TTLs, and dozens of other preferences. Settings live in `~/.config/jc/config.yaml` and can be overridden per-command via `JC_*` environment variables or flags (env > flag > config > built-in default). Use `jc config view` for the full effective configuration including override sources, or `jc config set ` to persist a change.", Subcommands: []string{"view", "set"}, }, { @@ -1076,6 +1085,7 @@ func BuildCommandManifest() CommandManifest { { Path: "jc recipe", Description: "Manage and run automation recipes", + Long: "Recipes turn JumpCloud workflows into declarative, version-controlled YAML files instead of one-off shell scripts. Each step is a `jc` invocation with template variables (`{{ .param.user }}`, `{{ .step.created_user.id }}`), conditional execution based on prior step outputs, and structured output capture that downstream steps can reference — so a single recipe can create a user, add them to groups, assign devices, send a welcome email, and bail out cleanly if any step fails or a precondition isn't met. The `--plan` flag walks every step without mutation, surfacing exactly what would change before you commit; `--param k=v` makes the same recipe reusable across users, orgs, or MSP customers. Built-ins ship for the workflows admins write over and over (onboarding, offboarding, MFA-reset campaigns, quarterly compliance audits); custom recipes live in `~/.config/jc/recipes/` and can be authored in `$EDITOR` via the TUI (`jc tui` → recipes → `n`). Recipes are also a first-class MCP primitive — agents can invoke `recipe.run` as a single tool call instead of orchestrating five separate ones, dramatically reducing the surface area for LLM missteps on multi-step changes.", Subcommands: []string{"list", "show", "run", "validate", "create", "import", "export"}, Flags: []FlagEntry{ {Name: "param", Type: "string[]", Description: "Recipe parameters as key=value (run)"}, @@ -1085,6 +1095,7 @@ func BuildCommandManifest() CommandManifest { { Path: "jc mcp", Description: "MCP server for AI agent integration", + Long: "Run the jc CLI as a Model Context Protocol (MCP) server, exposing JumpCloud resources as typed tools to MCP-aware clients (Claude Code, Claude Desktop, Cursor, and any other host that speaks MCP). Includes per-minute rate limiting, an optional `--read-only` mode that disables every mutation tool, and a step-up authentication flow (TTY prompt, Touch ID, or webhook) for high-impact operations. Transport is stdio by default — point your MCP client at `jc mcp serve` and the CLI's full surface area becomes available to the agent.", Subcommands: []string{"serve"}, Flags: []FlagEntry{ {Name: "rate-limit", Type: "int", Default: "60", Description: "Maximum tool calls per minute"}, @@ -1094,15 +1105,18 @@ func BuildCommandManifest() CommandManifest { { Path: "jc schema", Description: "Machine-readable schema and command manifest", + Long: "Return machine-readable JSON for every JumpCloud resource type and the full CLI command tree. Designed for LLMs, IDE plugins, code generators, and the public showcase site itself — `jc schema resources` lists every resource with its API version and supported verbs, `jc schema ` returns the typed field list, and `jc schema commands` returns the full command manifest (paths, subcommands, flags, descriptions). The schema is the single source of truth — this site, the MCP server, and `jc ask` all read from it.", Subcommands: []string{"resources", "commands"}, }, { Path: "jc ask", Description: "Translate natural language queries into jc CLI commands", + Long: "Translate plain-English questions into runnable `jc` commands using the bundled schema manifest plus an LLM prompt template. Useful for one-off queries like *\"show me admins who haven't logged in for 90 days\"* without remembering exact `jc insights query` flag syntax, or for *\"suspend everyone in the contractors group\"* without hand-piping `jc groups user list` into a `for` loop. The translated command is always printed for review before execution, and pairs naturally with `--plan` to preview any mutation before committing.", }, { Path: "jc explain", Description: "Explain what a command would do without executing", + Long: "Describe what a `jc` invocation would do — in plain English — without running it. Useful for sanity-checking LLM-generated commands before execution, understanding an unfamiliar invocation copied from a runbook, or onboarding new admins. The explanation covers the action type, target resource, affected scope (single object vs. batch), and a reversibility warning for destructive operations (`delete`, `lock`, `erase`).", }, }, }