Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

Репозиторий содержит OpenAPI-спецификацию, SDK для 5 языков и AI-скиллы для [Pachca API](https://dev.pachca.com) — API корпоративного мессенджера Пачка. Используйте для автоматизации: отправки сообщений, управления каналами и сотрудниками, настройки ботов, работы с задачами и аудитом событий.

**Документация**: https://dev.pachca.com · **OpenAPI**: https://dev.pachca.com/openapi.yaml · **Changelog**: https://dev.pachca.com/guides/updates · **Postman/Bruno**: https://dev.pachca.com/pachca.postman_collection.json
**Документация**: https://dev.pachca.com · **OpenAPI**: https://dev.pachca.com/openapi.yaml · **Авторизация**: https://dev.pachca.com/guides/authorization · **Changelog**: https://dev.pachca.com/guides/updates · **Postman/Bruno**: https://dev.pachca.com/pachca.postman_collection.json

## Agent Skills

AI-агенты могут использовать скиллы для работы с API Пачки — пошаговые инструкции с curl-примерами, обработкой ошибок и ограничениями.
AI-агенты могут использовать скиллы для работы с API Пачки — пошаговые инструкции с curl-примерами, требуемыми скоупами токена, ограничениями по тарифу и обработкой ошибок.

### Установка (40+ агентов)

Expand Down Expand Up @@ -256,15 +256,15 @@ FlexSearch с `tokenize: 'forward'`. Русский язык: синонимы (

Ссылки резолвятся в реальные URL и рендерятся с method-badge.

### Специальные теги (превращаются в callout-блоки)
### Требования к методам (x-requirements)

- `#admin_access_token_required`
- `#owner_access_token_required`
- `#corporation_price_only`
- `#files_not_supported`
- `#unfurling_bot_access_token_required`
- `#bot_access_token_required`
- `#access_token_not_required`
Ограничения эндпоинтов описываются через `@extension("x-requirements", ...)` в TypeSpec.
Попадают в OpenAPI YAML как `x-requirements` и рендерятся в трёх местах: в UI как бейджи, в Agent Skills рядом с каждой операцией, в per-endpoint `.md`-файлах.

Поля:
- `scope` — требуемый скоуп токена (например `"messages:read"`)
- `plan` — требуемый тариф (например `"corporation"`)
- `auth` — `false` если авторизация не нужна

### MDX компоненты

Expand Down
8 changes: 4 additions & 4 deletions apps/docs/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ html.dark {
--color-background-tertiary: oklch(27.77% 0.0068 240);
--color-background-border: oklch(34% 0.0077 240);

--color-callout-info-bg: oklch(53.91% 0.19 270 / 12%);
--color-callout-info-border: oklch(53.91% 0.19 270 / 20%);
--color-callout-info-header-bg: oklch(53.91% 0.19 270 / 10%);
--color-callout-info-text: oklch(68.4% 0.16 270);
--color-callout-info-bg: oklch(52% 0.22 290 / 12%);
--color-callout-info-border: oklch(52% 0.22 290 / 20%);
--color-callout-info-header-bg: oklch(52% 0.22 290 / 10%);
--color-callout-info-text: oklch(72% 0.18 290);

--color-accent-yellow: oklch(81.1% 0.154 70.7);
--color-accent-green: oklch(75% 0.12 143.5);
Expand Down
69 changes: 59 additions & 10 deletions apps/docs/components/api/endpoint-header.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
'use client';

import Link from 'next/link';

import { MarkdownActions } from './markdown-actions';
import { MethodBadge } from './method-badge';
import { CopyButton } from './copy-button';
import type { EndpointRequirements } from '@/lib/openapi/types';

const planNames: Record<string, string> = {
corporation: 'Корпорация',
};

interface EndpointHeaderProps {
title: string;
pageUrl: string;
method?: string;
path?: string;
requirements?: EndpointRequirements;
}

export function EndpointHeader({ title, pageUrl, method, path }: EndpointHeaderProps) {
export function EndpointHeader({
title,
pageUrl,
method,
path,
requirements,
}: EndpointHeaderProps) {
const fullUrl = typeof window !== 'undefined' ? `${window.location.origin}${pageUrl}` : pageUrl;

const hasBadges =
requirements && (requirements.scope || requirements.plan || requirements.auth === false);

return (
<div className="mb-8">
<h1 className="text-text-primary mb-2!">{title}</h1>
Expand All @@ -22,16 +39,48 @@ export function EndpointHeader({ title, pageUrl, method, path }: EndpointHeaderP
</div>

{method && path && (
<div className="flex items-center justify-between gap-2 px-3 min-h-[var(--boxed-header-height)] rounded-md text-[13px] font-medium text-text-primary border border-background-border bg-background mt-4">
<div className="flex gap-2 items-center overflow-hidden">
<MethodBadge
method={method.toUpperCase() as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'}
/>
<span className="font-mono text-[13px] text-text-primary font-bold truncate">
{path}
</span>
<div className="mt-4 not-prose">
<div className="flex flex-wrap items-center gap-x-2 px-3 rounded-md text-[13px] font-medium text-text-primary border border-background-border bg-background min-w-0">
<div className="flex gap-2 items-center overflow-hidden flex-1 min-w-0 min-h-[var(--boxed-header-height)]">
<MethodBadge
method={method.toUpperCase() as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'}
/>
<span className="font-mono text-[13px] text-text-primary font-bold truncate">
{path}
</span>
</div>
{hasBadges && (
<div className="flex items-center gap-1.5 order-last sm:order-none basis-full sm:basis-auto pb-2 sm:pb-0">
{requirements.auth === false && (
<Link
href="/guides/authorization"
className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[11px] font-semibold bg-[var(--color-callout-info-bg)] ![color:var(--color-callout-info-text)] ![text-decoration:none] hover:opacity-80 transition-opacity"
>
Без авторизации
</Link>
)}
{requirements.scope && (
<Link
href="/guides/authorization#скоупы"
className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[11px] font-semibold bg-[var(--color-callout-info-bg)] ![color:var(--color-callout-info-text)] ![text-decoration:none] hover:opacity-80 transition-opacity"
>
{requirements.scope}
</Link>
)}
{requirements.plan && (
<Link
href="/guides/authorization"
className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[11px] font-semibold bg-[var(--color-callout-warning-bg)] ![color:var(--color-callout-warning-text)] ![text-decoration:none] hover:opacity-80 transition-opacity"
>
{planNames[requirements.plan] ?? requirements.plan}
</Link>
)}
</div>
)}
<div className="shrink-0 min-h-[var(--boxed-header-height)] flex items-center">
<CopyButton text={`[${title} - ${method.toUpperCase()} ${path}](${fullUrl})`} />
</div>
</div>
<CopyButton text={`[${title} - ${method.toUpperCase()} ${path}](${fullUrl})`} />
</div>
)}
</div>
Expand Down
8 changes: 2 additions & 6 deletions apps/docs/components/api/markdown-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import remarkGfm from 'remark-gfm';
import { Callout } from './callout';
import { GuideCodeBlock } from './guide-code-block';
import { InternalLink } from './smooth-scroll-link';
import { replaceSpecialTagsForMDX } from '@/lib/replace-special-tags';
import { toSlug } from '@/lib/utils/transliterate';
import type { Endpoint } from '@/lib/openapi/types';
import { parseOpenAPI } from '@/lib/openapi/parser';
Expand Down Expand Up @@ -183,11 +182,8 @@ export async function MarkdownContent({
// Load endpoints if not provided (for resolving API links)
const endpoints = allEndpoints ?? (await parseOpenAPI()).endpoints;

// 1. Replace special tags with MDX components (<Warning>, <Info>)
let processedContent = replaceSpecialTagsForMDX(content);

// 2. Resolve endpoint links: [description](METHOD /path) -> <EndpointLink> with badge
processedContent = resolveEndpointLinks(processedContent, endpoints, { mdx: true });
// Resolve endpoint links: [description](METHOD /path) -> <EndpointLink> with badge
const processedContent = resolveEndpointLinks(content, endpoints, { mdx: true });

return (
<div className={className}>
Expand Down
1 change: 1 addition & 0 deletions apps/docs/components/api/method-template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function ApiMethodTemplate({
pageUrl={endpoint.url || generateUrlFromOperation(endpoint)}
method={endpoint.method}
path={endpoint.path}
requirements={endpoint.requirements}
/>

{fullDescription && (
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/components/api/schema-tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ export function PropertyRow({ name, schema, required, level, parentPath }: Prope
</MetadataRow>
)}

<EnumValues schema={schema} fieldPath={currentPath} />
<EnumValues schema={schema.items?.enum ? schema.items : schema} fieldPath={currentPath} />
{schema.default !== undefined && (
<MetadataRow label="По умолчанию">
<CodeBadge>
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/ai-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description: Как Пачка работает с AI-агентами и как
- **Треды как единица работы** — каждый тред изолирован, агент видит только его содержимое и отвечает туда же, не загрязняя общий чат
- **Сквозные треды** — упомяните любого сотрудника в треде, и он увидит весь контекст, даже если не состоит в исходном чате. Один тред — единая точка координации между людьми и агентом

<ImageCard src="/images/ai-agent-kai.jpg" alt="Пример работы AI-агента в треде Пачки" caption="Пример работы AI-агента в треде Пачки" />
<ImageCard src="/images/ai-agent-kai.jpg" alt="Пример работы AI-агента в треде Пачки" caption="Пример работы AI-агента в треде Пачки" maxWidth={804} />

<Info>Как мы сделали AI-агента, который живёт в корпоративном мессенджере — [читайте в блоге Пачки](https://pachca.com/blog/ai-agent-v-korporativnom-messendzhere)</Info>

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/audit-events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Отслеживание событий безопасности

# Пачка Audit Events API

#corporation_price_only #owner_access_token_required
<Warning>Доступно только на тарифе **Корпорация**. Для работы с журналом аудита токен должен иметь скоуп `audit_events:read`, доступный только владельцу пространства.</Warning>

`Audit events API` Пачки предоставляет командам безопасности доступ к логам о критически важных событиях в мессенджере. Это позволяет обеспечивать надежный мониторинг и соответствовать требованиям информационной безопасности и регуляторов.

Expand Down
Loading
Loading