agentleFS
aiqadamaiqadam/qadam-flow/AGENTS.md

qadam-flow

AGENTS.md5 starsChanged 36 days agoMITView on GitHub

Open-source AI-first workflow automation platform. Self-hosted by design. 238 qadams (27 core + 211 community). MCP support. End users install via curl -fsSL https://flow.aiqadam.org/run.sh | sh (POSIX script in repo root). The script downloads docker-compose.yml, generates a fresh .env, pulls ghcr.io/aiqadam/qadam-flow:latest, and brings the stack up on port 8080. Don't reintroduce start.sh — its job is covered by run.sh plus plain docker compose commands. The issue body is the least reliable part of an issue. It was written before anyone…

  • Pipes a download into a shell
  • Reads credentials
  • Installs packages
  • Commits and pushes

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

20 rules. About 0 are common, 4 are distinctive, and 16 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 16

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Before touching anything, run all of these and actually read the output:

    line 27
  2. Distinctive:

    If a ticket turns out to rest on a wrong premise, correct the ticket in a comment before writing code against it.

    line 42
  3. Very specific:

    All agent-facing knowledge lives under .agents/ — the one exception is adr/, which records decisions for humans and agents alike and is …

    line 48
  4. Very specific:

    No EE code in this repo: All features run as CE. Never reintroduce edition gating, paywalls, or EE-only services.

    line 86
  5. Very specific:

    Security: Every endpoint needs securityAccess config.

    line 89
  6. Very specific:

    Multi-server: Use distributedLock, BullMQ deduplication, or FOR UPDATE SKIP LOCKED for concurrent operations.

    line 91
  7. Very specific:

    Managed PostgreSQL: No custom extensions. Use sanitizeObjectForPostgresql() for external data.

    line 92
  8. Very specific:

    Before modifying a module: Read its .agents/features/<name>.md file for entities, services, and integration details.

    line 93
  9. Very specific:

    When running in --mode=cloud, do not use OAuth2 connections — the OAuth provider will redirect back to flow.aiqadam.org after sign-in …

    line 168
  10. Very specific:

    Verify before pushing, don't eyeball the message — and check the whole branch, not just HEAD, because the job checks every non-merge commit …

    line 192
  11. Very specific:

    Keep --no-merges — the job passes it too, so an unsigned merge commit from a branch update is not a failure and must not be treated as one.

    line 195
  12. Distinctive:

    Every line must show the sign-off matching that commit's own author.

    line 197
  13. Very specific:

    Always prefix git push with RUN_CHECKS=yes to auto-approve the pre-push lint/test gate, e.g.

    line 202
  14. Very specific:

    When creating a PR with gh pr create, always apply exactly one of these labels based on the nature of the change:

    line 210
  15. Very specific:

    If the PR includes any contributions to qadams (integrations under packages/qadams), also add the appropriate qadams label (in addition to …

    line 214
  16. Very specific:

    Before creating or modifying a database migration, always read .agents/skills/db-migration/SKILL.md first, and follow it.

    line 220
  17. Very specific:

    Always run npm run lint-dev as part of any verification step before considering a task complete.

    line 224
  18. Very specific:

    After touching anything under packages/web, also run npm run typecheck — vite build does not type-check, so a type error there surfaces …

    line 231
  19. Distinctive:

    Never review your own work: the agent that wrote the code is the worst reader of it.

    line 257
  20. Very specific:

    Read docs/README.md inside that installed package first, then read the relevant pages from its docs/ directory before changing Turborepo …

    line 283

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

Qadam Flow

Open-source AI-first workflow automation platform. Self-hosted by design. 238 qadams (27 core + 211 community). MCP support.

End users install via curl -fsSL https://flow.aiqadam.org/run.sh | sh (POSIX script in repo root). The script downloads docker-compose.yml, generates a fresh .env, pulls ghcr.io/aiqadam/qadam-flow:latest, and brings the stack up on port 8080. Don't reintroduce start.sh — its job is covered by run.sh plus plain docker compose commands.

Read the whole ticket before you write a line — this is not optional

The issue body is the least reliable part of an issue. It was written before anyone investigated. The comments are where the measurements, the corrections and the already-rejected approaches live, and a closed PR is where the reason something was not done is recorded. Skipping them does not save time; it spends a whole work session reproducing an answer the repo already had.

This has happened. #155's body proposed caching ~/.bun/install/cache. That exact change had already been written, measured on real runners and closed as a net regression in PR #157 — and a local branch ci/issue-155-cache-bun-deps was still sitting in the repo with the same diff. It was rebuilt from scratch anyway, opened as PR #191, and came within one review of merging a step that costs 18 s and saves 7 s. Cause: only the issue body was read.

Before touching anything, run all of these and actually read the output:

gh issue view <n> --comments                       # the body is the hypothesis; comments are the evidence
gh pr list --state all --search "<n> in:title,body" # closed PRs say why an approach was rejected
gh issue list --state all --search "<keyword>"      # a sibling issue may already own this
git branch -a --list '*<n>*'; git worktree list     # someone may already have a tree for it

Then follow the links. Every issue number, PR number, run URL and commit SHA mentioned in the body or in any comment is context someone paid for. Open them. A referenced CI run has the timings that settle a performance claim; a referenced closed PR has the verdict. If a comment contradicts the body, the comment is newer and probably right — and say so explicitly in your PR rather than silently following one of them.

If a ticket turns out to rest on a wrong premise, correct the ticket in a comment before writing code against it. That is not scope creep; it is the cheapest work in the whole session.

Agent knowledge map — single source: .agents/

All agent-facing knowledge lives under .agents/ — the one exception is adr/, which records decisions for humans and agents alike and is binding on both. .claude/{skills,agents,rules} and .cursor/{skills,rules} are git symlinks into it, so each harness's auto-discovery keeps working — never edit a mirror, and never replace one with a real directory; add content under .agents/ only. npm run check-agent-docs fails on either.

PathSizeWhenWhat
AGENTS.md (this file) + per-package AGENTS.md—Every sessionRules every task needs
.agents/features/*.md35–221 lines eachBefore modifying a moduleEntity schemas, services, data flows
.agents/rules/*.md2–105 lines eachEvery session — all of them, alwaysNon-negotiable invariants and process gates (full index below)
.agents/skills/*/SKILL.md12–1100 lines eachBefore the first line of code, whenever the task matches a skill's trigger14 step-by-step workflows. Trigger registry: skill-usage.md
.agents/agents/*.md25–80 lines eachBefore you report a code change complete5 subagent charters. Delegation matrix: agent-delegation.md
.agents/docs/*.mddeep divesOn trigger (see Verification)Verification pitfalls, CI node_modules cache, dependency updates
adr/*.mdone decision eachBefore a change that meets an ADR trigger (listed in adr/README.md)Architecture Decision Records — accepted decisions are binding. Standard, triggers and index: adr/README.md

Every rule, and what it stops you doing

Nothing under .agents/ is optional reading that happens to be filed there. Every rule below is in force in every session:

RuleWhat it stops you doing
adr.mdContradicting an accepted architecture decision, or making a new one without an ADR
agent-delegation.mdShipping code no second agent read, or briefing a subagent from memory
bun-install.mdRunning npm install
data-isolation.mdA query that does not filter by projectId / platformId
edition-safety.mdEdition gating, and copying upstream EE-licensed source
entity-registration.mdShipping an entity TypeORM never discovers
environment.mdAP_ENVIRONMENT=TESTING, which silently disables every test branch
read-the-ticket.mdWriting code against an issue body you did not finish reading
safe-http.mdAn unfiltered outbound request (SSRF)
skill-usage.mdRe-deriving a workflow a skill already encodes
versioning.mdShipping a change to a versioned package at the wrong level, or without the version change its consumers rely on

Architecture (Non-Obvious Rules)

  • Multi-tenant: Platform → Projects → Users. ALL queries MUST filter by projectId or platformId.
  • No EE code in this repo: All features run as CE. Never reintroduce edition gating, paywalls, or EE-only services. Never create an ee/ directory.
  • Entity registration: New entities MUST be added to getEntities() in database-connection.ts — TypeORM does NOT auto-discover.
  • HTTP: POST for all create/update mutations. DELETE for deletes. Never PUT/PATCH. One sanctioned exception: PUT /v1/files/:fileId in packages/server/api/src/app/file/files-controller.ts — it is the engine's file-upload wire protocol (packages/server/engine/src/lib/engine-file-api.ts) and the method the S3 signed-URL redirect it falls through to also requires, so changing it means a lockstep server+engine break for no user-visible gain. Don't add a second exception.
  • Security: Every endpoint needs securityAccess config.
  • Side effects: Separated into *-side-effects.ts files, called explicitly after mutations — except effects that must commit atomically with the mutation: those are registered as hooks (*-hooks.ts) and invoked inside the mutation's own transaction, never from a controller.
  • Multi-server: Use distributedLock, BullMQ deduplication, or FOR UPDATE SKIP LOCKED for concurrent operations.
  • Managed PostgreSQL: No custom extensions. Use sanitizeObjectForPostgresql() for external data.
  • Before modifying a module: Read its .agents/features/<name>.md file for entities, services, and integration details.

Coding Conventions

  • No any type — Use proper type definitions or unknown with type guards
  • No type casting — Do not use as SomeType to force types. If you encounter an unnecessary cast, remove it.
  • No deprecated APIs — Before using any library method or export, check its JSDoc. If it carries a @deprecated tag, use the recommended replacement instead. Examples: prefer z.enum over z.nativeEnum.
  • Go-style error handling — Use tryCatch / tryCatchSync from @aiqadam/shared (in qadams: from @aiqadam/qadams-framework)
  • Zod error messages must be i18n keys — Every .min(), .refine(), .superRefine(), etc. that surfaces a user-facing message must pass a string that exists as a key in packages/web/public/locales/en/translation.json. For common messages (e.g. required fields) use the formErrors constant from @aiqadam/shared. Add a new translation key if none fits; never use raw English sentences that are not in the translation file.
  • Published-package version bumps — every version number in this repo is a semver promise to a named consumer (ADR-0001, ADR-0002). What each number means, the caret-range promise, compatibility floors and the framework support window are in .agents/rules/versioning.md; choosing and applying a level is the versioning skill. A change that alters what packages/shared, packages/qadams/framework, packages/qadams/common or a qadam ships (its src/ or its own package.json) adds a .changeset/*.md naming that package and its level — CI gate 1 only detects src/ and dependency-section changes, so a manifest or build-config change that alters the tarball needs one too, while a README, test or AGENTS.md-only edit needs none; only the release PR raises version, and gates 1–7 in CI enforce the changeset, the level, the registry and the floors.
  • Helper functions — Define non-exported helpers outside of const declarations
  • Named parameters — Always use a single destructured object parameter instead of positional arguments. This applies to every function with more than one parameter, regardless of type. It prevents mix-ups at the call site and makes future additions non-breaking.
  • Prefer immutable data flow — Functions should produce data by returning it, not by mutating an array/object the caller passes in. If a helper accumulates results (logs, derived rows, computed bindings), it should build the collection locally and return it — not take a pre-allocated bag the caller will read after. Local mutation inside a function's own body is fine; mutation that crosses the function boundary is not. Build new collections with .map / .filter / .reduce / spread rather than in-place push / splice / property assignment when feasible.
  • File order: Imports → Exported functions/constants → Helper functions → Types. Types (exported or not) go at the end of the file, after all logic — the public type contract sits in one predictable place. Exported constants go at the top, right after imports: the namespace-const pattern (services, utils, repos) is the file's table of contents, not something to bury at the bottom (server canon: STYLE.md).
  • Sanctioned file-order exceptions (audit across the monorepo, do not stretch them): a zod schema's z.infer type may sit adjacent to its schema (paired or grouped with sibling schemas); a small local type may sit directly above its only consumer; a trailing enum after a type block is fine in shared domain files. These are idioms the codebase uses deliberately — they are not license to move types wholesale back up a file.

    // imports
    import { isNil } from '@aiqadam/shared'
    
    // exported namespace / constants — top, after imports
    export const flowService = (log: FastifyBaseLogger) => ({ /* ... */ })
    
    // helpers — unexported
    const lockFlowVersionIfNotLocked = async ({ /* ... */ }) => { /* ... */ }
    
    // types — end of file
    export type CreateParams = { projectId: ProjectId; /* ... */ }
  • Comments — Only comment to explain why something is done, never what the code is doing. Code should be self-explanatory; comments that restate the code add noise and rot.
  • Util file exports — When a util file exposes multiple plain functions or constants (non-React), do not export them individually. Instead, group them into a single named const and export that one object (e.g. export const myUtils = { fn1, fn2 }). Callers use myUtils.fn1() at the call site. React components in the same file should be named exports (e.g. export function MyAlert() or export const MyAlert = …) and imported by name — do not bundle them into a wrapper object for the sake of this rule.
  • Safe outbound HTTP (SSRF) — For any outbound HTTP in packages/server/{api,worker,utils}, use safeHttp.axios / safeHttp.createAxios({ ... }) from @aiqadam/server-utils, or safeHttp.fetch when a library takes a fetch override and nothing else. Never use raw fetch or axios.create for URLs that come from user input, admin config, OAuth endpoints, or third-party integrations — they bypass the SSRF filter (private/loopback/metadata IPs). See .agents/rules/safe-http.md.
  • i18n keys are four-locale by definition — a key added to packages/web/public/locales/en/translation.json needs an actual ru/uz/kk translation in the same PR. npm run check-i18n enforces key parity, non-empty values, ICU-argument preservation and exact key sets (--fix prunes stale keys); tools/ci/i18n-allowlist.json records the deliberate exceptions. See docs/about/i18n.mdx.
  • An action that calls waitForWaitpoint declares pauses on createAction — true when every execution waits, 'conditional' when it depends on the step's configuration. Creating a waitpoint is not pausing (create_approval_links carries no marker). ap_validate_flow's inline_pause check reads the marker off the pinned version's metadata (#426), and npm run check-pause-markers (tools/ci/check-pause-markers.mjs, in CI) fails on a waiting action without it, on a consumer of a waiting common/ helper without it, and on a stale marker where nothing waits. Never extend LEGACY_PAUSING_ACTIONS in ap-validate-flow.ts instead — it is frozen to pins that predate the marker.
  • A StaticDropdown/StaticMultiSelectDropdown prop's own defaultValue must be one of its own declared options — the builder seeds every form field from defaultValue, and the server accommodates a prop's own default even when it's absent from the prop's own option list (so the form isn't rejected outright), but that just pushes the mismatch downstream to whatever reads the resolved value — see #427's NocoDB (|| 3 masked it) and CSV (csv-parse threw on it) cases. npm run check-dropdown-defaults statically scans packages/qadams/{community,core,common} for this and runs in CI; it only catches a literal defaultValue against a literal options array, so a dynamically-built dropdown (.map(), an imported constant) is on you to get right by hand. If the value is a deliberate "unset" sentinel (e.g. '' on an optional filter with no natural default, or null), drop defaultValue entirely rather than adding a fake option for it.

Query Error Handling

  • Global error dialog via meta — app.tsx has a QueryCache.onError handler that shows an error dialog when query.meta?.showErrorDialog is truthy. When adding a new useQuery that fetches primary page data (e.g. table rows, list data), add meta: { showErrorDialog: true } to the query options.
  • Do NOT add showErrorDialog to minor/auxiliary queries (feature flags, qadam metadata, single-item fetches, filter options, user details). These should fail silently.
  • Rule of thumb: if the query failure would leave the user staring at an empty table or blank page with no explanation, it should have meta: { showErrorDialog: true }.

Key Utilities (@aiqadam/shared)

apId(), tryCatch(), tryCatchSync(), isNil(), spreadIfDefined(), spreadIfNotUndefined(), QadamFlowError({ code, params }), SeekPage<T>, formErrors, BaseModelSchema, chunk(), partition(), unique(), omit(), sanitizeObjectForPostgresql()

Testing

npm run test-unit     # Vitest, unfiltered: `turbo run test` — every package declaring a `test` script
npm run test-api      # CE API integration + migration check (this repo has no EE or Cloud suite)

API tests: setupTestEnvironment() + createTestContext(app) → ctx.post(), ctx.get(). DB auto-cleaned between tests.

  • AP_ENVIRONMENT valid values are prod / dev / test (the ApEnvironment enum). The test env is test, NOT TESTING. Beware the footgun: ApEnvironment.TESTING === 'test' but the unrelated RunEnvironment.TESTING === 'TESTING' — using TESTING for AP_ENVIRONMENT silently disables every environment === ApEnvironment.TESTING branch. Startup now throws on an invalid value. See .agents/rules/environment.md.
  • CE integration tests share one Postgres DB, so they must run serially — test-ce-command passes --no-file-parallelism. Don't re-enable file parallelism for test/integration.
  • Test files are linted too. The api package's lint script covers test/**/*.ts as well as src/, and the CE Integration Tests / Lint + Unit Tests CI jobs enforce it — so test/ code must satisfy the same ESLint rules as src/ (import order, single quotes, no unused vars, no floating promises, …). Two rules are relaxed for test/**/*.ts only, via serverConfigs.api in tools/eslint/server.mjs: no-explicit-any and no-dynamic-delete (tests legitimately poke internals and build negative fixtures). Run npm run lint-dev before finishing — it auto-fixes most test-lint issues.

Commands

This monorepo uses turbo (see turbo.json) as the task runner and bun as the package manager (see packageManager in package.json). There is no Nx — never invoke nx or npx nx.

Install dependencies with bun install. npm install will fail with TypeError: Cannot read properties of null (reading 'matches') in npm's arborist during dedup. The npm run <script> entries below still work because they only delegate to turbo — but the initial install must be bun.

bun install                                     # Install deps (required — npm install fails)
npm start                                       # Setup dev + start all
npm run dev                                     # Frontend + backend
npm run lint-dev                                # Lint with auto-fix (ALWAYS before done)
npm run review                                  # Advisory AI review against .opencodereview/rule.json
npm run check-agent-docs                        # Agent docs wiring gate (run after touching .agents/)
npx turbo run lint --filter=<package>           # Lint a single package, e.g. --filter=web
npx turbo run serve --filter=web -- --mode=cloud # Run local frontend against the cloud backend

When running in --mode=cloud, do not use OAuth2 connections — the OAuth provider will redirect back to flow.aiqadam.org after sign-in instead of your local frontend, breaking the flow. Use API-key / basic-auth connections, or test OAuth2 against a fully local backend.

npm run review is advisory and opt-in: it never runs as part of lint/tests and never blocks by itself. It wraps alibaba/open-code-review (the ocr CLI) — failure points, delegation and the [r]eview hook shape are in CONTRIBUTING.md. .opencodereview/rule.json encodes the conventions in this file for the reviewer — when a convention here changes, update the matching file under .opencodereview/rules/.

Git Commits (DCO)

  • Every commit must be signed off under the Developer Certificate of Origin. Always commit with git commit -s (--signoff) so a Signed-off-by: <name> <email> trailer (taken from user.name/user.email) is added. This is required by GOVERNANCE.md / CONTRIBUTING.md — PRs with un-signed-off commits can't be merged. Keep the Co-Authored-By: trailer as well; both trailers belong at the end of the message.
  • The trailers must sit in one final block with no blank line between them. Git treats only the last paragraph as the trailer block, and the DCO Sign-off job reads sign-offs with git show -s --format='%(trailers:key=Signed-off-by,valueonly)' (.github/workflows/ci.yml). So a message ending in Signed-off-by:, blank line, Co-Authored-By: has no parsed sign-off and fails the required check, even though the line is plainly visible in git log. Correct shape:

    Closes #123
    
    Signed-off-by: Name <email>
    Co-Authored-By: <agent or model that wrote the code> <contact>

    (The Co-Authored-By trailer is harness-specific — keep whatever your harness/model adds, e.g. Co-Authored-By: opencode (GLM) <noreply@example.com>. No hardcoded brand belongs in the template.)

    Verify before pushing, don't eyeball the message — and check the whole branch, not just HEAD, because the job checks every non-merge commit in the PR: git log --no-merges --format='%h %an <%ae> | %(trailers:key=Signed-off-by,valueonly)' origin/main..HEAD. Keep --no-merges — the job passes it too, so an unsigned merge commit from a branch update is not a failure and must not be treated as one. Every line must show the sign-off matching that commit's own author; a blank right-hand side is the failure.

Git Push

  • Always prefix git push with RUN_CHECKS=yes to auto-approve the pre-push lint/test gate, e.g. RUN_CHECKS=yes git push -u origin HEAD. (RUN_CHECKS=lint runs lint plus the i18n check, RUN_CHECKS=n or SKIP_CHECK=1 skips — the latter bypasses the whole hook including the direct-to-main guard.)
  • The hook is not installed in every checkout — check that core.hooksPath is set; a successful gated push from a tree without the hook proves nothing.

Pull Requests

  • When creating a PR with gh pr create, always apply exactly one of these labels based on the nature of the change:
    • feature — new functionality
    • bug — bug fix
    • skip-changelog — changes that should not appear in the changelog (docs, CI tweaks, internal refactors, etc.)
  • If the PR includes any contributions to qadams (integrations under packages/qadams), also add the appropriate qadams label (in addition to the primary label above):
    • area/third-party-qadams — for third-party integrations (most qadams under packages/qadams/community/)
    • area/core-qadams — for core qadams (under packages/qadams/core/)

Database Migrations

  • Before creating or modifying a database migration, always read .agents/skills/db-migration/SKILL.md first, and follow it. This is the loudest instance of the general rule in skill-usage.md, not an exception to it.

Verification

  • Always run npm run lint-dev as part of any verification step before considering a task complete.
  • Touched anything under .agents/, .claude/, .cursor/, adr/ or any AGENTS.md? Run npm run check-agent-docs — it fails on a skill missing from the trigger registry, a charter missing from the delegation matrix, a rule missing from the rules index, a SKILL.md without usable frontmatter, an AGENTS.md routing to a skill or charter that no longer exists, a mirror symlink someone replaced with a real directory, or an ADR that is misnamed, has an invalid status or no deciders, records supersession on one side only, or disagrees with the index in adr/README.md.
  • After touching anything under packages/web, also run npm run typecheck — vite build does not type-check, so a type error there surfaces nowhere else until CI.
  • Before trusting any verification output — especially a command that returned clean — read verification-pitfalls.md. An empty output is not a passing check; several plausible commands here check nothing at all.
  • Touching CI install or caching (bun.lock, turbo inputs, tools/ci/install-deps.sh, the refresh-cache label)? Read node-modules-cache.md first.

Skills and Subagents — Mandatory, Not Optional

This repo ships 14 skills (.agents/skills/) and 5 subagent charters (.agents/agents/). They are not slash commands idling until a user types them; they are how work is done here, and an agent that ignores them is not being efficient, it is re-deriving — badly — an answer the repo already paid for.

  • Task matches a skill's trigger → open that SKILL.md before writing code. The full trigger registry, and what to do when a skill is wrong, is .agents/rules/skill-usage.md.
  • Run the code-quality agent on every code change, and the app-sec agent on anything touching server code, auth, entities, migrations or outbound HTTP — before you report the task complete, not before some later merge. The matrix, the brief format and the read-only rules are .agents/rules/agent-delegation.md. A DO NOT MERGE verdict is blocking.
  • Skipping either is a decision you state out loud — in your reply and in the PR body, with a reason. Silently skipping is the one option these docs do not give you.
  • Never invent a skill or an agent, and never edit a charter, without asking the user. Never review your own work: the agent that wrote the code is the worst reader of it.
  • npm run check-agent-docs enforces the wiring — frontmatter, registry parity, the skills and agents each per-package AGENTS.md routes to, and the .claude/ / .cursor/ mirrors. It runs in CI. It cannot check that you actually used a skill; that part is on you.

White-Labeling & Edition Paths

  • The design skill is the authority on every user-visible surface — colours, logos, spacing, naming. Read .agents/skills/design/SKILL.md before changing one, including in docs/.
  • All customer-facing UI must be white-labeled. Sign-in/signup pages, email templates, logos, and any user-visible branding must use the platform's configured appearance (name, colors, logos) — never hardcode "Activepieces" in user-facing surfaces.
  • Never copy upstream EE source — clean-room reimplement instead. Upstream packages/ee/ (and packages/server/api/src/app/ee) is under the proprietary Activepieces Enterprise License, not MIT; this repo is MIT-only. When restoring a feature that lived under upstream ee/ (API keys, SSO, RBAC, audit logs, git sync), NEVER copy the EE source verbatim (no git show <upstream-sha>:packages/ee/..., no pasting bodies/structure) — that infringes the Enterprise License. Reimplement from behavior only (HTTP contract, schema-as-idea, auth flow); copyright protects the specific source, not the functionality or API. Code already in the MIT core is safe to reuse. See .agents/rules/edition-safety.md.

Useful Links

  • Skill trigger registry — which skill is mandatory when
  • Subagent delegation matrix — which reviewer is mandatory when
  • Database Migrations Playbook
  • Verification Pitfalls
  • CI node_modules Cache
  • Dependency Updates (Renovate) — tool choice, grouping policy, qadam exclusion
<!-- BEGIN:turborepo-agent-rules -->

This is NOT the Turborepo you know

Turborepo configuration, task behavior, and CLI commands can vary between installed versions and may differ from your training data. Resolve the turbo package from this file's directory or relevant workspace; in monorepos, it may not be visible from the repository root. For example, run node -p "require.resolve('turbo/package.json')" from a workspace that depends on turbo.

Read docs/README.md inside that installed package first, then read the relevant pages from its docs/ directory before changing Turborepo configuration or commands. Heed deprecation notices. These bundled docs match the installed package version and are available without network access.

This block is written and re-added by turbo before repository-scoped commands when an AI agent is detected. In the Turborepo source repository, its template is defined in crates/turborepo-cli/src/cli/agent_guidance.rs. Removing the managed block while updates are enabled means a later qualifying invocation will add it again. Set "agentGuidance": false in the root turbo.json or turbo.jsonc to opt out; this does not remove an existing block. Keep the block committed with your work to avoid an uncommitted change on the next agent invocation.

<!-- END:turborepo-agent-rules -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.