Repository navigation
Shared Packages
Canonical source:
docs/04-backend/shared-packages.md— this page is rendered from it on every publish; edit the source.
Reference for the shared npm workspace packages used across the ClawAI backend services.
- shared-types
- shared-constants
- shared-rabbitmq
- shared-auth
- shared-utilities — added 2026-04-26
Package: @claw/shared-types
Path: packages/shared-types/
Purpose: Central type definitions shared across all backend services. Contains enums, event payloads, and authentication types.
All domain enums are defined here and imported by every service. Using raw string literals or service-local enums for these values is forbidden.
| Enum | Values | Used By |
|---|---|---|
UserRole |
ADMIN, OPERATOR, VIEWER
|
Auth, all services via AuthGuard |
UserStatus |
ACTIVE, INACTIVE
|
Auth |
UserLanguagePreference |
EN, AR, DE, ES, FR, IT, PT, RU
|
Auth |
UserAppearancePreference |
LIGHT, DARK, SYSTEM
|
Auth |
ConnectorProvider |
OPENAI, ANTHROPIC, GOOGLE, DEEPSEEK, XAI, LOCAL_OLLAMA
|
Connector, Chat, Routing |
ConnectorStatus |
ACTIVE, INACTIVE, ERROR
|
Connector, Routing |
ConnectorAuthType |
API_KEY, OAUTH, NONE
|
Connector |
ModelLifecycle |
ACTIVE, DEPRECATED, PREVIEW
|
Connector |
RoutingMode |
AUTO, MANUAL_MODEL, LOCAL_ONLY, PRIVACY_FIRST, LOW_LATENCY, HIGH_REASONING, COST_SAVER
|
Routing, Chat |
MessageRole |
USER, ASSISTANT, SYSTEM
|
Chat |
MemoryType |
FACT, PREFERENCE, INSTRUCTION, SUMMARY
|
Memory |
FileIngestionStatus |
PENDING, PROCESSING, COMPLETED, FAILED
|
File |
AuditAction |
LOGIN, LOGOUT, CREATE, UPDATE, DELETE, ACCESS, EXPORT, IMPORT, SETTINGS_CHANGE, CONNECTOR_SYNC, ROUTING_DECISION
|
Audit |
AuditSeverity |
INFO, WARNING, CRITICAL
|
Audit |
LocalModelRole |
ROUTER, FALLBACK_CHAT, REASONING, CODING
|
Ollama |
HealthCheckStatus / ServiceStatus
|
Health check status values | Health |
LogLevel |
DEBUG, INFO, WARN, ERROR
|
All services |
The EventPattern enum defines all RabbitMQ routing keys used across the event bus:
enum EventPattern {
// User events
USER_CREATED = 'user.created'
USER_LOGIN = 'user.login'
USER_LOGOUT = 'user.logout'
USER_ROLE_CHANGED = 'user.role_changed'
USER_DEACTIVATED = 'user.deactivated'
// Message events
MESSAGE_CREATED = 'message.created'
MESSAGE_ROUTED = 'message.routed'
MESSAGE_COMPLETED = 'message.completed'
// Connector events
CONNECTOR_CREATED = 'connector.created'
CONNECTOR_UPDATED = 'connector.updated'
CONNECTOR_DELETED = 'connector.deleted'
CONNECTOR_SYNCED = 'connector.synced'
CONNECTOR_HEALTH_CHECKED = 'connector.health_checked'
// Routing events
ROUTING_DECISION_MADE = 'routing.decision_made'
// File events
FILE_UPLOADED = 'file.uploaded'
FILE_CHUNKED = 'file.chunked'
// Memory events
MEMORY_EXTRACTED = 'memory.extracted'
// System events
AUDIT_EVENT = 'audit.event'
HEALTH_CHECK = 'health.check'
LOG_SERVER = 'log.server'
// Image events
IMAGE_GENERATED = 'image.generated'
IMAGE_FAILED = 'image.failed'
}Type-safe payload interfaces for every event. All extend BaseEventPayload:
interface BaseEventPayload {
timestamp: string;
correlationId?: string;
}| Payload Type | Event Pattern | Key Fields |
|---|---|---|
UserCreatedPayload |
user.created |
userId, email, role |
UserLoginPayload |
user.login |
userId, email, ipAddress?, userAgent? |
UserLogoutPayload |
user.logout |
userId |
UserRoleChangedPayload |
user.role_changed |
userId, previousRole, newRole, changedBy |
UserDeactivatedPayload |
user.deactivated |
userId, deactivatedBy |
MessageCreatedPayload |
message.created |
messageId, threadId, userId, content, routingMode?, forcedProvider?, forcedModel? |
MessageRoutedPayload |
message.routed |
messageId, threadId, selectedProvider, selectedModel, routingMode, fallbackProvider?, fallbackModel? |
MessageCompletedPayload |
message.completed |
messageId, threadId, assistantMessageId, provider, model, inputTokens?, outputTokens?, latencyMs |
ConnectorCreatedPayload |
connector.created |
connectorId, provider, name, userId |
ConnectorUpdatedPayload |
connector.updated |
connectorId, provider, changes |
ConnectorDeletedPayload |
connector.deleted |
connectorId, provider |
ConnectorSyncedPayload |
connector.synced |
connectorId, provider, modelsDiscovered |
ConnectorHealthCheckedPayload |
connector.health_checked |
connectorId, provider, status, latencyMs? |
RoutingDecisionMadePayload |
routing.decision_made |
messageId, threadId, routingMode, selectedConnectorId, selectedModelId, reason, candidateCount |
FileUploadedPayload |
file.uploaded |
fileId, threadId, userId, fileName, mimeType, sizeBytes |
FileChunkedPayload |
file.chunked |
fileId, chunkCount, status |
MemoryExtractedPayload |
memory.extracted |
memoryId, threadId, userId, type, content |
AuditEventPayload |
audit.event |
userId, action, severity, resource, resourceId?, details? |
HealthCheckPayload |
health.check |
serviceName, status, details? |
ServerLogPayload |
log.server |
level, message, serviceName, module?, controller?, service?, action?, requestId?, traceId?, userId?, threadId?, messageId?, connectorId?, provider?, model?, latencyMs?, error fields, metadata? |
The union type EventPayload combines all payload types for generic handler signatures.
| Type | Fields | Purpose |
|---|---|---|
JwtPayload |
sub (userId), email, role, iat?, exp? | JWT token payload structure |
AuthenticatedUser |
id, email, role | Extracted user info attached to requests |
AuthenticatedRequest |
Extends Express Request with user: AuthenticatedUser
|
Typed request object |
PaginationParams |
page, limit | Standard pagination input |
PaginatedResult<T> |
data: T[], meta: { total, page, limit, totalPages } | Standard pagination output |
import {
UserRole,
RoutingMode,
EventPattern,
type MessageCreatedPayload,
type AuthenticatedUser,
type PaginatedResult,
} from '@claw/shared-types';Package: @claw/shared-constants
Path: packages/shared-constants/
Purpose: Shared constant values used across services. Prevents magic numbers and strings.
| Constant | Value | Description |
|---|---|---|
EXCHANGE_NAME |
'claw.events' |
Topic exchange name for all events |
RABBITMQ_QUEUE_PREFIX |
'claw' |
Prefix for queue names |
Queue naming convention: {prefix}.{serviceName}.{eventPattern} (e.g., claw.audit-service.message.completed)
| Constant | Value | Service |
|---|---|---|
AUTH_SERVICE_PORT |
4001 |
Auth |
CHAT_SERVICE_PORT |
4002 |
Chat |
CONNECTOR_SERVICE_PORT |
4003 |
Connector |
ROUTING_SERVICE_PORT |
4004 |
Routing |
MEMORY_SERVICE_PORT |
4005 |
Memory |
FILE_SERVICE_PORT |
4006 |
File |
AUDIT_SERVICE_PORT |
4007 |
Audit |
OLLAMA_SERVICE_PORT |
4008 |
Ollama |
HEALTH_SERVICE_PORT |
4009 |
Health |
IMAGE_SERVICE_PORT |
4012 |
Image |
Note: Client Logs (4010), Server Logs (4011), and File Generation (4013) ports are defined in their respective service configs.
| Constant | Value |
|---|---|
AUTH_SERVICE |
'auth-service' |
CHAT_SERVICE |
'chat-service' |
CONNECTOR_SERVICE |
'connector-service' |
ROUTING_SERVICE |
'routing-service' |
MEMORY_SERVICE |
'memory-service' |
FILE_SERVICE |
'file-service' |
AUDIT_SERVICE |
'audit-service' |
OLLAMA_SERVICE |
'ollama-service' |
HEALTH_SERVICE |
'health-service' |
IMAGE_SERVICE |
'image-service' |
| Constant | Value | Description |
|---|---|---|
API_PREFIX |
'api/v1' |
Global route prefix for all services |
| Constant | Value | Description |
|---|---|---|
DEFAULT_PAGE |
1 |
Default page number |
DEFAULT_PAGE_SIZE |
20 |
Default items per page |
MAX_PAGE_SIZE |
100 |
Maximum items per page |
import {
EXCHANGE_NAME,
API_PREFIX,
DEFAULT_PAGE,
DEFAULT_PAGE_SIZE,
MAX_PAGE_SIZE,
AUTH_SERVICE_PORT,
} from '@claw/shared-constants';Package: @claw/shared-rabbitmq
Path: packages/shared-rabbitmq/
Purpose: RabbitMQ client module with publish/subscribe, automatic retry with exponential backoff, dead-letter queues, and structured logging.
| Export | Type | Description |
|---|---|---|
RabbitMQModule |
NestJS Module | Global dynamic module for RabbitMQ connectivity |
RabbitMQService |
Injectable Service | Publish/subscribe operations with retry + DLQ |
StructuredLogger |
Class | Structured log emission via RabbitMQ |
A @Global() NestJS dynamic module. Two registration methods:
Static registration (forRoot):
@Module({
imports: [
RabbitMQModule.forRoot({
url: 'amqp://user:password@localhost:5672',
serviceName: 'chat-service',
exchangeName: EXCHANGE_NAME, // optional, defaults to 'claw.events'
queuePrefix: RABBITMQ_QUEUE_PREFIX, // optional, defaults to 'claw'
}),
],
})
export class AppModule {}Async registration (forRootAsync):
RabbitMQModule.forRootAsync({
useFactory: (config: AppConfig) => ({
url: config.rabbitmqUrl,
serviceName: 'chat-service',
}),
inject: [AppConfig],
});Injectable service providing publish and subscribe operations.
Configuration Constants:
-
MAX_RETRIES: 3 -- Maximum retry attempts before sending to DLQ -
RETRY_DELAY_MS: 5000ms -- Base delay between retries (multiplied by attempt number) -
MESSAGE_TTL_MS: 86,400,000ms (24 hours) -- Message expiration
Connection Management:
- Auto-connects on module init (
onModuleInit) - Auto-disconnects on module destroy (
onModuleDestroy) - Auto-reconnects on connection close (5-second delay)
- Creates a durable topic exchange on connect
publish(pattern, payload):
await this.rabbitMQ.publish(EventPattern.MESSAGE_CREATED, {
messageId: message.id,
threadId: message.threadId,
userId: message.userId,
content: message.content,
timestamp: new Date().toISOString(),
});Published messages include:
-
pattern-- The event routing key -
data-- The payload object -
timestamp-- ISO 8601 timestamp -
source-- The publishing service name
Message properties:
-
persistent: true-- Survives broker restart contentType: 'application/json'-
expiration-- 24-hour TTL
subscribe(pattern, handler):
await this.rabbitMQ.subscribe(EventPattern.MESSAGE_COMPLETED, async (data: unknown) => {
const payload = data as MessageCompletedPayload;
await this.processCompletion(payload);
});Subscription creates:
-
Dead-letter queue (
{prefix}.{service}.{pattern}.dlq) -- Durable, 24-hour TTL -
Main queue (
{prefix}.{service}.{pattern}) -- Durable, dead-letter routing to DLQ - Binding -- Main queue bound to exchange with pattern as routing key
Retry Behavior:
- On handler failure, message is acked and republished with incremented
x-retry-countheader - Retry delay increases with each attempt:
RETRY_DELAY_MS * (retryCount + 1)(5s, 10s, 15s) - After
MAX_RETRIES(3) exhausted, message is nacked without requeue (sent to DLQ) - Each retry is logged as a warning; DLQ sends are logged as errors
Queue Naming Convention:
Main: claw.audit-service.message.completed
DLQ: claw.audit-service.message.completed.dlq
A logging utility that writes to both the local NestJS Logger and publishes structured log events to RabbitMQ for centralized collection by the Server Logs Service.
Constructor:
const logger = new StructuredLogger(
rabbitMQService, // RabbitMQService instance
'chat-service', // Service name
EventPattern.LOG_SERVER, // Event pattern for log routing
'ChatService', // Optional NestJS Logger context
);logAction(params):
Accepts a StructuredLogParams object with:
| Field | Type | Required | Description |
|---|---|---|---|
level |
LogLevel |
Yes | DEBUG, INFO, WARN, ERROR |
message |
string |
Yes | Log message |
module |
string |
No | Module name |
controller |
string |
No | Controller name |
service |
string |
No | Service class name |
manager |
string |
No | Manager class name |
repository |
string |
No | Repository class name |
action |
string |
No | Action being performed |
route |
string |
No | HTTP route |
method |
string |
No | HTTP method |
statusCode |
number |
No | HTTP status code |
requestId |
string |
No | X-Request-ID correlation |
traceId |
string |
No | Distributed trace ID |
userId |
string |
No | Acting user ID |
threadId |
string |
No | Chat thread ID |
messageId |
string |
No | Chat message ID |
connectorId |
string |
No | Connector ID |
provider |
string |
No | AI provider name |
model |
string |
No | AI model name |
latencyMs |
number |
No | Operation latency |
errorCode |
string |
No | Error code |
errorMessage |
string |
No | Error message |
errorStack |
string |
No | Error stack trace |
metadata |
Record<string, unknown> |
No | Additional metadata |
Behavior:
- Logs locally via NestJS Logger at the appropriate level (error/warn/debug/log)
- Publishes a
ServerLogPayloadto RabbitMQ withtimestampandserviceNameauto-populated - Publishing failures are silently caught -- logging never breaks the service
Usage Example:
this.logger.logAction({
level: LogLevel.INFO,
message: 'Message routed successfully',
action: 'routeMessage',
service: 'RoutingService',
threadId: payload.threadId,
messageId: payload.messageId,
provider: decision.selectedProvider,
model: decision.selectedModel,
latencyMs: elapsed,
});Package: @claw/shared-auth
Path: packages/shared-auth/
Purpose: Authentication and authorization guards plus decorators. Used by all services that need JWT verification and RBAC.
| Export | Type | Description |
|---|---|---|
AuthGuard |
NestJS Guard | JWT token verification |
RolesGuard |
NestJS Guard | Role-based access control |
@Public() |
Decorator | Mark endpoint as public (skip auth) |
@Roles(...roles) |
Decorator | Require specific roles |
@CurrentUser() |
Parameter Decorator | Extract authenticated user from request |
A CanActivate guard that verifies JWT access tokens on every request.
Behavior:
- Checks for
@Public()metadata -- if present, allows request through - Extracts
Authorization: Bearer <token>header - Verifies token using
JWT_SECRETfrom environment - Attaches decoded user info to
request.userasAuthenticatedUser - Throws
UnauthorizedExceptionfor missing/invalid tokens
Error Cases:
- Missing authorization header:
"Missing authorization header" - Invalid format (not Bearer):
"Invalid authorization header format" - Missing token:
"Missing token" - Missing JWT_SECRET:
"Authentication service misconfigured" - Invalid/expired token:
"Invalid or expired token"
Decoded Token Structure:
request.user = {
id: payload.sub, // User UUID
email: payload.email, // User email
role: payload.role, // UserRole enum value
};Registration (typically in AppModule):
@Module({
providers: [
{ provide: APP_GUARD, useClass: AuthGuard },
{ provide: APP_GUARD, useClass: RolesGuard },
],
})
export class AppModule {}A CanActivate guard that checks if the authenticated user has the required role.
Behavior:
- Reads
@Roles()metadata from handler and class - If no roles are required, allows request through
- Checks if
request.user.roleis in the required roles array - Returns
false(403 Forbidden) if user lacks the required role
Example:
@Roles(UserRole.ADMIN)
@Get('admin-only')
async adminEndpoint(): Promise<void> { ... }
@Roles(UserRole.ADMIN, UserRole.OPERATOR)
@Get('staff-only')
async staffEndpoint(): Promise<void> { ... }Marks an endpoint or controller as publicly accessible, bypassing the AuthGuard.
Implementation: Sets isPublic metadata to true via SetMetadata.
Usage:
@Public()
@Post('login')
async login(@Body() dto: LoginDto): Promise<LoginResult> { ... }Common Use Cases:
- Login and refresh token endpoints
- Health check endpoints
- Internal inter-service endpoints
- Client log ingestion endpoint
- SSE stream endpoints
- Ollama generate endpoint
Specifies which UserRole values are required to access an endpoint.
Implementation: Sets roles metadata with the provided roles array.
Parameters: Accepts one or more UserRole enum values.
@Roles(UserRole.ADMIN) // Admin only
@Roles(UserRole.ADMIN, UserRole.OPERATOR) // Admin or OperatorA parameter decorator that extracts the AuthenticatedUser from the request object. Only usable on endpoints that are NOT marked @Public().
Implementation: Creates a parameter decorator via createParamDecorator that reads request.user.
Return Type: AuthenticatedUser ({ id, email, role })
Usage:
@Get('me')
async me(@CurrentUser() user: AuthenticatedUser): Promise<UserProfile> {
return this.authService.getProfile(user.id);
}import { Controller, Get, Post, Body } from '@nestjs/common';
import { Public, Roles, CurrentUser } from '@claw/shared-auth';
import { UserRole, type AuthenticatedUser } from '@claw/shared-types';
@Controller('example')
export class ExampleController {
// Public -- no auth required
@Public()
@Get('health')
async health(): Promise<{ status: string }> {
return { status: 'ok' };
}
// Authenticated -- any logged-in user
@Get('profile')
async profile(@CurrentUser() user: AuthenticatedUser): Promise<unknown> {
return this.service.getProfile(user.id);
}
// Admin only
@Roles(UserRole.ADMIN)
@Post('admin-action')
async adminAction(@CurrentUser() user: AuthenticatedUser): Promise<void> {
return this.service.performAdminAction(user.id);
}
}Package: @claw/shared-utilities
Path: packages/shared-utilities/
Added: 2026-04-26 (Phase C-1 of the codebase-wide refactor)
Purpose: Cross-service utility functions. The third "shape" alongside shared-types (types) and shared-constants (values) — this package owns functions that two or more services need. Eliminates per-service duplicates of the same wrapper code.
| Subdir | Exports | Wraps | Notes |
|---|---|---|---|
jwt/ |
verifyAccessToken<TPayload>(token, secret): TPayload |
jsonwebtoken |
Generic over payload type — services pass their local JwtPayload (or import from @claw/shared-types). Uses JWT_ALGORITHM from @claw/shared-constants. |
http-client/ |
httpRequest(options): Promise<HttpResponse<T>> (fetch) |
globalThis.fetch |
Used by chat / memory / routing flavour. Takes HttpRequestOptions from @claw/shared-types. |
http-client/ |
createHttpClient(config), httpGet<T>(url, cfg?), httpPost<T>(url, body?, cfg?)
|
axios |
Used by image / ollama / file-gen / file / health flavour. Defaults to DEFAULT_HTTP_TIMEOUT from @claw/shared-constants. |
safe-stringify/ |
safeStringify(value): string |
JSON.stringify |
Recursively redacts password, token, apiKey, apikey, refreshToken, accessToken, secret, authorization, cookie, clientSecret before stringifying. Use in logger.debug() calls when input may contain auth material. |
| Service | JWT verifier | HTTP client | crypto / url-safety |
|---|---|---|---|
| auth | ✅ signAccessToken + signRefreshToken are auth-local; verifyAccessToken delegates to shared. |
n/a | ⏳ pending |
| chat | ✅ | ⏳ pending | n/a |
| connector | ✅ | n/a | ⏳ pending |
| memory | ✅ | ⏳ pending | n/a |
| ollama | ✅ | ⏳ pending | n/a |
| routing | ✅ | ⏳ pending | n/a |
| image | ✅ | ⏳ pending | n/a |
| file-generation | ✅ | ⏳ pending | n/a |
| file | ✅ | n/a | n/a |
| audit | ✅ | n/a | n/a |
| client-logs | ✅ | n/a | n/a |
| server-logs | ✅ | n/a | n/a |
| health | n/a | ✅ axios wrapper redirects | n/a |
| agent | ❌ uses custom JWT (audience/issuer/scopes) — intentionally NOT deduped | n/a | n/a |
| workspace | ❌ no jwt.utility.ts
|
n/a | ⏳ pending |
| research | n/a | ⏳ pending | ⏳ pending |
When adopting @claw/shared-utilities, services keep a 4-line typed wrapper at src/common/utilities/jwt.utility.ts so every consumer (auth guards, etc.) keeps importing from @common/utilities — this avoids touching dozens of call sites:
// apps/<service>/src/common/utilities/jwt.utility.ts
import { verifyAccessToken as verifyAccessTokenGeneric } from '@claw/shared-utilities';
import { type JwtPayload } from '../types';
export function verifyAccessToken(token: string, secret: string): JwtPayload {
return verifyAccessTokenGeneric<JwtPayload>(token, secret);
}The actual jsonwebtoken library call now lives exactly once in packages/shared-utilities/src/jwt/jwt-verifier.utility.ts. The per-service file is just a typing adapter.
The package skeleton is designed to grow. Reserved sub-packages for future phases:
-
crypto/— AES-256-GCM encryption (currently duplicated in auth / connector / research / workspace) -
url-safety/— URL parsing + SSRF blocklists (currently duplicated in research + workspace) -
retry-policy/— exponential backoff + jitter -
pkce/— OAuth 2.1 PKCE helpers (currently in workspace only, but research will need it)
- Add to
apps/<service>/package.jsondependencies:"@claw/shared-utilities": "*" - Run
npm installfrom monorepo root. -
Add to
.github/workflows/ci.yml"Build shared packages" step — see footgun below. - Import from
@claw/shared-utilitiesin code.
The CI workflow has a "Build shared packages" step that compiles each package's dist/ before service typecheck/test/build runs. When a new shared package is added, all four jobs (lint / typecheck / test / build) must include the new compile line, otherwise consumer services fail with Cannot find module '@claw/shared-utilities' even though the package is in package-lock.json. Local builds work because node_modules/@claw/<pkg> symlink + dist/ are populated by the developer's npm run build.
The workflow step now reads:
- name: Build shared packages
run: |
cd packages/shared-types && npm run build
cd ../shared-constants && npm run build
cd ../shared-utilities && npm run build
cd ../shared-rabbitmq && npm run build
cd ../shared-auth && npm run build
cd ../shared-entitlements && npm run buildThis rule is now codified in rules/05-infra-rules.md and rules/09-refactor-rules.md.
shared-types ─────────┬─> shared-utilities ─> shared-auth
├─> shared-rabbitmq
└─> shared-entitlements
shared-constants ────┴─> shared-utilities / shared-rabbitmq
All services use only the shared packages they declare. In particular,
shared-auth depends on shared-utilities, so a clean build must compile
utilities before auth.
When modifying shared packages, rebuild in dependency order:
-
shared-typesandshared-constants(independent, can build in parallel) -
shared-utilities(depends on shared-types and shared-constants) -
shared-rabbitmq(depends on shared-types and shared-constants) -
shared-auth(depends on shared-types and shared-utilities) -
shared-entitlements(depends on shared-types) - All service packages (depend on the shared packages above)
The CI workflow .github/workflows/ci.yml enforces this order — if you add a new shared package, you MUST update the "Build shared packages" step in all four jobs (lint / typecheck / test / build).
ClawAI Wiki · source-controlled under wiki/ · generated/mirrored from the current repository knowledge layer.
ClawAI Wiki
Product
- Product-Vision
- Flagship-Features
- Business-Overview
- Requirements-Register
- Drift-Log
- Runtime-Managed-Connector-Providers
- Threads
- ADR-Index
Architecture
- System-at-a-Glance
- Architecture-Map
- System-Architecture
- Message-Flow
- End-to-End-Data-Flow
- Routing-Engine
- Event-Bus
- Security-Architecture
Platform
- Backend-Services
- Frontend-Architecture
- Shared-Packages
- Database-Reference
- API-Reference
- Provider-Catalog
- Memory-and-Context-Architecture
- File-Support-Architecture
- Research-and-Web-Crawling
Runtime & Ops
- Docker-Guide
- Nginx-Reference
- CI-CD-Pipeline
- Logging-and-Observability
- Operational-Runbooks
- Troubleshooting
Quality
Engineering OS
- AI-Native-Engineering-OS
- Generated-Manifests
- Rules-Catalog
- Skills-Catalog
- Context-Layer
- Engineering-Memory
- Tooling-and-Automation
- Scripts-and-Operations
- ESLint-and-Architecture-Enforcement
- Extended-Work-Skills
Agents
Reference