Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

Full documentation: **[docs.page/vypdev/copilot](https://docs.page/vypdev/copilot)**

*Maintains state and configuration persisted in issue descriptions for seamless workflow automation.*

---

## Documentation index
Expand Down
37 changes: 37 additions & 0 deletions _agent/docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: Architecture
description: Project architecture, entry points, and use case flows.
---

# Architecture & Key Paths

## Entry and main flow

1. **GitHub Action**: `src/actions/github_action.ts` reads inputs, builds `Execution`, calls `mainRun(execution)` from `common_action.ts`.
2. **CLI**: `src/actions/local_action.ts` same flow with CLI/config inputs.
3. **common_action.ts**: Sets up; calls `waitForPreviousRuns(execution)` (sequential workflow); then:
- **Single action** → `SingleActionUseCase`
- **Issue** → `IssueCommentUseCase` or `IssueUseCase`
- **Pull request** → `PullRequestReviewCommentUseCase` or `PullRequestUseCase`
- **Push** → `CommitUseCase`

## Key paths

| Area | Path | Purpose |
|------|------|--------|
| Action entry | `src/actions/github_action.ts` | Reads inputs, builds Execution |
| CLI entry | `src/cli.ts` → `local_action.ts` | Same flow, local inputs |
| Shared flow | `src/actions/common_action.ts` | mainRun, waitForPreviousRuns, dispatch to use cases |
| Use cases | `src/usecase/` | issue_use_case, pull_request_use_case, commit_use_case, single_action_use_case |
| Single actions | `src/usecase/actions/` | check_progress, detect_errors, recommend_steps, think, initial_setup, create_release, create_tag, publish_github_action, deployed_action |
| Steps (issue) | `src/usecase/steps/issue/` | check_permissions, close_not_allowed_issue, assign_members, update_title, update_issue_type, link_issue_project, check_priority_issue_size, prepare_branches, remove_issue_branches, remove_not_needed_branches, label_deploy_added, label_deployed_added, move_issue_to_in_progress, answer_issue_help_use_case (question/help on open). On issue opened: RecommendStepsUseCase (non release/question/help) or AnswerIssueHelpUseCase (question/help). |
| Steps (PR) | `src/usecase/steps/pull_request/` | update_title, assign_members (issue), assign_reviewers_to_issue, link_pr_project, link_pr_issue, sync_size_and_progress_from_issue, check_priority_pull_request_size, update_description (AI), close_issue_after_merging |
| Steps (commit) | `src/usecase/steps/commit/` | notify commit, check size |
| Steps (issue comment) | `src/usecase/steps/issue_comment/` | check_issue_comment_language (translation) |
| Steps (PR review comment) | `src/usecase/steps/pull_request_review_comment/` | check_pull_request_comment_language (translation) |
| Bugbot autofix & user request | `src/usecase/steps/commit/bugbot/` + `user_request_use_case.ts` | detect_bugbot_fix_intent_use_case (plan agent: is_fix_request, is_do_request, target_finding_ids), BugbotAutofixUseCase + runBugbotAutofixCommitAndPush (fix findings), DoUserRequestUseCase + runUserRequestCommitAndPush (generic “do this”). Permission: ProjectRepository.isActorAllowedToModifyFiles (org member or repo owner). |
| Manager (content) | `src/manager/` | description handlers, configuration_handler, markdown_content_hotfix_handler (PR description, hotfix changelog content) |
| Models | `src/data/model/` | Execution, Issue, PullRequest, SingleAction, etc. |
| Repos | `src/data/repository/` | branch_repository, issue_repository, workflow_repository, ai_repository (OpenCode), file_repository, project_repository |
| Config | `src/utils/constants.ts` | INPUT_KEYS, ACTIONS, defaults |
| Metadata | `action.yml` | Action inputs and defaults |
128 changes: 128 additions & 0 deletions _agent/docs/bugbot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
name: Bugbot
description: Detailed technical reference for Bugbot (detection, markers, context, intent, autofix, do user request, permissions)
---

# Bugbot – technical reference

Bugbot has two main modes: **detection** (on push or single action) and **fix/do** (on issue comment or PR review comment). All Bugbot code lives under `src/usecase/steps/commit/bugbot/` and `src/usecase/steps/commit/` (DetectPotentialProblemsUseCase, user_request_use_case).

---

## 1. Detection flow (push or single action)

**Entry:** `CommitUseCase` (on push) calls `DetectPotentialProblemsUseCase`; or `SingleActionUseCase` when action is `detect_potential_problems_action`.

**Steps:**

1. **Guard:** OpenCode must be configured; `issueNumber !== -1`.
2. **Load context:** `loadBugbotContext(param)` → issue comments + PR review comments parsed for markers; builds `existingByFindingId`, `issueComments`, `openPrNumbers`, `previousFindingsBlock`, `prContext`, `unresolvedFindingsWithBody`. Branch is `param.commit.branch` (or `options.branchOverride` when provided). PR context includes `prHeadSha`, `prFiles`, `pathToFirstDiffLine` for the first open PR.
3. **Build prompt:** `buildBugbotPrompt(param, context)` – repo context, head/base branch, issue number, optional `ai-ignore-files`, and `previousFindingsBlock` (task 2: which previous findings are now resolved). OpenCode is asked to compute the diff itself and return `findings` + `resolved_finding_ids`.
4. **Call OpenCode:** `askAgent(OPENCODE_AGENT_PLAN, prompt, BUGBOT_RESPONSE_SCHEMA)`.
5. **Process response:** Filter findings: safe path (`isSafeFindingFilePath`), not in `ai-ignore-files` (`fileMatchesIgnorePatterns`), `meetsMinSeverity` (min from `bugbot-severity`), `deduplicateFindings`. Apply `applyCommentLimit(findings, bugbot-comment-limit)` → `toPublish`, `overflowCount`, `overflowTitles`.
6. **Mark resolved:** `markFindingsResolved(execution, context, resolvedFindingIds, normalizedResolvedIds)` – for each existing finding in context whose id is in resolved set, update issue comment (and PR review comment if any) via `replaceMarkerInBody` to set `resolved:true`; if PR comment, call `resolveReviewThread` when applicable.
7. **Publish:** `publishFindings(execution, context, toPublish, overflowCount?, overflowTitles?)` – for each finding: add or update **issue comment** (always); add or update **PR review comment** only when `finding.file` is in `prContext.prFiles` (using `pathToFirstDiffLine` when finding has no line). Each comment body is built with `buildCommentBody(finding, resolved)` and includes the **marker** `<!-- copilot-bugbot finding_id:"id" resolved:false -->`. Overflow: one extra issue comment summarizing excess findings.

**Key paths (detection):**

- `detect_potential_problems_use_case.ts` – orchestration
- `load_bugbot_context_use_case.ts` – issue/PR comments, markers, previousFindingsBlock, prContext
- `build_bugbot_prompt.ts` – prompt for plan agent (task 1: new findings, task 2: resolved ids)
- `schema.ts` – BUGBOT_RESPONSE_SCHEMA (findings, resolved_finding_ids)
- `marker.ts` – BUGBOT_MARKER_PREFIX, buildMarker, parseMarker, replaceMarkerInBody, extractTitleFromBody, buildCommentBody
- `publish_findings_use_case.ts` – add/update issue comment, create/update PR review comment
- `mark_findings_resolved_use_case.ts` – update comment body with resolved marker, resolve PR thread
- `severity.ts`, `file_ignore.ts`, `path_validation.ts`, `limit_comments.ts`, `deduplicate_findings.ts`

---

## 2. Marker format and context

**Marker:** Hidden HTML comment in every finding comment (issue and PR):

`<!-- copilot-bugbot finding_id:"<id>" resolved:true|false -->`

- **Parse:** `parseMarker(body)` returns `{ findingId, resolved }[]`. Used when loading context from issue comments and PR review comments.
- **Build:** `buildMarker(findingId, resolved)`. IDs are sanitized (`sanitizeFindingIdForMarker`) so they cannot break HTML (no `-->`, `<`, `>`, newlines, etc.).
- **Update:** `replaceMarkerInBody(body, findingId, newResolved)` – used when marking a finding as resolved (same comment, body updated with `resolved:true`).

**Context (`BugbotContext`):**

- `existingByFindingId[id]`: `{ issueCommentId?, prCommentId?, prNumber?, resolved }` – from parsing all issue + PR comments for markers.
- `issueComments`: raw list from API (for body when building previousFindingsBlock / unresolvedFindingsWithBody).
- `openPrNumbers`, `previousFindingsBlock`, `prContext` (prHeadSha, prFiles, pathToFirstDiffLine), `unresolvedFindingsWithBody`: `{ id, fullBody }[]` for findings that are not resolved (body truncated to MAX_FINDING_BODY_LENGTH when loading).

---

## 3. Fix intent and file-modifying actions (issue comment / PR review comment)

**Entry:** `IssueCommentUseCase` or `PullRequestReviewCommentUseCase` (after language check).

**Steps:**

1. **Intent:** `DetectBugbotFixIntentUseCase.invoke(param)`
- Guards: OpenCode configured, issue number set, comment body non-empty, branch (or branchOverride from `getHeadBranchForIssue` when commit.branch empty).
- `loadBugbotContext(param, { branchOverride })` → unresolved findings.
- Build `UnresolvedFindingSummary[]` (id, title from `extractTitleFromBody`, description = fullBody.slice(0, 4000)).
- If PR review comment and `commentInReplyToId`: fetch parent comment body (`getPullRequestReviewCommentBody`), slice(0,1500).trim for prompt.
- `buildBugbotFixIntentPrompt(commentBody, unresolvedFindings, parentCommentBody?)` → prompt asks: is_fix_request?, target_finding_ids?, is_do_request?
- `askAgent(OPENCODE_AGENT_PLAN, prompt, BUGBOT_FIX_INTENT_RESPONSE_SCHEMA)` → `{ is_fix_request, target_finding_ids, is_do_request }`.
- Payload: `isFixRequest`, `isDoRequest`, `targetFindingIds` (filtered to valid unresolved ids), `context`, `branchOverride`.

2. **Permission:** `ProjectRepository.isActorAllowedToModifyFiles(owner, actor, token)`.
- If owner is Organization: `orgs.checkMembershipForUser` (204 = allowed).
- If owner is User: allowed only if `actor === owner`.

3. **Branch A – Bugbot autofix** (when `canRunBugbotAutofix(payload)` and `allowedToModifyFiles`):
- `BugbotAutofixUseCase.invoke({ execution, targetFindingIds, userComment, context, branchOverride })`
- Load context if not provided; filter targets to valid unresolved ids; `buildBugbotFixPrompt(...)` with repo, findings block (truncated fullBody per finding), user comment, verify commands; `copilotMessage(ai, prompt)` (build agent).
- If success: `runBugbotAutofixCommitAndPush(execution, { branchOverride, targetFindingIds })` – optional checkout if branchOverride, run verify commands (from `getBugbotFixVerifyCommands`, max 20), git add/commit/push (message `fix(#N): bugbot autofix - resolve ...`).
- If committed and context: `markFindingsResolved({ execution, context, resolvedFindingIds, normalizedResolvedIds })`.

4. **Branch B – Do user request** (when `!runAutofix && canRunDoUserRequest(payload)` and `allowedToModifyFiles`):
- `DoUserRequestUseCase.invoke({ execution, userComment, branchOverride })`
- `buildUserRequestPrompt(execution, userComment)` – repo context + sanitized user request; `copilotMessage(ai, prompt)`.
- If success: `runUserRequestCommitAndPush(execution, { branchOverride })` – same verify/checkout/add/commit/push with message `chore(#N): apply user request` or `chore: apply user request`.

5. **Think** (when no file-modifying action ran): `ThinkUseCase.invoke(param)` – answers the user (e.g. question).

**Key paths (fix/do):**

- `detect_bugbot_fix_intent_use_case.ts` – intent detection, branch resolution for issue_comment
- `build_bugbot_fix_intent_prompt.ts` – prompt for is_fix_request / is_do_request / target_finding_ids
- `bugbot_fix_intent_payload.ts` – getBugbotFixIntentPayload, canRunBugbotAutofix, canRunDoUserRequest
- `schema.ts` – BUGBOT_FIX_INTENT_RESPONSE_SCHEMA (is_fix_request, target_finding_ids, is_do_request)
- `bugbot_autofix_use_case.ts` – build prompt, copilotMessage (build agent)
- `build_bugbot_fix_prompt.ts` – fix prompt (findings block, verify commands, truncate finding body to MAX_FINDING_BODY_LENGTH)
- `bugbot_autofix_commit.ts` – runBugbotAutofixCommitAndPush, runUserRequestCommitAndPush (checkout, verify commands max 20, git config, add, commit, push)
- `user_request_use_case.ts` – DoUserRequestUseCase, buildUserRequestPrompt
- `mark_findings_resolved_use_case.ts` – update issue/PR comment with resolved marker
- `project_repository.ts` – isActorAllowedToModifyFiles

---

## 4. Configuration (inputs / Ai model)

- **bugbot-severity:** Minimum severity to publish (info, low, medium, high). Default low. `getBugbotMinSeverity()`, `normalizeMinSeverity`, `meetsMinSeverity`.
- **bugbot-comment-limit:** Max individual finding comments per issue/PR (overflow gets one summary). Default 20. `getBugbotCommentLimit()`, `applyCommentLimit`.
- **bugbot-fix-verify-commands:** Comma-separated commands run after autofix (and do user request) before commit. `getBugbotFixVerifyCommands()`, parsed with shell-quote; max 20 executed. Stored in `Ai` model; read in `github_action.ts` / `local_action.ts`.
- **ai-ignore-files:** Exclude paths from detection (and from reporting). Used in buildBugbotPrompt and in filtering findings.

---

## 5. Constants and types

- `BUGBOT_MARKER_PREFIX`: `'copilot-bugbot'`
- `BUGBOT_MAX_COMMENTS`: 20 (default limit)
- `MAX_FINDING_BODY_LENGTH`: 12000 (truncation when loading context and in build_bugbot_fix_prompt)
- `MAX_VERIFY_COMMANDS`: 20 (in bugbot_autofix_commit)
- Types: `BugbotContext`, `BugbotFinding` (id, title, description, file?, line?, severity?, suggestion?), `UnresolvedFindingSummary`, `BugbotFixIntentPayload`.

---

## 6. Sanitization and safety

- **User comment in prompts:** `sanitizeUserCommentForPrompt(raw)` – trim, escape backslashes, replace `"""`, truncate 4000 with no lone trailing backslash.
- **Finding body in prompts:** `truncateFindingBody(body, MAX_FINDING_BODY_LENGTH)` with suffix `[... truncated for length ...]` (used in load_bugbot_context and build_bugbot_fix_prompt).
- **Verify commands:** Parsed with shell-quote; no shell operators (;, |, etc.); max 20 run.
- **Path:** `isSafeFindingFilePath` (no null byte, no `..`, no absolute); PR review comment only if file in `prFiles`.
33 changes: 33 additions & 0 deletions _agent/docs/code-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Code Conventions
description: Copilot – coding conventions and where to change things
---

# Code Conventions

## Logging and constants

- Use **logger**: `logInfo`, `logError`, `logDebugInfo` from `src/utils/logger`. No ad-hoc `console.log`.
- Use **constants**: `INPUT_KEYS` and `ACTIONS` from `src/utils/constants.ts` for input names and action names. No hardcoded strings for these.

## Adding a new action input

1. **`action.yml`**: Add the input with `description` and `default` (if any).
2. **`src/utils/constants.ts`**: Add the key to `INPUT_KEYS` (e.g. `NEW_INPUT: 'new-input'`).
3. **`src/actions/github_action.ts`**: Read the input (e.g. `core.getInput(INPUT_KEYS.NEW_INPUT)`) and pass it into the object used to build `Execution`.
4. **Optional**: If the CLI must support it, add to `local_action.ts` and the corresponding CLI option.

## Where to change content/descriptions

- **PR description** (template filling, AI content): `src/manager/description/` (configuration_handler, content interfaces).
- **Hotfix/release changelog** (markdown extraction, formatting): `src/manager/description/markdown_content_hotfix_handler.ts`.

## Build and bundles

- The project uses **`@vercel/ncc`** to bundle the action and CLI. Keep imports and dependencies compatible with ncc (no dynamic requires that ncc cannot see).
- **Do not** edit or rely on `build/`; it is generated. Run tests and lint only on `src/`.

## Style and lint

- Prefer TypeScript; avoid `any` (lint rule: no-explicit-any).
- Run `npm run lint` before committing; use `npm run lint:fix` when possible.
32 changes: 32 additions & 0 deletions _agent/docs/commit-messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: Commit Messages
description: Commit message nomenclature (prefix = current branch)
---

# Commit messages

The commit message must use the **current branch name as prefix**, with any `/` replaced by `-`.

## Format

```
<normalized-branch>: <short description>

[optional body]
```

- **Prefix**: current branch name, replacing `/` with `-`. Example: branch `feature/292-github-action-rename` → prefix `feature-292-github-action-rename`.
- **Description**: imperative, lowercase, no trailing period. You may optionally include conventional type (`feat`, `fix`, `docs`, etc.) in the description.

## Examples

Branch `feature-292-github-action-rename`:

- `feature-292-github-action-rename: add concurrency and permissions to ci_check`
- `feature-292-github-action-rename: fix docs callouts (Info instead of Note/Tip)`

Branch `fix/123-docs-anchor` (normalized to `fix-123-docs-anchor`):

- `fix-123-docs-anchor: remove invalid MDX heading anchors`

When suggesting or writing a commit message, use the current branch with `/` replaced by `-` as the prefix. If you don't know the branch, tell the user to use their branch name as the prefix.
40 changes: 40 additions & 0 deletions _agent/docs/project-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Project Context
description: Copilot – quick read, commands, and where to find more
---

# Copilot – Project Context

## Quick read (for fast understanding)

- **What it is**: GitHub Action + CLI that automates Git-Flow: creates branches from issue labels, links issues/PRs to projects, tracks commits; AI via OpenCode (progress, errors, PR descriptions).
- **Entry points**: GitHub Action → `src/actions/github_action.ts`; CLI → `src/cli.ts`. Shared logic in `src/actions/common_action.ts` (single actions vs issue/PR/push).
- **Do**: Use Node 20, run from repo root; edit only `src/`; use `INPUT_KEYS`/`ACTIONS` and `logInfo`/`logError`/`logDebugInfo`. When adding inputs: update `action.yml`, `constants.ts` (INPUT_KEYS), and `github_action.ts` (and optionally `local_action.ts`).
- **Don’t**: Edit or depend on `build/` (generated by `ncc`); run tests/lint on `build/`.

## Commands (repo root)

```bash
nvm use 20
npm install
npm run build
npm test
npm run test:watch
npm run test:coverage
npm run lint
npm run lint:fix
```

- **Build**: `npm run build` → bundles `github_action.ts` and `cli.ts` into `build/`.
- **Tests**: Jest; `npm run test:watch` / `npm run test:coverage` as needed.
- **Lint**: ESLint + typescript-eslint on `src/`; `npm run lint:fix` to auto-fix.

## What to ignore

- **`build/`** – Generated output; do not edit or run tests/lint against it.
- **`.agent-sessions/`** – Session data; ignore unless debugging.

## Other rules

- **Architecture & paths**: see `architecture.md` (entry points, use cases, single actions, key files).
- **Code conventions**: see `code-conventions.md` (logger, constants, adding inputs, ncc).
Loading