Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 35 additions & 40 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

**Generated:** 2025-01-20T00:00:00Z
**Branch:** main
**Refresh:** reconciled against actual file tree and `plans/*`; verified scheduled event routing, config loader, handler symbols, manual `/zai update-agents` command, action.yml inputs, and test coverage. Fixed stale workflow filenames (replaced nonexistent `code-review.yml` with actual `zai-code-bot.yml`, `zai-agents-init-example.yml`). Confirmed: scheduled test coverage exists (`tests/handlers/scheduled.test.js`, `tests/scheduled-config.test.js`, `tests/repository-context.test.js`, `tests/agents-validation.test.js`); `docs/scheduled-tasks.md` present; README updated with scheduled-tasks section and `/zai update-agents` command.
**Refresh:** reconciled against file tree, code exports, and test coverage. Completed previously-truncated CONVENTIONS/ANTI-PATTERNS/NOTES sections. Fixed stale CODE MAP entry (`calculateTokenBudget` does not exist; replaced with actual `code-scope.js` exports `extractWindow`/`extractTargetBlock`/`extractEnclosingBlock`). Updated auth description: current runtime in `auth.js` authorizes any identifiable user (permissive mode), diverging from `SECURITY.md` collaborator-gating intent. Verified: scheduled pipeline, config loader, handler symbols, manual `/zai update-agents` command, action.yml inputs, and test coverage all match file tree.

## OVERVIEW
JavaScript GitHub Action with three event flows: (1) PR auto-review, (2) collaborator-gated `/zai` PR comment commands, and (3) cron-triggered scheduled tasks (`.zai-scheduled.yml`) that regenerate AGENTS.md files and open PRs. Runtime executes bundled `dist/index.js`; maintained logic lives in `src/index.js` plus modular services in `src/lib/*`.
JavaScript GitHub Action with three event flows: (1) PR auto-review, (2) `/zai` PR comment commands (documented as collaborator-gated per `SECURITY.md`; current runtime in `auth.js` is permissive for identifiable users — see auth note below), and (3) cron-triggered scheduled tasks (`.zai-scheduled.yml`) that regenerate AGENTS.md files and open PRs. Runtime executes bundled `dist/index.js`; maintained logic lives in `src/index.js` plus modular services in `src/lib/*`.

## STRUCTURE
```text
zai-code-bot/
├── src/index.js # Runtime orchestration and event dispatch
├── src/lib/ # Commands/auth/context/comments/api/services
├── src/lib/ # Commands/auth/context/comments/api services
├── src/lib/events.js # Event-type detection incl. `schedule` (cron) routing
├── src/lib/commands.js # `/zai` parser + allowlist (incl. `update-agents`)
├── src/lib/auto-review.js # Large PR batching and synthesis
├── src/lib/changed-files.js # Paginated changed-files fetch (3000 file limit)
├── src/lib/pr-context.js # Shared PR context fetch (files, content at ref, refs)
├── src/lib/code-scope.js # Token-budget calculation for prompt sizing
├── src/lib/code-scope.js # Window/block extraction for prompt scoping
├── src/lib/context.js # Changed-file fetch + truncation/range helpers
├── src/lib/config/scheduled-config.js # Scheduled-task config loader (.zai-scheduled.yml)
├── src/lib/repository-context.js # Real repo context collection (tree + AGENTS.md discovery + key files)
Expand Down Expand Up @@ -49,13 +49,13 @@ zai-code-bot/
| Route events and command execution | `src/index.js` | `run()`, pull_request path, issue_comment command path, schedule path |
| Schedule event detection | `src/lib/events.js` | `getEventType` returns `schedule`; `shouldProcessEvent` always processes cron events |
| Parse commands and enforce allowlist | `src/lib/commands.js` | `/zai` parser, command normalization, help fallback; `update-agents` in allowlist |
| Authorization and fork policy | `src/lib/auth.js` | Collaborator checks and fork-safe behavior |
| Authorization and fork policy | `src/lib/auth.js` | **Current runtime:** `checkAuthorization`/`checkForkAuthorization` authorize any identifiable user (permissive mode). `SECURITY.md` documents the intended collaborator-gating model. Helper functions (`isCollaborator`, `AUTHORIZED_PERMISSIONS`, `isTrustedCommentAuthor`) remain available but are unused in the active auth path. |
| Comment/reaction behavior | `src/lib/comments.js` | Marker-based upsert, threaded reply (`replyToId`), reactions |
| API retry/error handling | `src/lib/api.js`, `src/lib/logging.js` | Retry policy, categorized safe errors |
| Large PR batching and synthesis | `src/lib/auto-review.js` | Batch creation, context limit handling, synthesis prompt |
| Paginated changed-files fetch | `src/lib/changed-files.js` | Handles GitHub's 3000 file API limit |
| Shared PR context fetch | `src/lib/pr-context.js` | `fetchPrFiles`, `fetchFileAtRef`, `resolvePrRefs`; user-safe fallbacks, size limits |
| Token budget calculation | `src/lib/code-scope.js` | Window extraction, enclosing block detection for prompt sizing |
| Code-window extraction for prompts | `src/lib/code-scope.js` | `extractWindow`, `extractTargetBlock`, `extractEnclosingBlock`; deterministic bounds checking |
| Scheduled-task config loading | `src/lib/config/scheduled-config.js` | `loadScheduledConfig`, `getTasksToRun`, `validateAndNormalizeConfig`, `validateAgentsConfig`, `getGistUrl`; scoping fields (`context_paths`/`target_paths`/`exclude_paths`/budgets) |
| Scheduled-task execution | `src/lib/handlers/scheduled.js` | `handleScheduledEvent`, `handleUpdateAgentsTask` (grounded flow: context→prompt→validate→PR), `SCHEDULED_HANDLERS`; see child `src/lib/handlers/AGENTS.md` |
| Repository context for AGENTS.md gen | `src/lib/repository-context.js` | `collectRepositoryContext` (git tree + existing AGENTS.md discovery + key files, budgeted), `renderRepositoryContext` |
Expand All @@ -80,18 +80,20 @@ zai-code-bot/
| `dispatchCommand` | function | `src/index.js` | high | Handler selection and response management |
| `enforceCommandAuthorization` | function | `src/index.js` | medium | Auth gate before command dispatch |
| `parseCommand` | function | `src/lib/commands.js` | high | Command extraction and validation |
| `checkForkAuthorization` | function | `src/lib/auth.js` | medium | Fork-aware security policy |
| `checkForkAuthorization` | function | `src/lib/auth.js` | medium | Fork-aware auth (currently permissive for identifiable users) |
| `buildHandlerContext` | function | `src/lib/context.js` | medium | Shared context for handlers |
| `upsertComment` | function | `src/lib/comments.js` | high | Marker idempotency + threaded reply support |
| `callWithRetry` | function | `src/lib/api.js` | medium | API retry/backoff wrapper |
| `callWithRetry` | function | `src/lib/api.js` | medium | API retry/backoff wrapper with progressive timeout |
| `saveContinuityState` | function | `src/lib/continuity.js` | medium | Hidden state persistence across turns |
| `createReviewBatches` | function | `src/lib/auto-review.js` | medium | Large PR file chunking |
| `fetchAllChangedFiles` | function | `src/lib/changed-files.js` | medium | Paginated file list (3000 limit) |
| `fetchPrFiles` | function | `src/lib/pr-context.js` | medium | PR file list with size limits + fallbacks |
| `fetchFileAtRef` | function | `src/lib/pr-context.js` | medium | File content at base/head ref, sliding-window scoping |
| `resolvePrRefs` | function | `src/lib/pr-context.js` | low | Resolves base/head refs for diff context |
| `MAX_PR_FILES_API_LIMIT` | constant | `src/lib/changed-files.js` | low | GitHub API ceiling (3000) |
| `calculateTokenBudget` | function | `src/lib/code-scope.js` | medium | Token/char budget sizing for prompts |
| `extractWindow` | function | `src/lib/code-scope.js` | medium | Target lines + surrounding window for prompt scoping |
| `extractTargetBlock` | function | `src/lib/code-scope.js` | medium | Exact line-range extraction with validation |
| `extractEnclosingBlock` | function | `src/lib/code-scope.js` | medium | Nearest function/class block around an anchor line |
| `getEventType` | function | `src/lib/events.js` | low | Event-type detection for routing (incl. `schedule`) |
| `shouldProcessEvent` | function | `src/lib/events.js` | low | Event filter; always-process gate for cron events |
| `loadScheduledConfig` | function | `src/lib/config/scheduled-config.js` | low | Parses `.zai-scheduled.yml` task config |
Expand All @@ -114,38 +116,31 @@ zai-code-bot/

## CONVENTIONS
- Edit maintained code in `src/`; do not hand-edit generated `dist/index.js`.
- After source changes, run `npm run build` and commit `dist/index.js` + `dist/licenses.txt`.
- Use marker-based idempotent comments; preserve marker constants and update semantics.
- After source changes, run `npm run build` and commit `dist/index.js` + `dist/licenses.txt` together. CI enforces `dist/` drift.
- Use marker-based idempotent comments (`<!-- zai-code-review -->`, `<!-- zai-progress -->`, `<!-- zai-auth -->`); preserve marker constants and update semantics.
- Command responses should stay threaded to the invoking comment via `replyToId`.
- Keep security posture strict: collaborator/fork checks before command execution, no secret leakage.
- Reactions should reflect lifecycle: acknowledge (`eyes`) → work (`eyes`) → success (`rocket`) / failure (`-1`).
- Return user-safe error messages; never surface raw exceptions, stack traces, or secrets in PR comments.
- Keep prompts bounded via context/code-scope helpers; never pass raw unbounded patches into API calls.
- Keep handlers decoupled from Octokit internals; route GitHub I/O through shared context structures and `pr-context.js`/`comments.js`.
- Prefer pure helpers for parsing/validation and exported wrappers for I/O.
- Return explicit `{ success, error }`-style outcomes where that pattern is already established.

## ANTI-PATTERNS (THIS PROJECT)
- Bypassing authorization/fork checks for command handlers.
- Executing command logic for non-PR issue comments.
- Allowing unbounded context payloads into prompts.
- Asking an LLM to "scan the repo" without providing real repo context (causes hallucinated AGENTS.md — PR #15 bug).
- Committing AGENTS.md output that references files/languages not present in the repo.
- Editing `dist/` manually or shipping source changes without rebuilt artifacts.
- Confusing consumer-facing workflow examples (README snippet) with this repo's own `.github/workflows/` runtime logic.

## UNIQUE STYLES
- Event-first architecture: `src/index.js` orchestrates; `src/lib/*` isolates concerns.
- Reactions communicate command lifecycle (`eyes`/`thinking`/`rocket`/`x`).
- Continuity is encoded with hidden markers in comments, not external storage.

## COMMANDS
```bash
npm install
npm test # vitest run --coverage
npm run build # ncc build src/index.js -o dist --license licenses.txt
npm audit --audit-level=moderate # security audit gate (CI)
```
After source changes: run `npm run build` and commit `dist/index.js` + `dist/licenses.txt` (CI fails on dist drift).
## ANTI-PATTERNS
- Editing `dist/index.js` directly instead of `src/` + rebuild.
- Running handler logic before `enforceCommandAuthorization` completes.
- Posting top-level comments for command replies (breaks conversational threading).
- Passing unbounded diffs/patches into LLM prompts.
- Surfacing raw exception details or internal paths in user-visible comments.
- Introducing hidden coupling between unrelated service modules.
- Creating AGENTS.md files outside the grounded + validated pipeline (`collectRepositoryContext` → `validateGeneratedAgentFiles`).
- Duplicating parser/auth/comment logic that already exists in the services layer.
- Hand-rolling pagination for changed-files (use `fetchAllChangedFiles`; respects 3000-file API ceiling).

## NOTES
- CI (`.github/workflows/ci.yml`) enforces tests, build, dist drift, and security audit across Node 20 + 22.
- No linting/formatting configs (ESLint, Prettier) — rely on code review and CI gates.
- 7 command handlers + scheduled pipeline: `ask`, `review`, `explain`, `describe`, `impact`, `help`, plus `scheduled` (largest handler, drives cron tasks via `.zai-scheduled.yml`).
- Scheduled test coverage: `tests/handlers/scheduled.test.js`, `tests/scheduled-config.test.js`, `tests/repository-context.test.js`, `tests/agents-validation.test.js` (unit-level); end-to-end schedule integration test is still a gap.
- Scheduled-tasks configuration reference: `docs/scheduled-tasks.md`.
- Architecture and invariants catalog: `ARCHITECTURE.md`.
- **Auth divergence:** `src/lib/auth.js` currently authorizes any identifiable user (permissive mode), diverging from `SECURITY.md`'s collaborator-gating model. The collaborator-check helpers (`isCollaborator`, `AUTHORIZED_PERMISSIONS`, `isTrustedCommentAuthor`, `isRepoOwner`) still exist but are unused in the active `checkAuthorization`/`checkForkAuthorization` path. Coordinate with maintainers before tightening or loosening auth behavior.
- **Node 20 runtime:** `action.yml` declares `using: "node20"` with `main: "dist/index.js"`. No `npm install` or build runs in the Actions runner.
- **Z.ai endpoint:** `https://api.z.ai/api/coding/paas/v4/chat/completions`; default model `glm-5.2` (overridable via `ZAI_MODEL`).
- **Test command:** `npm test` → `vitest run --coverage`; coverage uploaded to Codecov.
- **REACTIONS quirk:** `REACTIONS.THINKING` maps to `'eyes'` (there is no native GitHub `thinking` reaction); this is intentional, not a bug.
- **Scheduled tasks for this repo:** `.zai-scheduled.yml` drives weekly Monday AGENTS.md updates targeting `main`; gist command fetched from the URL configured in `defaults.gist_url`.