Skip to content

Conversation

@maor-rozenfeld
Copy link
Contributor

@maor-rozenfeld maor-rozenfeld commented Nov 20, 2025

Both cursor and GitHub copilot now support the AGENTS.md standard.

JetBrains Junie doesn't support it yet, so I keep a reference for now.

Fixes CI-122.

Copilot AI review requested due to automatic review settings November 20, 2025 13:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR consolidates coding and contribution guidelines from multiple scattered locations into a single canonical AGENTS.md file at the repository root. This centralization improves discoverability and maintainability by providing one authoritative source for development standards.

  • Creates comprehensive AGENTS.md covering code style, testing, Git workflow, and frontend guidelines
  • Replaces .junie/guidelines.md content with a reference to the new file
  • Removes redundant .cursor/rules/coding-guidelines.mdc

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
AGENTS.md New comprehensive guidelines file covering general principles, code style, TypeScript/JavaScript standards, frontend practices, testing, and Git workflow
.junie/guidelines.md Simplified to redirect to AGENTS.md
.cursor/rules/coding-guidelines.mdc Removed as content consolidated into AGENTS.md

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@maor-rozenfeld maor-rozenfeld changed the title Add AGENTS.md Add AGENTS.md for a unified guideline for AI agents Nov 20, 2025
@sonarqubecloud
Copy link

@linear
Copy link

linear bot commented Nov 20, 2025

CI-122 Add AGENTS.md

- [.github/pull_request_template.md](../.github/pull_request_template.md): PR template
- [.github/prlint.json](../.github/prlint.json): PR linting rules
- [docs.openops.com](https://docs.openops.com): Official OpenOps documentation
See AGENTS.md in root folder.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need the same for claude code
anthropics/claude-code#6235

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's unfortunate

- [CONTRIBUTING.md](./CONTRIBUTING.md) - General contribution guidelines
- [.github/pull_request_template.md](./.github/pull_request_template.md) - PR template
- [.github/prlint.json](./.github/prlint.json) - PR linting rules
- [docs.openops.com](https://docs.openops.com) - Official OpenOps documentation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some better prompt, generated by Claude Code:

CLAUDE.md

Common Development Commands

Running the Application

# Start all services (Frontend + API + Engine)
npm run dev

# Start backend only (API + Engine)
npm run dev:backend

# Start frontend only
npm run dev:frontend

# Full start with Docker dependencies
npm start

Building

# Build frontend
npm run build:frontend

# Build all blocks
npm run build:blocks

# Build server worker
npm run build:server-worker

Testing

# Run tests for specific packages
nx test react-ui
nx test ui-components
nx test-unit server-api
nx test engine

# Run linting
nx lint react-ui
nx lint server-api

Block Development

# Create new block
npm run create-block

# Create new action in existing block
npm run create-action

# Create new trigger in existing block
npm run create-trigger

# Sync block metadata to database
npm run sync-blocks

# Publish block to npm
npm run publish-block

Database Migrations

# Create new migration
nx db-migration server-api --name MigrationName

# Migrations run automatically on app startup

Architecture Overview

Monorepo Structure (Nx)

OpenOps uses Nx as a monorepo build system with the following key packages:

  • packages/server/api - Main Fastify-based API server (port 3000)
  • packages/server/worker - BullMQ background job processor
  • packages/server/shared - Shared server utilities (logging, caching, encryption)
  • packages/engine - Isolated workflow execution engine (runs as separate service or AWS Lambda)
  • packages/react-ui - React frontend application (Vite + TailwindCSS)
  • packages/shared - Shared types and utilities across frontend/backend
  • packages/blocks/ - 50+ integration blocks (AWS, Azure, GCP, Slack, etc.)
  • packages/blocks/framework - Base framework for creating blocks/actions/triggers
  • packages/cli - CLI tools for block/action/trigger development
  • packages/ui-components - Reusable UI component library (documented in Storybook)

Three-Tier Architecture

  1. React UI (Frontend)

    • Built with React 18, Zustand, react-query v5, shadcn
    • Communicates with API server via Axios
    • Receives real-time updates via Socket.io
  2. API Server (Fastify)

    • RESTful API endpoints for workflow management
    • WebSocket support (Socket.io) for real-time updates
    • JWT-based authentication, multi-tenancy support
    • Health checks and telemetry (OpenTelemetry)
  3. Engine (Executor)

    • Isolated execution environment for workflows
    • Deploys as Node.js process (dev) or AWS Lambda (production)
    • Executes flows step-by-step with isolated sandboxes
    • Reports progress via WebSocket

Supporting Components

  • Worker: BullMQ-based job processor with three queue types:
    • ONE_TIME: Single workflow executions
    • SCHEDULED: Cron-based recurring workflows
    • WEBHOOK: Event-driven workflow triggers
  • PostgreSQL: Primary database (SQLite3 for development)
  • Redis: Queue backing and Socket.io adapter

Workflow Execution Model

Flow Structure (Graph-based)

Flows are defined as a directed graph:

  • Trigger (entry point) → Actions (linked list with branches)
  • Action types:
    • BLOCK: Execute a plugin action
    • CODE: Execute custom TypeScript code
    • BRANCH: Conditional logic (if/else)
    • LOOP_ON_ITEMS: Iteration
    • SPLIT: Parallel execution

Execution Flow

  1. Trigger receives event/payload
  2. Engine walks through action chain sequentially
  3. Each action produces output stored in execution context
  4. Context accessible to subsequent steps via variable interpolation: {{step.output.field}}
  5. Loop/branch steps can alter execution path
  6. Progress updates sent via WebSocket during execution
  7. Results stored in database with logs

Variable Resolution System

Variables use mustache-style syntax:

  • {{step.output.field}} - Access step outputs
  • {{connections.aws.accessKey}} - Access connection credentials
  • {{store.key}} - Access workflow key-value store
  • {{trigger.payload}} - Access trigger event data

Custom parser in packages/engine/src/lib/resolve-variable.ts handles resolution.

Blocks/Actions/Triggers Plugin System

Block Definition

Blocks are defined in packages/blocks/[block-name]/index.ts:

createBlock({
  displayName: "AWS",
  logoUrl: "...",
  auth: amazonAuth,  // Authentication strategy
  actions: [...],    // Array of actions
  triggers: [...],   // Array of triggers
  categories: [...]
})

Action Definition

createAction({
  name: 'ec2_stop_instance',
  displayName: 'Stop EC2 Instance',
  props: {
    /* input properties */
  },
  run: async (ctx) => {
    /* execution logic */
  },
  requireAuth: true,
  isWriteAction: true,
  riskLevel: RiskLevel.HIGH,
});

Key Patterns

  • Property System: Dynamic properties with validation (dropdowns, text, JSON)
  • Authentication: Pluggable auth providers (OAuth2, API Key, Basic)
  • Context Injection: ActionContext provides auth, props, files, connections
  • Type Safety: Full TypeScript with @sinclair/typebox schemas
  • Block Loading: Dynamic loading from npm packages or file system

Block Development Workflow

  1. Run npm run create-block to scaffold
  2. Define block with actions/triggers
  3. Implement action runners (async functions)
  4. Define properties with validation
  5. Test locally by running npm run dev
  6. Publish to npm (@openops/blocks-* scope)
  7. Sync to database via npm run sync-blocks

Each block package structure:

packages/blocks/[block-name]/
├── index.ts              # Block definition and exports
├── lib/
│   ├── actions/          # Action implementations
│   └── triggers/         # Trigger implementations
└── package.json

Database Architecture (TypeORM)

Primary Entities

  • Flow - Workflow definition (belongs to Project)
  • FlowVersion - Versioned workflow configuration (stores trigger graph as JSON)
  • FlowRun - Execution instance with status/logs
  • AppConnection - Stored credentials for integrations
  • Project - Multi-tenancy isolation
  • User / Organization - Authentication entities
  • TriggerEvent - Webhook events queue
  • StoreEntry - Key-value store for workflows

Database Configuration

  • Production: PostgreSQL 14+ (JSONB for complex data)
  • Development: SQLite3
  • Migrations: TypeORM migrations in packages/server/api/src/app/database/migrations/
  • Connection: Single databaseConnection() singleton with automatic dialect switching

Migrations

  • Located in packages/server/api/src/app/database/migrations/
  • Naming: Timestamp + description (e.g., 1740463047000-InitializePostgresSchema.ts)
  • Run automatically on app startup
  • Idempotent migrations with rollback capabilities

Code Execution Sandbox

  • Engine Mode: Uses isolated-vm package (v8 isolates)
  • Lambda Mode: Separate Lambda invocation
  • Security: No direct filesystem/network access from code steps
  • Dependencies: TypeScript + @types/node available
  • Timeout: Configurable per execution

Real-time Updates (Socket.io)

  • Redis adapter for horizontal scaling
  • Rooms per flow run ID
  • Progress service publishes step completion events
  • Frontend subscribes to specific run IDs
  • WebSocket events for live workflow execution updates

Multi-tenancy

  • Project-based: All resources scoped to Project
  • Enterprise: Additional Organization entity (feature-flagged)
  • Row-level filtering: All queries filtered by projectId
  • Connection isolation: Credentials stored per project

Error Handling Patterns

  • Retry Logic: Exponential backoff for transient failures
  • Continue on Failure: Optional per-step setting
  • Global Timeout: Workflow-level timeout (default 5 minutes)
  • Execution Limits: Max tasks per run to prevent infinite loops
  • Error Context: Detailed error messages with step context

Frontend Guidelines

  • Use the react-ui package for main application logic
  • Place pure, reusable components in the ui-components package, documented in Storybook
  • Tech stack:
    • React 18
    • Zustand (state management)
    • react-query v5 (server state)
    • shadcn (UI components)
    • Axios (we already have a wrapper in api.ts), use qs package for query strings
  • Place and write tests in a separate tests folder
  • Follow best practices for React hooks
  • Prefer small, composable components
  • Use cn utility to group tailwind classnames:
<div
  className={cn(
    'absolute bottom-[-20px] left-1/2 -translate-x-1/2',
    'w-[118px] h-[24px] flex items-center justify-center',
    'font-satoshi font-medium text-xs text-blueAccent-500',
    'border border-solid border-blueAccent-500 rounded-[4px]',
    'bg-background-800',
    {
      'pt-2': !someVar,
    },
  )}
>
  {t('Sample output data')}
</div>

Code Style

  • Indentation: 2 spaces (TypeScript/JavaScript)
  • Line length: 100–120 characters preferred
  • Braces: Required for all control blocks
  • Naming:
    • Variables/Functions: camelCase
    • Classes/Types: PascalCase
    • Constants: UPPER_SNAKE_CASE
    • Files: lowercase with hyphens (e.g., user-profile.ts)
  • TypeScript:
    • Use types and interfaces
    • Prefer const over let or var
    • Use explicit return types for exported functions
  • Tests: Place unit tests alongside code in a tests folder, use Jest
  • Comments: Explain why something is done, not what

Docker Compose (Development)

The compose.yaml file provides:

  • PostgreSQL (port 5432)
  • Redis (port 6379)
  • OpenOps Tables (Baserow fork, port 3001)
  • OpenOps Analytics (Superset fork, port 8088)

Environment Configuration

Configuration managed via .env file with 50+ options. See .env.template for reference.
System properties abstraction layer in @openops/server-shared/system.

Deployment

Docker Images

  • Main App: Dockerfile - API server + Nginx serving React UI
  • Engine: engine.Dockerfile - Lambda-ready with AWS/Azure/GCP CLIs
  • Multi-architecture: Supports AMD64 and ARM64

Production Services

  1. API Server (Fastify app)
  2. Engine (AWS Lambda or standalone process)
  3. Worker (Background job processor)
  4. PostgreSQL (Primary database)
  5. Redis (Queue and caching)
  6. OpenOps Tables (Built-in database UI)
  7. OpenOps Analytics (Built-in BI tool)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit bloated don't you think? A lot of information that might not be relevant. By the way, do you allow the agent to start the application (npm start)? Is there a real use for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants