Imported from eai-support/eai (
AGENTS.md). Install upstream withnpx skills add eai-support/eai. Copyright stays with the author.
AGENTS.md
Feature Test Ownership
- When creating, updating, or removing feature behavior, update the owned tests in the same repo and PR. Do not hand feature testing to
eai-testing-devunless the deployed canary, route/config contract, auth/tenant smoke, or release evidence surface changes. - Broad browser click-through paths belong in the owning frontend repo's Playwright CI/preview suite with controlled fixtures. Keep them out of prod cross-service checks except for stable read-only canaries and monitoring.
- Provider/data oddities belong in provider contract tests, mocked edge-case tests, and safe non-prod live provider smokes owned by the repo that implements the provider surface.
- Entra UI/session/cookie changes require controlled auth UI/session tests in the owning frontend repo. Deployed login-smoke plus role/tenant canaries live in
enterpriseaigroup/eai-testing-dev. - EAI CLI behavior is owned by
eai-support/eaithroughci/eai-cli-tests;eai-testing-devonly keeps deployed read-only CLI canaries and release-observability evidence aligned. - Release/SRP evidence changes must keep CI check names, required-test metadata, coverage mappings, and any
eai-testing-devdispatch aliases in sync before promotion enforcement is tightened.
Project Overview
- Project: eai
- Language: TypeScript
- Package Manager: npm
Object Type Identifier Contract
- Keep the PascalCase source/model
name(for exampleBoardAppUser) distinct from its explicit lowercase kebab-case transportslug(board-app-user). Do not convert every field to one case. - Emitted/persisted
linkTypes[].targetObjectType, runtimetarget_type, path parameters, and governed v4 query fields contain exact stored slugs. - A same-manifest PascalCase relationship target is source shorthand only. The
CLI must resolve it through the target's declared
slugbefore diffing or seeding; it must reject an unresolved model name instead of guessing. - Historical stored slugs are authoritative. Do not silently re-derive, normalize, alias, or rename them.
- App feature code uses the shared SDK for route construction. CLI code must not encourage hand-written v4 resource paths or app-local slugifiers.
Commands
- Build:
npm run build - Lint:
npm run lint - Focused SRP CLI evidence:
npm run test:eai-cli:ci - Release preflight:
npm run release:check
Project Structure
eai/
├── src/
│ ├── index.ts # Entry point, Commander.js program
│ ├── commands/ # Command modules
│ │ ├── init.ts # Scaffold new app
│ │ ├── dev.ts # Local dev server
│ │ ├── login.ts # Auth (login/logout)
│ │ ├── whoami.ts # Auth status
│ │ ├── user.ts # User management
│ │ ├── env.ts # Environment config
│ │ ├── types.ts # Object Type management
│ │ ├── resources.ts # CRUD operations
│ │ ├── tenant.ts # Tenant management
│ │ ├── chat.ts # AI chat workflows
│ │ ├── docs.ts # Document operations
│ │ ├── deploy.ts # Deployment
│ │ ├── verify.ts # Platform checks (verify/doctor)
│ │ ├── gofer.ts # Safe Gofer asset refresh for existing repos
│ │ └── update.ts # CLI updates
│ └── lib/ # Shared library modules
│ ├── api.ts # PlatformAPIClient
│ ├── auth.ts # Entra CIAM auth
│ ├── config.ts # Config loader
│ ├── error-codes.ts # Error code system
│ ├── gofer-refresh.ts # Gofer manifest planning/apply
│ ├── output.ts # Output utilities
│ ├── project-manifest.ts # Project manifest persistence
│ ├── schema-builder.ts # CLI schema introspection
│ └── update-check.ts # Update checker
├── docs-site/ # Docusaurus docs wrapper publishing from .tech-docs
├── .specify/ # Gofer pipeline specs
│ └── specs/
│ └── cli-help-enhancement/
├── package.json # @enterpriseai/cli
├── tsconfig.json # TypeScript strict ESM
├── CLAUDE.md # Workflow instructions
└── AGENTS.md # This file
Code Style
TypeScript Conventions
- Use strict mode (
"strict": truein tsconfig.json) - Use ESM imports (
import/export), neverrequire() - Add explicit return types to all public functions
- Prefer
unknownoverany; use proper type narrowing - Use
readonlyfor properties that should not be reassigned - Prefer interfaces over type aliases for object shapes
CLI Patterns
Command Structure (Commander.js):
import { Command } from 'commander';
export const myCommand = new Command('my-command')
.description('Brief description')
.option('--format <format>', 'Output format (text|json)', 'text')
.option('--simple', 'Plain text output for screen readers')
.action(async (options) => {
// Command logic
});
Error Handling:
import { ErrorCode, exitWithError } from '../lib/error-codes.js';
// Exit with structured error
exitWithError(ErrorCode.E101); // Not logged in
// Exit with context interpolation
exitWithError(ErrorCode.E002, { var: 'BASE_URL_PUBLIC_API' });
// Exit with format awareness
exitWithError(ErrorCode.E201, { url: apiUrl }, options.format);
Output Utilities:
import { success, error, warn, info, symbols } from '../lib/output.js';
success('Operation completed'); // ✓ Operation completed
error('Something went wrong'); // ✗ Something went wrong
warn('Deprecation warning'); // ⚠ Deprecation warning
info('Additional context'); // → Additional context
// Respects --simple flag (ERROR: Something went wrong)
// Respects --no-color flag (no ANSI codes)
// Detects TTY automatically
API Calls:
import { createAPIClient } from '../lib/api.js';
import { getToken } from '../lib/auth.js';
const token = await getToken();
const client = createAPIClient(token);
const result = await client.get('/v4/data/resources/object-types');
Config Loading:
import { loadConfig } from '../lib/config.js';
const config = await loadConfig();
// Returns: { env vars from .env.local, eai.config.ts exports }
Testing
- Write tests for new functionality before marking tasks complete
- Run the full test suite before committing
Git Workflow
- Use conventional commit messages (feat:, fix:, chore:, docs:)
- Create feature branches for new work
- Run tests and linting before committing
Release Workflow
./release.sh <patch|minor|major> "Message"is the canonical human release entrypointrelease.shmust remain aligned with:.github/workflows/release.yml.github/workflows/docs.ymlsrc/commands/update.tssrc/lib/update-check.tsREADME.md
- Every release should refresh
docs-site/static/llms.txt,docs-site/static/llms-full.txt, anddocs-site/static/cli-help.txt - CLI auth, tenant context, command schema, error envelope, PublicAPI, and preview-lifecycle behavior must keep
ci/eai-cli-testsgreen. That check is the repo-owned SRP evidence for the EAI CLI surface. - The release workflow dispatches
eai-testing-devwithservice=eai-clifor deployed read-only schema/error/auth smoke. Keep prod canaries read-only; preview lifecycle is opt-in and cleanup-backed. - npmjs is the primary release/install channel; GitHub Pages static registry is the fallback channel
- Before changing release behavior, verify npmjs and the public fallback
packument still work:
npm view eai-cli version --registry=https://registry.npmjs.org/npm view @enterpriseai/cli version --registry=https://registry.npmjs.org/ --@enterpriseai:registry=https://registry.npmjs.org/curl https://eai-support.github.io/eai/registry/@enterpriseai/cli
- Recommended install is
npm install -g eai-cli - Canonical package install is
npm install -g @enterpriseai/cli - Static fallback install is
npm install -g @enterpriseai/cli --@enterpriseai:registry=https://eai-support.github.io/eai/registry/ - Persistent static fallback setup is
npm config set @enterpriseai:registry https://eai-support.github.io/eai/registry/ --location=user eai updateupgrades the installed CLI package onlyeai gofer refresh --checkpreviews safe repo-local Gofer asset updateseai template checkpreviews app-template and UI drift for existing repos without writing files- Template or UI component changes are not auto-merged; review the preview before copying changes manually
Boundaries
- Do not modify files outside the project scope without approval
- Do not commit secrets, API keys, or credentials
- Do not add dependencies without justification
Core Principles
Workflow Principles
-
Plan First
- Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions)
- If something goes sideways, STOP and re-plan immediately — don't keep pushing
- Use plan mode for verification steps, not just building
- Write detailed specs upfront to reduce ambiguity
-
Use Subagents
- Use subagents liberally to keep main context window clean
- Offload research, exploration, and parallel analysis to subagents
- For complex problems, throw more compute at it via subagents
- One task per subagent for focused execution
-
Self-Improvement
- After ANY correction from the user: update lessons file with the pattern
- Write rules for yourself that prevent the same mistake
- Ruthlessly iterate on these lessons until mistake rate drops
- Review lessons at session start for relevant project
-
Verify Before Done
- Never mark a task complete without proving it works
- Never state anything that you do not know is correct, do not make assumptions, and always cite the latest on the internet or from information you have
- Diff behavior between main and your changes when relevant
- Ask yourself: "Would a staff engineer approve this?"
- Run tests, check logs, demonstrate correctness
-
Demand Elegance
- For non-trivial changes: pause and ask "is there a more elegant way?"
- If a fix feels hacky: "Knowing everything I know now, implement the elegant solution"
- Skip this for simple, obvious fixes — don't over-engineer
- Challenge your own work before presenting it
-
Autonomous Bug Fixing
- When given a bug report: just fix it. Don't ask for hand-holding
- Point at logs, errors, failing tests — then resolve them
- Zero context switching required from the user
- Go fix failing CI tests without being told how
Task Management
- Plan First: Write plan with checkable items before starting
- Verify Plan: Check in before starting implementation
- Track Progress: Mark items complete as you go
- Explain Changes: High-level summary at each step
- Document Results: Add review section to task tracking
- Capture Lessons: Update lessons file after corrections
Core Principles
- Simplicity First: Make every change as simple as possible. Impact minimal code.
- No Laziness: Find root causes. No temporary fixes. Senior developer standards.
- Minimal Impact: Changes should only touch what's necessary. Avoid introducing bugs.
Always-On EAI Contract
Apply this contract to every request after Gofer is installed for this repo or AI coding app. The user does not need to type /eai or $eai.
- Preserve the user's request. Do not rewrite it or add a visible command prefix.
- Treat an explicit
/eaiin Claude, Copilot, Antigravity, Grok, or VS Code, and$eaiin Codex, as an idempotent request for the same contract. - Apply Gofer's Controlled English and business-first response rules.
- Select the internal pipeline stage. Do not make the user select a stage.
- Check workspace health before meaningful repo work, tool use, or a pipeline stage. Do not repeat setup on every message.
- When the user explicitly asks to update Gofer, use its maintenance contract only.