diff --git a/.claude/skills/kosli-next-writer/SKILL.md b/.claude/skills/kosli-next-writer/SKILL.md new file mode 100644 index 0000000..62ea731 --- /dev/null +++ b/.claude/skills/kosli-next-writer/SKILL.md @@ -0,0 +1,87 @@ +--- +name: kosli-next-writer +description: Use when writing or editing docs for Kosli Next - the docs surface for forward-looking concepts and preview features. Triggers on mentions of "Kosli Next", "concept docs", "preview feature docs", or any work on files under `kosli_next/`. Covers where files go, required front matter and banners, navigation updates, and tone. +--- + +# Writing for Kosli Next + +Kosli Next is a separate Mintlify Product (alongside "Product") for content that is **not currently available in Kosli**. Use it for concepts (ideas we're considering) and preview features (opt-in pre-GA features). + +If the content describes something shippable today, it does NOT belong in Kosli Next - it goes in the main "Product" surface under `understand_kosli/`, `getting_started/`, etc. + +## Decision flow + +1. **Is the feature available to all customers today?** → Main docs. Stop reading this skill. +2. **Is it an idea or direction we want feedback on, but nothing is built yet?** → Kosli Next → Concepts. +3. **Is it real, usable, but opt-in / pre-GA?** → Kosli Next → Preview. + +## File locations + +| Content type | Directory | +|---|---| +| Concept page | `kosli_next/concepts/.mdx` | +| Preview page | `kosli_next/preview/.mdx` | + +Use lowercase, underscore-separated slugs to match the rest of the repo (`kosli_next/concepts/my_concept.mdx`). + +## Required page template + +Every Kosli Next page starts with this shape: + +```mdx +--- +title: "Short, specific title" +description: "One sentence describing the page purpose." +tag: "Concept" # or "Preview" +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; +{/* or: import { PreviewBanner } from '/snippets/kosli-next-banner.mdx'; */} + + +{/* or: */} + +Page content goes here. +``` + +The banner snippet (`snippets/kosli-next-banner.mdx`) is the single source of truth for the disclaimer + feedback CTA. Do NOT inline a custom disclaimer. + +## Navigation update (required) + +Add the new page path to `config/navigation.json` under the matching tab in the **Kosli Next** product: + +- Concept pages → `products[1].tabs[0].groups[0].pages` +- Preview pages → `products[1].tabs[1].groups[0].pages` + +A page that isn't in `config/navigation.json` won't appear in the sidebar. This is a core repo rule. + +## Tone + +Standard Kosli writing rules from the project `CLAUDE.md` still apply: + +- Sentence case for headings. +- Active voice and imperative mood. +- "Kosli" - not "the Kosli platform" or "KOSLI". +- Root-relative internal links (`/kosli_next/concepts/foo`, not `../foo`). +- No em-dashes. Use hyphens or rewrite the sentence. + +Two Kosli Next-specific additions: + +- **Be honest about status.** Don't write a Concept page in the present tense as if it works ("Kosli reports X..."). Write in the conditional ("Kosli would report X...") so readers aren't misled into thinking the feature exists. +- **Invite feedback.** End each page with a short prompt: "Tell us what you think - email support@kosli.com." (The banner says this too; an end-of-page nudge is fine.) + +## Form + +Diátaxis is NOT enforced inside Kosli Next. Pick whichever shape best explains the idea: + +- A short PR/FAQ-style explainer (problem → proposed approach → open questions) is often a good fit for Concepts. +- A how-to + reference combination tends to fit Previews. + +## Verification + +Before opening a PR: + +1. Run `mint dev` and confirm the page appears under the right tab in the Kosli Next product switcher. +2. Confirm the banner renders. +3. Run `mint broken-links`. + diff --git a/.gitignore b/.gitignore index 6013b4e..6c8a294 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .claude/settings.local.json tmp/ __pycache__/ +docs/superpowers/ +.DS_Store diff --git a/.mintlify/AGENTS.md b/.mintlify/AGENTS.md new file mode 100644 index 0000000..dbc023c --- /dev/null +++ b/.mintlify/AGENTS.md @@ -0,0 +1,96 @@ +# Kosli docs agent instructions + +These instructions apply to the Mintlify agent across the dashboard, the `@Mintlify` Slack bot, and the docs site assistant. Read them before answering any question or writing any documentation. + +## Project context + +Kosli is a platform for recording changes in software and business processes so customers can prove compliance and maintain security without slowing delivery. The docs site is organised into two Mintlify Products: + +- **`Product`** - documentation for what Kosli does today. This is the default and the authoritative source for "how do I do X" questions. +- **`Kosli Next`** - forward-looking content. Two tabs: + - **Concepts** (`kosli_next/concepts/`) - ideas we're considering. Nothing in here is built. + - **Preview** (`kosli_next/preview/`) - real features available to opt-in customers ahead of general availability. Behaviour can still change. + +## Retrieval rules + +**Default to the `Product` surface.** When a customer asks how to do something, answer from the `Product` Product only. + +**Use Kosli Next only when:** + +1. The user explicitly asks about a future, concept, preview, beta, or roadmap topic, OR +2. No answer exists in the `Product` surface AND a Kosli Next page is directly relevant. + +**Never** answer a "how do I do X today" question using a Kosli Next page without the disclaimer below. + +## Disclaimer when citing Kosli Next + +Every answer that draws on a page under `kosli_next/` must begin with one of: + +- For Concepts: *"This isn't available in Kosli today - it's a concept we're sharing to gather feedback."* +- For Previews: *"This is a preview feature, available to opt-in customers. Behaviour can still change."* + +End the answer with an invitation to share feedback at `support@kosli.com`. + +## When writing documentation + +These rules apply to any documentation you author or edit, including via the `@Mintlify` Slack bot. + +### Where things go + +- Features generally available today → main docs under `understand_kosli/`, `getting_started/`, `administration/`, `integrations/`, `tutorials/`, `troubleshooting/`, `client_reference/`, etc. +- Ideas not built yet → `kosli_next/concepts/.mdx` with `tag: "Concept"` and the `` from `/snippets/kosli-next-banner.mdx`. +- Opt-in pre-GA features → `kosli_next/preview/.mdx` with `tag: "Preview"` and the `` from `/snippets/kosli-next-banner.mdx`. + +Every new page must be registered in `config/navigation.json` under the matching Product and tab. + +### Required Kosli Next page shape + +```mdx +--- +title: "Short, specific title" +description: "One sentence describing the page purpose." +tag: "Concept" # or "Preview" +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; + + + +Page content here. +``` + +Do not inline a custom disclaimer. The banner snippet is the single source of truth so the feedback channel can be swapped later without editing every page. + +For Concept pages, write in the conditional ("Kosli would report X..."), not the present tense, so readers are not misled into thinking the feature exists. + +### Style and tone + +- Refer to the product as **Kosli** - never "the Kosli platform" or "KOSLI". +- Use "audit trail" not "audit log"; "attest" not "certify". +- Active voice and imperative mood for instructions ("Run `kosli attest`", not "You should run"). +- Sentence case for all headings. +- Root-relative internal links only (`/getting_started/install`, not `../install`). +- No em-dashes. Use hyphens or rewrite the sentence. + +### MDX components + +Prefer the components already in use in this repo: + +- `` / `` for sequential procedures. +- `` / `` for platform-specific alternatives. +- `` / `` / `` for navigational tiles. +- `` / `` for progressive disclosure. +- `` / `` / `` / `` for callouts, sparingly. +- `` for the same command in multiple languages. +- `` for wrapping images. + +### Do not + +- Do not edit pages under `essentials/` - they are Mintlify's own content, not Kosli's. +- Do not add new snippets unless the content is genuinely reused in 2+ pages. +- Do not propose changes that bypass `config/navigation.json` - pages not in nav do not appear on the site. + +## Reference + +- Writer skill (for Claude in the repo): `.claude/skills/kosli-next-writer/SKILL.md` +- Project conventions: `CLAUDE.md` diff --git a/CLAUDE.md b/CLAUDE.md index 2e74e08..8c92f85 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,9 +6,9 @@ This file governs repo-specific conventions for Claude Code. Skills, plugins, ag Apply these unless a skill, plugin, agent, or system prompt explicitly overrides them for its scope: -1. Never commit directly to `main` — always work on a branch and open a PR. +1. Never commit directly to `main` - always work on a branch and open a PR. 2. Never create a page file without also adding it to `navigation` in `config/navigation.json`. -3. Never use relative links — always use root-relative paths (e.g., `/getting_started/install`). +3. Never use relative links - always use root-relative paths (e.g., `/getting_started/install`). 4. Commit messages and PR titles must follow [Conventional Commits](https://www.conventionalcommits.org/): `type: short description` (lowercase, no period). Common types: `feat`, `fix`, `docs`, `style`, `chore`. 5. Run `mint broken-links` before committing navigation or link changes. @@ -60,13 +60,13 @@ description: One sentence describing the page purpose. --- ``` -- **MUST** Use root-relative paths for internal links: `/understand_kosli/what_is_kosli` ✓ — `../what_is_kosli` ✗ +- **MUST** Use root-relative paths for internal links: `/understand_kosli/what_is_kosli` ✓ - `../what_is_kosli` ✗ - **MUST** Adding a new page: create the file AND add its path to `navigation` in `config/navigation.json`. Both steps are required. - **SHOULD** Follow the [Diátaxis](https://diataxis.fr/) framework when choosing page form: - - **Tutorial** — teaches by doing (e.g., "Get familiar with Kosli") - - **How-to guide** — step-by-step for a specific goal (e.g., "Report AWS environments") - - **Reference** — factual, lookup-oriented (e.g., CLI reference pages) - - **Explanation** — concepts and background (e.g., "What is Kosli?") + - **Tutorial** - teaches by doing (e.g., "Get familiar with Kosli") + - **How-to guide** - step-by-step for a specific goal (e.g., "Report AWS environments") + - **Reference** - factual, lookup-oriented (e.g., CLI reference pages) + - **Explanation** - concepts and background (e.g., "What is Kosli?") - **MAY** Add an `icon` field to front matter using [Font Awesome](https://fontawesome.com/icons) names. ### MDX Components @@ -77,17 +77,18 @@ description: One sentence describing the page purpose. | `` / `` | Platform-specific or alternative content | | `` / `` | Navigational links, feature highlights | | `` / `` | Progressive disclosure, FAQs | -| `` / `` / `` / `` | Callouts — use sparingly | +| `` / `` / `` / `` | Callouts - use sparingly | | `` | Same command in multiple languages/tools | | `` | Wrapping images | ### Writing style - Use active voice and imperative mood for instructions ("Run `kosli attest`", not "You should run"). -- Refer to the product as **Kosli** — not "the Kosli platform" or "KOSLI". +- Refer to the product as **Kosli** - not "the Kosli platform" or "KOSLI". - Use "audit trail" not "audit log"; "attest" not "certify". - Use American spelling (organization, behavior, color), not British. Enforced by Vale via `styles/Kosli/AmericanSpelling.yml`. - Sentence case for all headings. +- No em-dashes. Use hyphens or rewrite the sentence. ## Don'ts @@ -95,14 +96,15 @@ description: One sentence describing the page purpose. - Don't create a page without updating `config/navigation.json` — it won't appear in the site. - Don't add content to `snippets/` unless it is genuinely reused in 2+ pages. - Don't commit image files without placing them in an appropriate subdirectory. -- Don't push to `main` directly — always use a PR. +- Don't push to `main` directly - always use a PR. ## Skills When available, prefer skills over ad-hoc approaches: -- **PR creation** — use the `pr-creator` skill if available. -- **Changelog entries** — use the `changelog-creator` skill if available. Follow the existing `` format in `changelog/index.mdx` exactly: +- **Kosli Next writing** - for any docs work under `kosli_next/` (concepts and preview features), use the `kosli-next-writer` skill in `.claude/skills/kosli-next-writer/`. It covers file locations, the required banner snippet, navigation updates, and tone. +- **PR creation** - use the `pr-creator` skill if available. +- **Changelog entries** - use the `changelog-creator` skill if available. Follow the existing `` format in `changelog/index.mdx` exactly: ```mdx diff --git a/config/footer.json b/config/footer.json index 825e68e..c0b26ae 100644 --- a/config/footer.json +++ b/config/footer.json @@ -25,6 +25,10 @@ "label": "Labs", "href": "/labs" }, + { + "label": "Kosli Next", + "href": "/kosli_next/index" + }, { "label": "Blog", "href": "https://kosli.com/blog/" diff --git a/config/navigation.json b/config/navigation.json index b436386..fa4fb96 100644 --- a/config/navigation.json +++ b/config/navigation.json @@ -1,518 +1,551 @@ { - "tabs": [ + "products": [ { - "tab": "Documentation", - "groups": [ - { - "group": "Understand Kosli", - "icon": "book-open", - "pages": [ - "understand_kosli/what_is_kosli", - "understand_kosli/risks", - "understand_kosli/controls", - "understand_kosli/how_kosli_works", - "understand_kosli/glossary", - "understand_kosli/ai_docs_access" - ] - }, - { - "group": "Getting started", - "icon": "rocket", - "pages": [ - "getting_started/install", - "getting_started/authenticating_to_kosli", - "getting_started/flows", - "getting_started/trails", - "getting_started/artifacts", - "getting_started/attestations", - "getting_started/environments", - "getting_started/policies", - "getting_started/enforce_policies", - "getting_started/approvals" - ] - }, - { - "group": "User", - "icon": "user", - "pages": [ - "user/default_organization", - "user/personal_api_keys" - ] - }, + "product": "Product", + "description": "Documentation for Kosli as it exists today.", + "tabs": [ { - "group": "Administration", - "icon": "cog", - "pages": [ - { - "group": "Authentication & access", - "pages": [ - "administration/authentication/api_authentication_methods", - "administration/authentication/service_accounts", - "administration/authentication/api_key_rotation" - ] - }, - { - "group": "Users & roles", - "pages": [ - "administration/managing_users/roles_in_kosli", - "administration/managing_users/mapping_users_to_roles" - ] - }, + "tab": "Documentation", + "groups": [ { - "group": "Managing Environments", + "group": "Understand Kosli", + "icon": "book-open", "pages": [ - "administration/managing_environments/overview" + "understand_kosli/what_is_kosli", + "understand_kosli/risks", + "understand_kosli/controls", + "understand_kosli/how_kosli_works", + "understand_kosli/glossary", + "understand_kosli/ai_docs_access" ] }, - { - "group": "Managing Custom Attestation Types", - "pages": [ - "administration/managing_custom_attestation_types/overview" - ] - }, - "administration/managing_tags" - ] - }, - { - "group": "Tutorials", - "icon": "graduation-cap", - "pages": [ { "group": "Getting started", + "icon": "rocket", "pages": [ - "tutorials/try_kosli_locally", - "tutorials/cli_and_http_proxy", - "tutorials/organizing_with_spaces" - ] - }, - { - "group": "Attesting", - "pages": [ - "tutorials/attest_custom", - "tutorials/attest_snyk", - "tutorials/custom-attestation-ctrf", - "tutorials/attest_large_documents" - ] - }, - { - "group": "Reporting environments", - "pages": [ - "tutorials/report_aws_envs", - "tutorials/report_k8s_envs", - "tutorials/report_cloud_run_envs" + "getting_started/install", + "getting_started/authenticating_to_kosli", + "getting_started/flows", + "getting_started/trails", + "getting_started/artifacts", + "getting_started/attestations", + "getting_started/environments", + "getting_started/policies", + "getting_started/enforce_policies", + "getting_started/approvals" ] }, { - "group": "Querying & tracing", + "group": "User", + "icon": "user", "pages": [ - "tutorials/querying_kosli", - "tutorials/following_a_git_commit_to_runtime_environments", - "tutorials/tracing_a_production_incident_back_to_git_commits" + "user/default_organization", + "user/personal_api_keys" ] }, { - "group": "Security", + "group": "Administration", + "icon": "cog", "pages": [ - "tutorials/unauthorized_iac_changes", - "tutorials/rotating_api_keys" + { + "group": "Authentication & access", + "pages": [ + "administration/authentication/api_authentication_methods", + "administration/authentication/service_accounts", + "administration/authentication/api_key_rotation" + ] + }, + { + "group": "Users & roles", + "pages": [ + "administration/managing_users/roles_in_kosli", + "administration/managing_users/mapping_users_to_roles" + ] + }, + { + "group": "Managing Environments", + "pages": [ + "administration/managing_environments/overview" + ] + }, + { + "group": "Managing Custom Attestation Types", + "pages": [ + "administration/managing_custom_attestation_types/overview" + ] + }, + "administration/managing_tags" ] }, { - "group": "Evaluation", + "group": "Tutorials", + "icon": "graduation-cap", "pages": [ - "tutorials/evaluate_trails_with_opa" + { + "group": "Getting started", + "pages": [ + "tutorials/try_kosli_locally", + "tutorials/cli_and_http_proxy", + "tutorials/organizing_with_spaces" + ] + }, + { + "group": "Attesting", + "pages": [ + "tutorials/attest_custom", + "tutorials/attest_snyk", + "tutorials/custom-attestation-ctrf", + "tutorials/attest_large_documents" + ] + }, + { + "group": "Reporting environments", + "pages": [ + "tutorials/report_aws_envs", + "tutorials/report_k8s_envs", + "tutorials/report_cloud_run_envs" + ] + }, + { + "group": "Querying & tracing", + "pages": [ + "tutorials/querying_kosli", + "tutorials/following_a_git_commit_to_runtime_environments", + "tutorials/tracing_a_production_incident_back_to_git_commits" + ] + }, + { + "group": "Security", + "pages": [ + "tutorials/unauthorized_iac_changes", + "tutorials/rotating_api_keys" + ] + }, + { + "group": "Evaluation", + "pages": [ + "tutorials/evaluate_trails_with_opa" + ] + }, + { + "group": "Multi-flow workflows", + "pages": [ + "tutorials/linking_trails_across_branches" + ] + }, + { + "group": "Controls", + "pages": [ + "tutorials/working_with_controls" + ] + }, + { + "group": "Repositories", + "pages": [ + "tutorials/repositories" + ] + } ] }, { - "group": "Multi-flow workflows", + "group": "Troubleshooting", + "icon": "wrench", "pages": [ - "tutorials/linking_trails_across_branches" + "troubleshooting/what_do_i_do_if_kosli_is_down", + "troubleshooting/docker_api_version_error", + "troubleshooting/repo_digest_unavailable", + "troubleshooting/zsh_no_such_user", + "troubleshooting/github_kosli_api_token", + "troubleshooting/subshell_stderr", + "troubleshooting/whitespace_path" ] }, { - "group": "Controls", + "group": "FAQ", + "icon": "circle-question", "pages": [ - "tutorials/working_with_controls" + "faq/faq" ] }, { - "group": "Repositories", + "group": "Integrations", + "icon": "puzzle-piece", "pages": [ - "tutorials/repositories" + "integrations/actions", + "integrations/ci_cd", + "integrations/slack", + "integrations/launchdarkly", + "integrations/sonar" ] } ] }, { - "group": "Troubleshooting", - "icon": "wrench", - "pages": [ - "troubleshooting/what_do_i_do_if_kosli_is_down", - "troubleshooting/docker_api_version_error", - "troubleshooting/repo_digest_unavailable", - "troubleshooting/zsh_no_such_user", - "troubleshooting/github_kosli_api_token", - "troubleshooting/subshell_stderr", - "troubleshooting/whitespace_path" - ] - }, - { - "group": "FAQ", - "icon": "circle-question", - "pages": [ - "faq/faq" - ] - }, - { - "group": "Integrations", - "icon": "puzzle-piece", - "pages": [ - "integrations/actions", - "integrations/ci_cd", - "integrations/slack", - "integrations/launchdarkly", - "integrations/sonar" - ] - } - ] - }, - { - "tab": "Labs", - "groups": [ - { - "group": "Kosli Learning Labs", - "pages": [ - "labs/index", - "labs/lab-01-get-ready", - "labs/lab-02-flows-and-trails", - "labs/lab-03-build-controls", - "labs/lab-04-release-controls", - "labs/lab-05-runtime-controls" - ] - } - ] - }, - { - "tab": "Implementation Guide", - "groups": [ - { - "group": "Phase 1: Initial Discovery", - "icon": "lightbulb", - "pages": [ + "tab": "Labs", + "groups": [ { - "group": "Roles & Responsibilities", + "group": "Kosli Learning Labs", "pages": [ - "implementation_guide/phase_1/roles_and_responsibilities/overview", - "implementation_guide/phase_1/roles_and_responsibilities/platform_engineers", - "implementation_guide/phase_1/roles_and_responsibilities/app_developers", - "implementation_guide/phase_1/roles_and_responsibilities/security_compliance", - "implementation_guide/phase_1/roles_and_responsibilities/sponsors" + "labs/index", + "labs/lab-01-get-ready", + "labs/lab-02-flows-and-trails", + "labs/lab-03-build-controls", + "labs/lab-04-release-controls", + "labs/lab-05-runtime-controls" ] } ] }, { - "group": "Phase 2: Configure Kosli", - "icon": "gear", - "pages": [ + "tab": "Implementation Guide", + "groups": [ { - "group": "Plan Organizational Structure", + "group": "Phase 1: Initial Discovery", + "icon": "lightbulb", "pages": [ { - "group": "Naming Conventions", + "group": "Roles & Responsibilities", "pages": [ - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/overview", - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/attestation_types", - "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/flows_and_trails" + "implementation_guide/phase_1/roles_and_responsibilities/overview", + "implementation_guide/phase_1/roles_and_responsibilities/platform_engineers", + "implementation_guide/phase_1/roles_and_responsibilities/app_developers", + "implementation_guide/phase_1/roles_and_responsibilities/security_compliance", + "implementation_guide/phase_1/roles_and_responsibilities/sponsors" ] } ] - } - ] - } - ] - }, - { - "tab": "Reference", - "menu": [ - { - "item": "CLI Reference", - "icon": "terminal", - "groups": [ - { - "group": "General", - "pages": [ - "client_reference/overview", - "client_reference/output_and_verbosity" - ] - }, - { - "group": "Top-level commands", - "pages": [ - "client_reference/kosli", - "client_reference/kosli_attach-policy", - "client_reference/kosli_completion", - "client_reference/kosli_config", - "client_reference/kosli_detach-policy", - "client_reference/kosli_fingerprint", - "client_reference/kosli_search", - "client_reference/kosli_status", - "client_reference/kosli_tag", - "client_reference/kosli_version" - ] - }, - { - "group": "kosli allow", - "pages": [ - "client_reference/kosli_allow_artifact" - ] - }, - { - "group": "kosli archive", - "pages": [ - "client_reference/kosli_archive_attestation-type", - "client_reference/kosli_archive_environment", - "client_reference/kosli_archive_flow" - ] - }, - { - "group": "kosli assert", - "pages": [ - "client_reference/kosli_assert_artifact", - "client_reference/kosli_assert_pullrequest_azure", - "client_reference/kosli_assert_pullrequest_bitbucket", - "client_reference/kosli_assert_pullrequest_github", - "client_reference/kosli_assert_pullrequest_gitlab", - "client_reference/kosli_assert_snapshot", - "client_reference/kosli_assert_status" - ] }, { - "group": "kosli attest", + "group": "Phase 2: Configure Kosli", + "icon": "gear", "pages": [ - "client_reference/kosli_attest_artifact", - "client_reference/kosli_attest_custom", - "client_reference/kosli_attest_generic", - "client_reference/kosli_attest_jira", - "client_reference/kosli_attest_junit", - "client_reference/kosli_attest_pullrequest_azure", - "client_reference/kosli_attest_pullrequest_bitbucket", - "client_reference/kosli_attest_pullrequest_github", - "client_reference/kosli_attest_pullrequest_gitlab", - "client_reference/kosli_attest_snyk", - "client_reference/kosli_attest_sonar" - ] - }, - { - "group": "kosli begin", - "pages": [ - "client_reference/kosli_begin_trail" - ] - }, - { - "group": "kosli create", - "pages": [ - "client_reference/kosli_create_api-key", - "client_reference/kosli_create_attestation-type", - "client_reference/kosli_create_environment", - "client_reference/kosli_create_flow", - "client_reference/kosli_create_policy" - ] - }, - { - "group": "kosli delete", - "pages": [ - "client_reference/kosli_delete_api-key" - ] - }, - { - "group": "kosli diff", - "pages": [ - "client_reference/kosli_diff_snapshots" - ] - }, - { - "group": "kosli disable / enable", - "pages": [ - "client_reference/kosli_disable_beta", - "client_reference/kosli_enable_beta" - ] - }, - { - "group": "kosli evaluate", - "pages": [ - "client_reference/kosli_evaluate_input", - "client_reference/kosli_evaluate_trail", - "client_reference/kosli_evaluate_trails" - ] - }, - { - "group": "kosli get", - "pages": [ - "client_reference/kosli_get_artifact", - "client_reference/kosli_get_attestation-type", - "client_reference/kosli_get_attestation", - "client_reference/kosli_get_environment", - "client_reference/kosli_get_flow", - "client_reference/kosli_get_policy", - "client_reference/kosli_get_snapshot", - "client_reference/kosli_get_trail" - ] - }, - { - "group": "kosli join", - "pages": [ - "client_reference/kosli_join_environment" + { + "group": "Plan Organizational Structure", + "pages": [ + { + "group": "Naming Conventions", + "pages": [ + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/overview", + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/attestation_types", + "implementation_guide/phase_2/plan_organizational_structure/naming_conventions/flows_and_trails" + ] + } + ] + } ] - }, + } + ] + }, + { + "tab": "Reference", + "menu": [ { - "group": "kosli list", - "pages": [ - "client_reference/kosli_list_api-keys", - "client_reference/kosli_list_artifacts", - "client_reference/kosli_list_attestation-types", - "client_reference/kosli_list_environments", - "client_reference/kosli_list_flows", - "client_reference/kosli_list_policies", - "client_reference/kosli_list_snapshots", - "client_reference/kosli_list_trails" + "item": "CLI Reference", + "icon": "terminal", + "groups": [ + { + "group": "General", + "pages": [ + "client_reference/overview", + "client_reference/output_and_verbosity" + ] + }, + { + "group": "Top-level commands", + "pages": [ + "client_reference/kosli", + "client_reference/kosli_attach-policy", + "client_reference/kosli_completion", + "client_reference/kosli_config", + "client_reference/kosli_detach-policy", + "client_reference/kosli_fingerprint", + "client_reference/kosli_search", + "client_reference/kosli_status", + "client_reference/kosli_tag", + "client_reference/kosli_version" + ] + }, + { + "group": "kosli allow", + "pages": [ + "client_reference/kosli_allow_artifact" + ] + }, + { + "group": "kosli archive", + "pages": [ + "client_reference/kosli_archive_attestation-type", + "client_reference/kosli_archive_environment", + "client_reference/kosli_archive_flow" + ] + }, + { + "group": "kosli assert", + "pages": [ + "client_reference/kosli_assert_artifact", + "client_reference/kosli_assert_pullrequest_azure", + "client_reference/kosli_assert_pullrequest_bitbucket", + "client_reference/kosli_assert_pullrequest_github", + "client_reference/kosli_assert_pullrequest_gitlab", + "client_reference/kosli_assert_snapshot", + "client_reference/kosli_assert_status" + ] + }, + { + "group": "kosli attest", + "pages": [ + "client_reference/kosli_attest_artifact", + "client_reference/kosli_attest_custom", + "client_reference/kosli_attest_generic", + "client_reference/kosli_attest_jira", + "client_reference/kosli_attest_junit", + "client_reference/kosli_attest_pullrequest_azure", + "client_reference/kosli_attest_pullrequest_bitbucket", + "client_reference/kosli_attest_pullrequest_github", + "client_reference/kosli_attest_pullrequest_gitlab", + "client_reference/kosli_attest_snyk", + "client_reference/kosli_attest_sonar" + ] + }, + { + "group": "kosli begin", + "pages": [ + "client_reference/kosli_begin_trail" + ] + }, + { + "group": "kosli create", + "pages": [ + "client_reference/kosli_create_api-key", + "client_reference/kosli_create_attestation-type", + "client_reference/kosli_create_environment", + "client_reference/kosli_create_flow", + "client_reference/kosli_create_policy" + ] + }, + { + "group": "kosli delete", + "pages": [ + "client_reference/kosli_delete_api-key" + ] + }, + { + "group": "kosli diff", + "pages": [ + "client_reference/kosli_diff_snapshots" + ] + }, + { + "group": "kosli disable / enable", + "pages": [ + "client_reference/kosli_disable_beta", + "client_reference/kosli_enable_beta" + ] + }, + { + "group": "kosli evaluate", + "pages": [ + "client_reference/kosli_evaluate_input", + "client_reference/kosli_evaluate_trail", + "client_reference/kosli_evaluate_trails" + ] + }, + { + "group": "kosli get", + "pages": [ + "client_reference/kosli_get_artifact", + "client_reference/kosli_get_attestation-type", + "client_reference/kosli_get_attestation", + "client_reference/kosli_get_environment", + "client_reference/kosli_get_flow", + "client_reference/kosli_get_policy", + "client_reference/kosli_get_snapshot", + "client_reference/kosli_get_trail" + ] + }, + { + "group": "kosli join", + "pages": [ + "client_reference/kosli_join_environment" + ] + }, + { + "group": "kosli list", + "pages": [ + "client_reference/kosli_list_api-keys", + "client_reference/kosli_list_artifacts", + "client_reference/kosli_list_attestation-types", + "client_reference/kosli_list_environments", + "client_reference/kosli_list_flows", + "client_reference/kosli_list_policies", + "client_reference/kosli_list_snapshots", + "client_reference/kosli_list_trails" + ] + }, + { + "group": "kosli log", + "pages": [ + "client_reference/kosli_log_environment" + ] + }, + { + "group": "kosli rename", + "pages": [ + "client_reference/kosli_rename_environment", + "client_reference/kosli_rename_flow" + ] + }, + { + "group": "kosli rotate", + "pages": [ + "client_reference/kosli_rotate_api-key" + ] + }, + { + "group": "kosli snapshot", + "pages": [ + "client_reference/kosli_snapshot_azure", + "client_reference/kosli_snapshot_cloud-run", + "client_reference/kosli_snapshot_docker", + "client_reference/kosli_snapshot_ecs", + "client_reference/kosli_snapshot_k8s", + "client_reference/kosli_snapshot_lambda", + "client_reference/kosli_snapshot_path", + "client_reference/kosli_snapshot_paths", + "client_reference/kosli_snapshot_s3" + ] + }, + { + "group": "Deprecated", + "pages": [ + "client_reference/kosli_assert_approval", + "client_reference/kosli_get_approval", + "client_reference/kosli_list_approvals", + "client_reference/kosli_report_approval", + "client_reference/kosli_report_artifact", + "client_reference/kosli_request_approval", + "client_reference/kosli_snapshot_server" + ] + } ] }, { - "group": "kosli log", - "pages": [ - "client_reference/kosli_log_environment" + "item": "Template Reference", + "icon": "file-code", + "groups": [ + { + "group": "Templates", + "pages": [ + "template-reference/flow_template" + ] + } ] }, { - "group": "kosli rename", - "pages": [ - "client_reference/kosli_rename_environment", - "client_reference/kosli_rename_flow" + "item": "Policy Reference", + "icon": "scroll", + "groups": [ + { + "group": "Policies", + "pages": [ + "policy-reference/environment_policy", + "policy-reference/policy_builder", + "policy-reference/rego_policy" + ] + } ] }, { - "group": "kosli rotate", - "pages": [ - "client_reference/kosli_rotate_api-key" - ] + "item": "API Reference", + "icon": "code", + "openapi": "https://app.kosli.com/api/v2/openapi.json" }, { - "group": "kosli snapshot", - "pages": [ - "client_reference/kosli_snapshot_azure", - "client_reference/kosli_snapshot_cloud-run", - "client_reference/kosli_snapshot_docker", - "client_reference/kosli_snapshot_ecs", - "client_reference/kosli_snapshot_k8s", - "client_reference/kosli_snapshot_lambda", - "client_reference/kosli_snapshot_path", - "client_reference/kosli_snapshot_paths", - "client_reference/kosli_snapshot_s3" + "item": "Helm Reference", + "icon": "layer-group", + "groups": [ + { + "group": "Helm Charts", + "pages": [ + "helm/k8s_reporter" + ] + } ] }, { - "group": "Deprecated", - "pages": [ - "client_reference/kosli_assert_approval", - "client_reference/kosli_get_approval", - "client_reference/kosli_list_approvals", - "client_reference/kosli_report_approval", - "client_reference/kosli_report_artifact", - "client_reference/kosli_request_approval", - "client_reference/kosli_snapshot_server" + "item": "Terraform Reference", + "icon": "cubes", + "groups": [ + { + "group": "Provider", + "pages": [ + "terraform-reference/index" + ] + }, + { + "group": "Resources", + "pages": [ + "terraform-reference/resources/environment", + "terraform-reference/resources/logical_environment", + "terraform-reference/resources/flow", + "terraform-reference/resources/custom_attestation_type", + "terraform-reference/resources/action", + "terraform-reference/resources/policy", + "terraform-reference/resources/policy_attachment" + ] + }, + { + "group": "Data Sources", + "pages": [ + "terraform-reference/data-sources/environment", + "terraform-reference/data-sources/logical_environment", + "terraform-reference/data-sources/flow", + "terraform-reference/data-sources/custom_attestation_type", + "terraform-reference/data-sources/action", + "terraform-reference/data-sources/policy" + ] + } ] } ] }, { - "item": "Template Reference", - "icon": "file-code", + "tab": "Changelog", + "icon": "clock", "groups": [ { - "group": "Templates", + "group": "Changelog", "pages": [ - "template-reference/flow_template" + "changelog/index" ] } ] - }, + } + ] + }, + { + "product": "Kosli Next", + "description": "Concepts and preview features we're exploring with customers.", + "groups": [ { - "item": "Policy Reference", - "icon": "scroll", - "groups": [ - { - "group": "Policies", - "pages": [ - "policy-reference/environment_policy", - "policy-reference/policy_builder", - "policy-reference/rego_policy" - ] - } + "group": "Kosli Next", + "icon": "compass", + "pages": [ + "kosli_next/index" ] }, { - "item": "API Reference", - "icon": "code", - "openapi": "https://app.kosli.com/api/v2/openapi.json" - }, - { - "item": "Helm Reference", - "icon": "layer-group", - "groups": [ - { - "group": "Helm Charts", - "pages": [ - "helm/k8s_reporter" - ] - } + "group": "Concepts", + "icon": "lightbulb", + "pages": [ + "kosli_next/concepts/index" ] }, { - "item": "Terraform Reference", - "icon": "cubes", - "groups": [ - { - "group": "Provider", - "pages": [ - "terraform-reference/index" - ] - }, - { - "group": "Resources", - "pages": [ - "terraform-reference/resources/environment", - "terraform-reference/resources/logical_environment", - "terraform-reference/resources/flow", - "terraform-reference/resources/custom_attestation_type", - "terraform-reference/resources/action", - "terraform-reference/resources/policy", - "terraform-reference/resources/policy_attachment" - ] - }, - { - "group": "Data Sources", - "pages": [ - "terraform-reference/data-sources/environment", - "terraform-reference/data-sources/logical_environment", - "terraform-reference/data-sources/flow", - "terraform-reference/data-sources/custom_attestation_type", - "terraform-reference/data-sources/action", - "terraform-reference/data-sources/policy" - ] - } - ] - } - ] - }, - { - "tab": "Changelog", - "icon": "clock", - "groups": [ - { - "group": "Changelog", + "group": "Preview", + "icon": "flask", "pages": [ - "changelog/index" + "kosli_next/preview/mcp_server" ] } ] diff --git a/images/kosli_next/controls/controls-compliance-coverage.png b/images/kosli_next/controls/controls-compliance-coverage.png new file mode 100644 index 0000000..e67dbe1 Binary files /dev/null and b/images/kosli_next/controls/controls-compliance-coverage.png differ diff --git a/images/kosli_next/controls/controls-compliance-deployments.png b/images/kosli_next/controls/controls-compliance-deployments.png new file mode 100644 index 0000000..db50bc6 Binary files /dev/null and b/images/kosli_next/controls/controls-compliance-deployments.png differ diff --git a/images/kosli_next/controls/controls-decisions.png b/images/kosli_next/controls/controls-decisions.png new file mode 100644 index 0000000..d559013 Binary files /dev/null and b/images/kosli_next/controls/controls-decisions.png differ diff --git a/images/kosli_next/controls/controls-list.png b/images/kosli_next/controls/controls-list.png new file mode 100644 index 0000000..0145238 Binary files /dev/null and b/images/kosli_next/controls/controls-list.png differ diff --git a/images/kosli_next/index/kosli-next-dark.png b/images/kosli_next/index/kosli-next-dark.png new file mode 100644 index 0000000..91686f7 Binary files /dev/null and b/images/kosli_next/index/kosli-next-dark.png differ diff --git a/images/kosli_next/index/kosli-next-light.png b/images/kosli_next/index/kosli-next-light.png new file mode 100644 index 0000000..8ce2c00 Binary files /dev/null and b/images/kosli_next/index/kosli-next-light.png differ diff --git a/kosli_next/concepts/index.mdx b/kosli_next/concepts/index.mdx new file mode 100644 index 0000000..7f31d78 --- /dev/null +++ b/kosli_next/concepts/index.mdx @@ -0,0 +1,12 @@ +--- +title: "Concepts" +description: "Ideas and directions we're considering for Kosli. Nothing here is built yet — we publish them to gather feedback." +--- + +import { ConceptBanner } from '/snippets/kosli-next-banner.mdx'; + + + +We publish concepts here before building them, so customers can shape the direction early. + +More concepts coming soon. To give feedback or suggest a topic, email [support@kosli.com](mailto:support@kosli.com). diff --git a/kosli_next/index.mdx b/kosli_next/index.mdx new file mode 100644 index 0000000..9580a60 --- /dev/null +++ b/kosli_next/index.mdx @@ -0,0 +1,33 @@ +--- +title: "Overview" +description: "Forward-looking concepts and preview features we're exploring with our customers." +--- + + + Kosli Next + Kosli Next + + +Kosli Next is where we share what we're working on next, so customers can shape it before it ships. + +It contains two kinds of content: + +- **Concepts** - ideas and directions we're considering. Nothing here is built yet. We publish them to gather feedback on the problem and the proposed approach. +- **Preview** - real features available to opt-in customers ahead of general availability. Behaviour can still change. + +Nothing in Kosli Next is part of Kosli's current product surface. To learn what Kosli does today, switch to the **Product** view. + +## How to give feedback + +Email [support@kosli.com](mailto:support@kosli.com) with the page name and your thoughts. We read every message. + +## Explore + + + + Ideas we're considering. Tell us what resonates and what doesn't. + + + Opt-in features close to general availability. + + diff --git a/kosli_next/preview/mcp_server.mdx b/kosli_next/preview/mcp_server.mdx new file mode 100644 index 0000000..18e214c --- /dev/null +++ b/kosli_next/preview/mcp_server.mdx @@ -0,0 +1,107 @@ +--- +title: "Kosli MCP Server" +description: "Expose the Kosli API to LLM clients like Claude Code and Claude Desktop via the Model Context Protocol." +tag: "Preview" +--- + +import { PreviewBanner } from '/snippets/kosli-next-banner.mdx'; + + + +The Kosli MCP Server is a [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the Kosli API to LLM clients. Once installed, you can ask Claude things like _"which artifacts are running in prod-aws and which are non-compliant?"_ and it will call the relevant Kosli endpoints for you. + +It is published from [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server) and distributed as both an npm package (`@kosli/mcp-server`) and a `.mcpb` desktop bundle. + +## How it works + +Rather than ship a tool per Kosli endpoint, the server generates a catalog from Kosli's OpenAPI spec and exposes three generic tools: + +| Tool | Purpose | +|------|---------| +| `search_actions` | Fuzzy-search the catalog for relevant actions by natural-language query. | +| `execute_read_action` | Invoke any GET action by ID. Auto-allowed in MCP clients. | +| `execute_write_action` | Invoke any POST/PUT/PATCH/DELETE action by ID. Gated behind user approval. | + +The typical flow is: the LLM calls `search_actions` to discover the right action ID and its parameter schema, then calls `execute_read_action` or `execute_write_action` with the chosen ID. Both execute tools accept an optional `fields` array to request only specific top-level fields in the response, which keeps token usage down. + +## Prerequisites + +- Node.js v20 or higher +- A [Kosli API token](/getting_started/service-accounts) +- An MCP-capable client (Claude Code, Claude Desktop, or any other) + +## Install + + + + Run from your project directory, or add `--scope user` to install globally: + + ```bash + claude mcp add kosli \ + -e KOSLI_API_TOKEN=your-token \ + -e KOSLI_ORG=your-org \ + -- npx -y @kosli/mcp-server + ``` + + + Download the latest `.mcpb` file from the [releases page](https://github.com/kosli-dev/mcp-server/releases) and drag it into Claude Desktop (or double-click to install). Claude Desktop will prompt for your API token and organization, and store secrets in the OS keychain. + + + Sideloaded extensions show an "unverified by Anthropic" warning and do not auto-update. These limitations will go away once the extension is listed in Anthropic's Connectors Directory. + + + + Edit `claude_desktop_config.json` via **Settings → Developer → Edit Config**: + + ```json + { + "mcpServers": { + "kosli": { + "command": "npx", + "args": ["-y", "@kosli/mcp-server"], + "env": { + "KOSLI_API_TOKEN": "your-token", + "KOSLI_ORG": "your-org" + } + } + } + } + ``` + + This method auto-updates via `npx` on each restart, but stores secrets in plain text. + + + The server communicates over stdio. Point any MCP-compatible client at the package via `npx -y @kosli/mcp-server` and set the required environment variables. + + + +## Configuration + +The server reads configuration from environment variables. + +| Variable | Required | Default | Notes | +|----------|----------|---------|-------| +| `KOSLI_API_TOKEN` | yes | - | Preferred. `KOSLI_API_KEY` is accepted as a fallback. | +| `KOSLI_ORG` | yes | - | Default org used when a path parameter `org` is not supplied. | +| `KOSLI_BASE_URL` | no | `https://app.kosli.com` | Use `https://app.us.kosli.com` for US, or your single-tenant endpoint. | + +## Example prompts + +Once connected, try prompts like: + +- "List the environments in my org and tell me which are compliant." +- "Show me the last 5 deployments to prod-aws." +- "What attestations are on trail `release-456` in flow `my-release`?" +- "Create a new flow called `payments-api`." + +Read prompts run without confirmation. Write prompts (create, update, delete) require an approval step in the MCP client. + +## Limitations + +- The catalog is generated from a snapshot of the OpenAPI spec. New endpoints land when the catalog is regenerated and a new package is published. +- LLM clients may need several `search_actions` calls before settling on the right action ID for ambiguous queries. +- Response shapes are whatever the Kosli API returns. Use the `fields` parameter on execute calls to trim large responses. + +## Feedback + +Tell us what you think - email [support@kosli.com](mailto:support@kosli.com) or open an issue at [`kosli-dev/mcp-server`](https://github.com/kosli-dev/mcp-server/issues). diff --git a/snippets/kosli-next-banner.mdx b/snippets/kosli-next-banner.mdx new file mode 100644 index 0000000..6c0febe --- /dev/null +++ b/snippets/kosli-next-banner.mdx @@ -0,0 +1,15 @@ +export const ConceptBanner = () => ( + + This is a concept and not available in Kosli today. We're sharing it to gather your feedback.

+ Email{' '} + support@kosli.com with your thoughts. + +); + +export const PreviewBanner = () => ( + + This is a preview feature, available to opt-in customers.

+ Share feedback at{' '} + support@kosli.com. + +); diff --git a/style.css b/style.css index f8bd7fe..50f3529 100644 --- a/style.css +++ b/style.css @@ -15,3 +15,20 @@ background-color: #CFD8FF !important; color: #111A26 !important; } + +/* ─── Kosli Next page tags ─────────────────────────────────────────────────── */ +/* + * Recolor the sidebar "Concept" and "Preview" tag pills to match the + * Kosli Next callout colour, so the future-state signal is consistent + * between the sidebar tag and the on-page banner. + */ +[data-nav-tag="Concept"] { + background-color: #FFB4AA !important; + color: #111A26 !important; +} + +[data-nav-tag="Preview"] { + background-color: #B4C5FF !important; + color: #111A26 !important; +} +