diff --git a/.gitignore b/.gitignore index 462060d9..683c6d51 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ _* TODO.txt **/.env **/id_rsa* +.agent +.claude +CLAUDE.md .task/ attic.txt **/venv/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..1ba51323 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,147 @@ +# Apache OpenServerless Task Agent Guidelines + +This file provides instructions for agentic coding agents working in this repository. + + +## Setup commands + +- Install Dependencies: `bun install` +- Start development server: `` +- Build the configurator utility: `cd util/config/configurator && bun run build` + +## Testing instructions +- Run tests: `bun test` + +- Run a single test: `bun test util/config/configurator/tests/index.test.ts` +- Run tests with verbose output `bun test --reporter=verbose` + +## Running the application +- Run the configurator utility: `cd util/config/configurator && bun run start` +- Run the configurator utility with a specified configuration file: `bun run start -- ` +- Run the configurator utility with a specified configuration file overriding existing values: `bun run start -- [--override]` + + +## Code style + +- TypeScript strict mode + +### Language & Version +- Primary language: TypeScript +- Runtime: Bun (Node.js compatible) +- Target ES version: ES2022+ +- Module system: ES Modules (`"type": "module"` in package.json) + +### File Organization +- TypeScript files: `.ts` extension +- Test files: `*.test.ts` located in `__tests__` or `tests` directories +- Configuration: TOML (`.toml`) or JSON (`.json`) +- Operations definitions: YAML (`.yml`) + +### Imports +1. **Order**: + - Built-in Node.js/Bun modules (e.g., `import { $ } from "bun";`) + - Third-party libraries (e.g., `import { select } from "@clack/prompts";`) + - Local application files (relative paths) + +2. **Syntax**: + - Use ES module syntax: `import { foo } from "bar";` + - Default imports: `import foo from "bar";` + - Avoid `require()` syntax + +3. **Specific Rules**: + - Import types separately when needed: `import type { TypeName } from "./types";` + - Group related imports together + - No unused imports allowed + +### Formatting +- **Indentation**: 2 spaces (not tabs) +- **Line length**: Maximum 100 characters (prefer 80-100) +- **Semicolons**: Required (use semicolons to terminate statements) +- **Quotes**: + - Single quotes (`'`) for strings + - Template literals (`` ` ``) for multi-line or interpolated strings + - Double quotes (`"`) only when required by JSON or external specifications +- **Commas**: Trailing commas in multi-line objects/arrays +- **Braces**: + - Opening brace on the same line as the statement + - Closing brace on its own line + - No braces for single-line conditionals when it improves readability + +### Types +- **Type Annotations**: + - Always annotate function parameters + - Annotate return values for public functions + - Use type inference for local variables when obvious +- **Interfaces vs Types**: + - Use `interface` for object shapes that may be extended + - Use `type` for unions, primitives, complex mapped types +- **Strictness**: Enable strict TypeScript options (null checks, no implicit any, etc.) + +### Naming Conventions +- **Files & Directories**: kebab-case (e.g., `configurator.ts`, `all-config-parameters.toml`) +- **Variables & Functions**: camelCase (e.g., `readPositionalFile`, `isInputConfigValid`) +- **Constants**: UPPER_SNAKE_CASE (e.g., `HelpMsg`, `AdditionalArgsMsg`) +- **Types & Interfaces**: PascalCase (e.g., `OpsConfig`, `PromptData`) +- **Classes**: PascalCase (though minimal class usage in this codebase) +- **Boolean Variables**: Prefix with `is`, `has`, `should`, `can` (e.g., `isValid`, `hasError`) + +### Error Handling +- **Early Returns**: Handle error conditions first with early returns +- **Async Functions**: Use try/catch for async operations that can fail +- **Bun Specific**: + - Use `process.exit(1)` for error exits + - Use `process.exit(0)` for successful exits + - Check `success` property on result objects from utils +- **Messages**: + - Export constant error messages (as seen with `HelpMsg`, `NotValidJsonMsg`, etc.) + - Use descriptive, user-friendly error messages + - Log warnings with `console.warn()`, errors with `console.error()` + +### Specific Patterns from Codebase +- **Configuration Validation**: Separate validation functions (e.g., `isInputConfigValid`) +- **File Operations**: + - Read β†’ Parse β†’ Validate pattern + - Return objects with `{ success: boolean, message?: string, ...data }` shape +- **CLI Argument Parsing**: Use `util.parseArgs` with strict mode and positionals +- **Interactive Prompts**: Use `@clack/prompts` with proper cancellation handling +- **Shell Commands**: Use Bun's `$` helper for shell commands with `.quiet()` to suppress output + +### Testing +- **Framework**: Bun's built-in test framework (`bun:test`) +- **File Naming**: `*.test.ts` +- **Structure**: + - Use `describe()` for test suites + - Use `test()` for individual tests + - Use `expect()` for assertions +- **Mocking**: Minimal mocking; prefer testing actual behavior +- **Async Tests**: Return promises or use `async`/`await` + +### Comments +- Use JSDoc-style comments for public APIs +- Use `//` for inline comments explaining why (not what) +- Keep comments up-to-date; delete outdated comments +- TODO comments should include GitHub issue references when possible +- When adding bash scripts in the documentation, always keep commands separate (one command per ```bash section) + +### Security +- Never log secrets or credentials +- Use `password` prompt type for sensitive inputs +- Validate and sanitize all external inputs +- Follow the principle of least privilege + +## Task Tracking + +For any task that involves more than one non-trivial step (multi-file changes, investigations with uncertain outcomes, features spanning multiple components), maintain a TODO list using the `TaskCreate` / `TaskUpdate` / `TaskList` tools: + +1. **Start**: call `TaskCreate` to create one task entry per step before writing any code. +2. **Progress**: call `TaskUpdate` (status `in_progress`) when starting a step, `completed` when it is done. +3. **Visibility**: after completing a task, call `TaskList` to confirm no steps are left open. + +Keep task titles short and action-oriented ("Add `type` field to ConfigParameter", "Update parseParameter", etc.). +Do **not** create tasks for trivial single-file edits or quick answers. + +## Additional Notes +- This repository uses Bun as its primary runtime/package manager +- Configuration is driven by TOML files and environment variables +- The `opsfile.yml` defines operational tasks but is not part of the main TypeScript codebase +- When modifying the configurator utility, remember to rebuild after changes \ No newline at end of file diff --git a/admin/docopts.md b/admin/docopts.md index dffa3625..19c836f3 100644 --- a/admin/docopts.md +++ b/admin/docopts.md @@ -27,7 +27,7 @@ You can create namespaces and choose which services to enable. ```text Usage: - admin adduser [--all] [--redis] [--mongodb] [--minio] [--postgres] [--milvus] [--storagequota=|auto] + admin adduser [--all] [--redis] [--mongodb] [--minio|--seaweedfs] [--postgres] [--milvus] [--storagequota=|auto] admin deleteuser admin listuser [] admin compact [--ttl=|10] @@ -49,6 +49,7 @@ Usage: --redis enable redis --mongodb enable mongodb --minio enable minio + --seaweedfs enable seaweedfs --postgres enable postgres --milvus enable milvus vector db --storagequota= diff --git a/admin/opsfile.yml b/admin/opsfile.yml index 0898a4ba..415699ce 100644 --- a/admin/opsfile.yml +++ b/admin/opsfile.yml @@ -119,17 +119,18 @@ tasks: fi fi - if {{.__minio}} || {{.__all}} + if {{.__minio}} || {{.__seaweedfs}} || {{.__all}} then - if $OPERATOR_COMPONENT_MINIO + if $OPERATOR_COMPONENT_MINIO || $OPERATOR_COMPONENT_SEAWEEDFS then MINIO_DATA_ENABLED=true MINIO_STATIC_ENABLED=true else - die "Error! Minio is not enabled in OpenServerless" + die "Error! Minio or Seaweedfs are not enabled in OpenServerless" fi fi + if test -n "{{.__storagequota}}" then MINIO_STORAGE_QUOTA={{.__storagequota}} fi diff --git a/bun.lock b/bun.lock new file mode 100644 index 00000000..db01606d --- /dev/null +++ b/bun.lock @@ -0,0 +1,46 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "dependencies": { + "@clack/prompts": "^1.0.1", + "js-toml": "^1.0.2", + "toml": "^3.0.0", + }, + }, + }, + "packages": { + "@babel/runtime-corejs3": ["@babel/runtime-corejs3@7.29.0", "", { "dependencies": { "core-js-pure": "^3.48.0" } }, "sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA=="], + + "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@11.1.1", "", { "dependencies": { "@chevrotain/gast": "11.1.1", "@chevrotain/types": "11.1.1", "lodash-es": "4.17.23" } }, "sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw=="], + + "@chevrotain/gast": ["@chevrotain/gast@11.1.1", "", { "dependencies": { "@chevrotain/types": "11.1.1", "lodash-es": "4.17.23" } }, "sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg=="], + + "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.1.1", "", {}, "sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg=="], + + "@chevrotain/types": ["@chevrotain/types@11.1.1", "", {}, "sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw=="], + + "@chevrotain/utils": ["@chevrotain/utils@11.1.1", "", {}, "sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ=="], + + "@clack/core": ["@clack/core@1.0.1", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-WKeyK3NOBwDOzagPR5H08rFk9D/WuN705yEbuZvKqlkmoLM2woKtXb10OO2k1NoSU4SFG947i2/SCYh+2u5e4g=="], + + "@clack/prompts": ["@clack/prompts@1.0.1", "", { "dependencies": { "@clack/core": "1.0.1", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-/42G73JkuYdyWZ6m8d/CJtBrGl1Hegyc7Fy78m5Ob+jF85TOUmLR5XLce/U3LxYAw0kJ8CT5aI99RIvPHcGp/Q=="], + + "chevrotain": ["chevrotain@11.1.1", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.1.1", "@chevrotain/gast": "11.1.1", "@chevrotain/regexp-to-ast": "11.1.1", "@chevrotain/types": "11.1.1", "@chevrotain/utils": "11.1.1", "lodash-es": "4.17.23" } }, "sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ=="], + + "core-js-pure": ["core-js-pure@3.48.0", "", {}, "sha512-1slJgk89tWC51HQ1AEqG+s2VuwpTRr8ocu4n20QUcH1v9lAN0RXen0Q0AABa/DK1I7RrNWLucplOHMx8hfTGTw=="], + + "js-toml": ["js-toml@1.0.2", "", { "dependencies": { "chevrotain": "^11.0.3", "xregexp": "^5.1.1" } }, "sha512-/7IQ//bzn2a/5IDazPUNzlW7bsjxS51cxciYZDR+Z+3Le60yzT0YfI8KOWqTtBcZkXXVklhWd2OuGd8ZksB0wQ=="], + + "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="], + + "xregexp": ["xregexp@5.1.2", "", { "dependencies": { "@babel/runtime-corejs3": "^7.26.9" } }, "sha512-6hGgEMCGhqCTFEJbqmWrNIPqfpdirdGWkqshu7fFZddmTSfgv5Sn9D2SaKloR79s5VUiUlpwzg3CM3G6D3VIlw=="], + } +} diff --git a/config/docopts.md b/config/docopts.md index a41be77e..54b69bd7 100644 --- a/config/docopts.md +++ b/config/docopts.md @@ -24,13 +24,14 @@ Configure OpenServerless ```text Usage: - config (enable|disable) [--all] [--redis] [--mongodb] [--minio] [--cron] [--static] [--postgres] [--prometheus] [--slack] [--mail] [--affinity] [--tolerations] [--quota] [--milvus] [--registry] + config (enable|disable) [--all] [--redis] [--mongodb] [--minio] [--cron] [--static] [--postgres] [--prometheus] [--slack] [--mail] [--affinity] [--tolerations] [--quota] [--milvus] [--registry] [--seaweedfs] config apihost (|auto) [--tls=] [--protocol=|auto] config runtimes [] config slack [--apiurl=] [--channel=] config mail [--mailuser=] [--mailpwd=] [--mailfrom=] [--mailto=] - config volumes [--couchdb=] [--kafka=] [--pgvol=] [--storage=] [--alerting=] [--zookeeper=] [--redisvol=] [--mongodbvol=] [--etcdvol=] [--mvvol=] [--mvzookvol=] [--pulsarjournalvol=] [--pulsarledgelvol=] + config volumes [--couchdb=] [--kafka=] [--pgvol=] [--storage=] [--alerting=] [--zookeeper=] [--redisvol=] [--mongodbvol=] [--etcdvol=] [--mvvol=] [--mvzookvol=] [--pulsarjournalvol=] [--pulsarledgelvol=] [--seaweedfsvol=] config controller [--javaopts=] [--loglevel=] [--replicas=] + config ingress [--class=] config invoker [--javaopts=] [--poolmemory=] [--timeoutsrun=] [--timeoutslogs=] [--loglevel=] [--replicas=] config limits [--time=